├── .eslintrc.cjs ├── .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 ├── be.js ├── be.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 ├── sw.js ├── sw.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 ├── Controller │ ├── ConfigController.php │ └── GoogleAPIController.php ├── Migration │ └── Version03001001Date20241111105515.php ├── Notification │ └── Notifier.php ├── Service │ ├── GoogleAPIService.php │ ├── GoogleCalendarAPIService.php │ ├── GoogleContactsAPIService.php │ ├── GoogleDriveAPIService.php │ ├── SecretService.php │ ├── UserScopeService.php │ └── Utils │ │ └── FileUtils.php └── Settings │ ├── Admin.php │ ├── AdminSection.php │ ├── Personal.php │ └── PersonalSection.php ├── makefile ├── package-lock.json ├── package.json ├── psalm-baseline.xml ├── psalm.xml ├── src ├── adminSettings.js ├── components │ ├── AdminSettings.vue │ ├── PersonalSettings.vue │ └── icons │ │ ├── GoogleIcon.vue │ │ └── GoogleIconColor.vue ├── personalSettings.js ├── popupSuccess.js └── utils.js ├── stylelint.config.cjs ├── templates ├── adminSettings.php ├── personalSettings.php └── popupSuccess.php ├── tests └── stub.phpstub └── vite.config.js /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | module.exports = { 7 | globals: { 8 | appVersion: true, 9 | }, 10 | parserOptions: { 11 | requireConfigFile: false, 12 | }, 13 | extends: [ 14 | '@nextcloud', 15 | ], 16 | rules: { 17 | 'jsdoc/require-jsdoc': 'off', 18 | 'jsdoc/tag-lines': 'off', 19 | 'vue/first-attribute-linebreak': 'off', 20 | 'import/extensions': 'off', 21 | 'import/no-unresolved': ['error', { ignore: ['\\?raw'] }], 22 | 'vue/no-v-model-argument': 'off', 23 | }, 24 | } 25 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | .php-cs-fixer.cache 11 | -------------------------------------------------------------------------------- /.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 | This integration supports both personal Google accounts and Google Workspace (formerly G Suite) accounts. 5 | 6 | Note that this is a one-time import and will not keep Nextcloud in sync with Google. 7 | 8 | ## 🚀 Installation 9 | 10 | In your Nextcloud, simply enable the Google Integration app through the Apps management. 11 | The Google Integration app is available for Nextcloud >= 22. 12 | 13 | ## 🔧 Setup 14 | 15 | The app needs some setup in the Google API Console in order to work. 16 | To do this, go to Nextcloud Settings > Administration > Connected accounts and follow the instructions in the "Google integration" section. 17 | 18 | ## **🛠️ State of maintenance** 19 | 20 | While there are many things that could be done to further improve this app, the app is currently maintained with **limited effort**. This means: 21 | 22 | - The main functionality works for the majority of the use cases 23 | - 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' 24 | - We will not invest further development resources ourselves in advancing the app with new features 25 | - We do review and enthusiastically welcome community PR's 26 | 27 | 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. 28 | 29 | 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. 30 | 31 | ## Limitations 32 | 33 | This app can not migrate Google photos files due to limitations in the Google Photos API making it too complex for end users. 34 | For more information please visit [the Google Photos Documentation.](https://developers.google.com/photos/support/updates#affected-scopes-methods) 35 | -------------------------------------------------------------------------------- /appinfo/info.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | integration_google 4 | Google integration 5 | Import Google data into Nextcloud 6 | 7 | 4.1.0 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#importCalendar', 'url' => '/import-calendar', 'verb' => 'GET'], 24 | ['name' => 'googleAPI#importContacts', 'url' => '/import-contacts', 'verb' => 'GET'], 25 | ['name' => 'googleAPI#importDrive', 'url' => '/import-files', 'verb' => 'GET'], 26 | ['name' => 'googleAPI#getImportDriveInformation', 'url' => '/import-files-info', 'verb' => 'GET'], 27 | ] 28 | ]; 29 | -------------------------------------------------------------------------------- /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/d3eed964fc99f298eec6d3d231aaebc75978975a/img/screenshot1.jpg -------------------------------------------------------------------------------- /l10n/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcloud/integration_google/d3eed964fc99f298eec6d3d231aaebc75978975a/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 contacts" : "Nun se pue consiguir el númberu de contautos de Google", 10 | "Failed to import Google calendar" : "Nun se pue importar el calendariu 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 | }, 16 | "nplurals=2; plural=(n != 1);"); 17 | -------------------------------------------------------------------------------- /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 contacts" : "Nun se pue consiguir el númberu de contautos de Google", 8 | "Failed to import Google calendar" : "Nun se pue importar el calendariu de Google", 9 | "Failed to start importing Google Drive" : "Nun se pue comenzar a importar Google Drive", 10 | "Authentication" : "Autenticación", 11 | "Contacts" : "Contautos", 12 | "Calendars" : "Calendarios" 13 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 14 | } -------------------------------------------------------------------------------- /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 | }, 9 | "nplurals=2; plural=(n != 1);"); 10 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 7 | } -------------------------------------------------------------------------------- /l10n/be.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 | "OAuth access token refused" : "Токен доступу OAuth адхілены", 7 | "Client ID" : "Ідэнтыфікатар кліента", 8 | "Sign in with Google" : "Увайсці з дапамогай Google", 9 | "Authentication" : "Аўтэнтыфікацыя", 10 | "Contacts" : "Кантакты", 11 | "Calendars" : "Календары", 12 | "Import all events including Birthdays" : "Імпартаваць усе падзеі, у тым ліку дні нараджэння" 13 | }, 14 | "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"); 15 | -------------------------------------------------------------------------------- /l10n/be.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Missing refresh token in Google response." : "Адсутнічае токен абнаўлення ў адказе Google.", 3 | "Error getting OAuth access token." : "Памылка атрымання токена доступу OAuth.", 4 | "OAuth access token refused" : "Токен доступу OAuth адхілены", 5 | "Client ID" : "Ідэнтыфікатар кліента", 6 | "Sign in with Google" : "Увайсці з дапамогай Google", 7 | "Authentication" : "Аўтэнтыфікацыя", 8 | "Contacts" : "Кантакты", 9 | "Calendars" : "Календары", 10 | "Import all events including Birthdays" : "Імпартаваць усе падзеі, у тым ліку дні нараджэння" 11 | },"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);" 12 | } -------------------------------------------------------------------------------- /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 | "Drive" : "Bleinañ" 9 | }, 10 | "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);"); 11 | -------------------------------------------------------------------------------- /l10n/br.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Google" : "Google", 3 | "Client ID" : "ID kliant", 4 | "Contacts" : "Darempredoù", 5 | "Calendars" : "Deiziataerioù", 6 | "Drive" : "Bleinañ" 7 | },"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);" 8 | } -------------------------------------------------------------------------------- /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 | "Private event" : "Esdeveniment privat", 11 | "Google Calendar import" : "Importació de Google Calendar", 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 | "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.", 25 | "Client ID" : "ID de Client", 26 | "Client ID of your Google application" : "ID de client o la vostra aplicació Google", 27 | "Client secret" : "Secret del client", 28 | "Client secret of your Google application" : "Secret del client o de la vostra aplicació Google", 29 | "Last Google Drive import job at {date}" : "Darrer treball d'importació de Google Drive a {date}", 30 | "Google Drive background import process will begin soon." : "El procés d'importació de fons de Google Drive començarà aviat.", 31 | "You can close this page. You will be notified when it finishes." : "Podeu tancar aquesta pàgina. Se us notificarà quan acabi.", 32 | "Successfully connected to Google!" : "S'ha connectat correctament a Google!", 33 | "Google connection error:" : "Error de connexió de Google:", 34 | "Google options saved" : "Opcions de Google desades.", 35 | "Failed to save Google options" : "No s'han pogut desar les opcions de Google", 36 | "Sign in with Google" : "Inicieu la sessió amb Google", 37 | "Failed to save Google OAuth state" : "No s'ha pogut desar l'estat de Google OAuth", 38 | "Failed to get Google Drive information" : "No s'ha pogut obtenir la informació de Google Drive", 39 | "Failed to get calendar list" : "No s'ha pogut obtenir la llista de calendaris", 40 | "Failed to get number of Google contacts" : "No s'ha pogut obtenir el nombre de contactes de Google", 41 | "Failed to get address book list" : "No s'ha pogut obtenir la llista de la llibreta d'adreces", 42 | "Failed to import Google calendar" : "No s'ha pogut importar el calendari de Google", 43 | "Starting importing files in {targetPath} directory" : "S'està iniciant la importació de fitxers al directori {targetPath}", 44 | "Failed to start importing Google Drive" : "No s'ha pogut començar a importar Google Drive", 45 | "Google data migration" : "Migració de dades de Google", 46 | "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.", 47 | "Authentication" : "Autenticació", 48 | "Connected as {user}" : "S'ha connectat com a {user}", 49 | "Disconnect from Google" : "Desconnectar-se de Google", 50 | "Contacts" : "Contactes", 51 | "{amount} Google contacts" : "{amount} Contactes de Google", 52 | "Import Google Contacts in Nextcloud" : "Importar contactes de Google a Nextcloud", 53 | "Choose where to import the contacts" : "Trieu on voleu importar els contactes", 54 | "New address book" : "Nova llibreta d'adreces", 55 | "address book name" : "nom de la llibreta d'adreces", 56 | "Calendars" : "Celendaris", 57 | "Import calendar" : "Importa un calendari", 58 | "Drive" : "Conduir", 59 | "Ignore shared files" : "Ignora els fitxers compartits", 60 | "Import directory" : "Carpeta d'importació", 61 | "Import Google Drive files" : "Importar fitxers de Google Drive", 62 | "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})", 63 | "Cancel Google Drive import" : "Cancel·lar la importació de Google Drive", 64 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["{amount} fitxer importat ({progress}%)","{amount} fitxers importats ({progress}%)"] 65 | }, 66 | "nplurals=2; plural=(n != 1);"); 67 | -------------------------------------------------------------------------------- /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 | "Private event" : "Esdeveniment privat", 9 | "Google Calendar import" : "Importació de Google Calendar", 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 | "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.", 23 | "Client ID" : "ID de Client", 24 | "Client ID of your Google application" : "ID de client o la vostra aplicació Google", 25 | "Client secret" : "Secret del client", 26 | "Client secret of your Google application" : "Secret del client o de la vostra aplicació Google", 27 | "Last Google Drive import job at {date}" : "Darrer treball d'importació de Google Drive a {date}", 28 | "Google Drive background import process will begin soon." : "El procés d'importació de fons de Google Drive començarà aviat.", 29 | "You can close this page. You will be notified when it finishes." : "Podeu tancar aquesta pàgina. Se us notificarà quan acabi.", 30 | "Successfully connected to Google!" : "S'ha connectat correctament a Google!", 31 | "Google connection error:" : "Error de connexió de Google:", 32 | "Google options saved" : "Opcions de Google desades.", 33 | "Failed to save Google options" : "No s'han pogut desar les opcions de Google", 34 | "Sign in with Google" : "Inicieu la sessió amb Google", 35 | "Failed to save Google OAuth state" : "No s'ha pogut desar l'estat de Google OAuth", 36 | "Failed to get Google Drive information" : "No s'ha pogut obtenir la informació de Google Drive", 37 | "Failed to get calendar list" : "No s'ha pogut obtenir la llista de calendaris", 38 | "Failed to get number of Google contacts" : "No s'ha pogut obtenir el nombre de contactes de Google", 39 | "Failed to get address book list" : "No s'ha pogut obtenir la llista de la llibreta d'adreces", 40 | "Failed to import Google calendar" : "No s'ha pogut importar el calendari de Google", 41 | "Starting importing files in {targetPath} directory" : "S'està iniciant la importació de fitxers al directori {targetPath}", 42 | "Failed to start importing Google Drive" : "No s'ha pogut començar a importar Google Drive", 43 | "Google data migration" : "Migració de dades de Google", 44 | "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.", 45 | "Authentication" : "Autenticació", 46 | "Connected as {user}" : "S'ha connectat com a {user}", 47 | "Disconnect from Google" : "Desconnectar-se de Google", 48 | "Contacts" : "Contactes", 49 | "{amount} Google contacts" : "{amount} Contactes de Google", 50 | "Import Google Contacts in Nextcloud" : "Importar contactes de Google a Nextcloud", 51 | "Choose where to import the contacts" : "Trieu on voleu importar els contactes", 52 | "New address book" : "Nova llibreta d'adreces", 53 | "address book name" : "nom de la llibreta d'adreces", 54 | "Calendars" : "Celendaris", 55 | "Import calendar" : "Importa un calendari", 56 | "Drive" : "Conduir", 57 | "Ignore shared files" : "Ignora els fitxers compartits", 58 | "Import directory" : "Carpeta d'importació", 59 | "Import Google Drive files" : "Importar fitxers de Google Drive", 60 | "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})", 61 | "Cancel Google Drive import" : "Cancel·lar la importació de Google Drive", 62 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["{amount} fitxer importat ({progress}%)","{amount} fitxers importats ({progress}%)"] 63 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 64 | } -------------------------------------------------------------------------------- /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 | "Data migration" : "Datamigrering", 9 | "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\".", 10 | "Client ID" : "Klient ID", 11 | "Client secret" : "Klienthemmelighed", 12 | "Sign in with Google" : "Log ind med Google", 13 | "Authentication" : "Godkendelse", 14 | "Connected as {user}" : "Forbundet som {user}", 15 | "Contacts" : "Kontakter", 16 | "Calendars" : "Kalendere", 17 | "Import calendar" : "Importér kalender", 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 | "Data migration" : "Datamigrering", 7 | "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\".", 8 | "Client ID" : "Klient ID", 9 | "Client secret" : "Klienthemmelighed", 10 | "Sign in with Google" : "Log ind med Google", 11 | "Authentication" : "Godkendelse", 12 | "Connected as {user}" : "Forbundet som {user}", 13 | "Contacts" : "Kontakter", 14 | "Calendars" : "Kalendere", 15 | "Import calendar" : "Importér kalender", 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 | }, 10 | "nplurals=2; plural=(n != 1);"); 11 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 8 | } -------------------------------------------------------------------------------- /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 | }, 10 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 11 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 8 | } -------------------------------------------------------------------------------- /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 | }, 11 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 12 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 9 | } -------------------------------------------------------------------------------- /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 | }, 11 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 12 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 9 | } -------------------------------------------------------------------------------- /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 | "Calendars" : "Calendarios", 9 | "Import calendar" : "Importar calendario" 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 | "Calendars" : "Calendarios", 7 | "Import calendar" : "Importar calendario" 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 | }, 10 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 11 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 8 | } -------------------------------------------------------------------------------- /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 | }, 10 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 11 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 8 | } -------------------------------------------------------------------------------- /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 | }, 10 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 11 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 8 | } -------------------------------------------------------------------------------- /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 | }, 10 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 11 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 8 | } -------------------------------------------------------------------------------- /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 | }, 12 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 13 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 10 | } -------------------------------------------------------------------------------- /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 | }, 10 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 11 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 8 | } -------------------------------------------------------------------------------- /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 | }, 10 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 11 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 8 | } -------------------------------------------------------------------------------- /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 | }, 10 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 11 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 8 | } -------------------------------------------------------------------------------- /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 | }, 10 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 11 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 8 | } -------------------------------------------------------------------------------- /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 | }, 10 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 11 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 8 | } -------------------------------------------------------------------------------- /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 | }, 10 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 11 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 8 | } -------------------------------------------------------------------------------- /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 | }, 10 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 11 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 8 | } -------------------------------------------------------------------------------- /l10n/et_EE.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "No logged in user" : "Sisselogitud kasutajat pole", 5 | "Error getting OAuth access token." : "Viga OAuthi tunnusloa laadimisel.", 6 | "Error during OAuth exchanges" : "Viga OAuth andmevahetusel", 7 | "_%n file was imported from Google Drive._::_%n files were imported from Google Drive._" : ["%n fail on imporditud Google Drive'ist.","%n faili on imporditud Google Drive'ist."], 8 | "OAuth access token refused" : "OAuthi tunnusluba pole õige.", 9 | "Bad credentials" : "Vale kasutajanimi, salasõna või tunnusluba", 10 | "Connected accounts" : "Ühendatud kasutajakontod", 11 | "Google integration allows you to automatically migrate your Google calendars, contacts, and files into Nextcloud." : "Google'i lõiming võimaldab sul automaatselt kolida Google'i kalendrid, kontaktid ja failid Nextcloudi.", 12 | "Client ID" : "Kliendi ID", 13 | "Client secret" : "Kliendi salasõna", 14 | "Use a pop-up to authenticate" : "Kasuta autentimiseks hüpikakent", 15 | "Sign in with Google" : "Logi sisse Google'i kontoga", 16 | "Failed to get Google Drive information" : "Google Drive'i teabe laadimine ei õnnestunud", 17 | "Choose where to write imported files" : "Vali, kuhu soovid salvestada imporditud failid", 18 | "Authentication" : "Autentimine", 19 | "Connected as {user}" : "Ühendatud kui {user}", 20 | "Contacts" : "Kontaktid", 21 | "Include other contacts" : "Kaasa muud kontaktid", 22 | "{amount} Google + {otherAmount} other contacts" : "{amount} Google'i + {otherAmount} muud kontakti", 23 | "Import in \"{name}\" address book" : "Impordi aadressiraamatusse „{name}“", 24 | "Calendars" : "Kalendrid", 25 | "Import all events including Birthdays" : "Impordi kõik sündmused, sh sünnipäevad", 26 | "Import calendar" : "Impordi kalender", 27 | "Drive" : "Sõit", 28 | "Google documents import format" : "Google'i dokumentide impordivorming", 29 | "Import directory" : "Impordi kaust", 30 | "Your Google Drive ({formSize} + {formSharedSize} shared with you)" : "Sinu Google Drive ({formSize} + {formSharedSize} jagatud sinuga)", 31 | "Your Google Drive ({formSize})" : "Sinu Google Drive ({formSize})", 32 | "Cancel Google Drive import" : "Katkesta import Google Drive'ist", 33 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["Imporditud on {amount} fail ({progress}%)","Imporditud on {amount} faili ({progress}%)"] 34 | }, 35 | "nplurals=2; plural=(n != 1);"); 36 | -------------------------------------------------------------------------------- /l10n/et_EE.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No logged in user" : "Sisselogitud kasutajat pole", 3 | "Error getting OAuth access token." : "Viga OAuthi tunnusloa laadimisel.", 4 | "Error during OAuth exchanges" : "Viga OAuth andmevahetusel", 5 | "_%n file was imported from Google Drive._::_%n files were imported from Google Drive._" : ["%n fail on imporditud Google Drive'ist.","%n faili on imporditud Google Drive'ist."], 6 | "OAuth access token refused" : "OAuthi tunnusluba pole õige.", 7 | "Bad credentials" : "Vale kasutajanimi, salasõna või tunnusluba", 8 | "Connected accounts" : "Ühendatud kasutajakontod", 9 | "Google integration allows you to automatically migrate your Google calendars, contacts, and files into Nextcloud." : "Google'i lõiming võimaldab sul automaatselt kolida Google'i kalendrid, kontaktid ja failid Nextcloudi.", 10 | "Client ID" : "Kliendi ID", 11 | "Client secret" : "Kliendi salasõna", 12 | "Use a pop-up to authenticate" : "Kasuta autentimiseks hüpikakent", 13 | "Sign in with Google" : "Logi sisse Google'i kontoga", 14 | "Failed to get Google Drive information" : "Google Drive'i teabe laadimine ei õnnestunud", 15 | "Choose where to write imported files" : "Vali, kuhu soovid salvestada imporditud failid", 16 | "Authentication" : "Autentimine", 17 | "Connected as {user}" : "Ühendatud kui {user}", 18 | "Contacts" : "Kontaktid", 19 | "Include other contacts" : "Kaasa muud kontaktid", 20 | "{amount} Google + {otherAmount} other contacts" : "{amount} Google'i + {otherAmount} muud kontakti", 21 | "Import in \"{name}\" address book" : "Impordi aadressiraamatusse „{name}“", 22 | "Calendars" : "Kalendrid", 23 | "Import all events including Birthdays" : "Impordi kõik sündmused, sh sünnipäevad", 24 | "Import calendar" : "Impordi kalender", 25 | "Drive" : "Sõit", 26 | "Google documents import format" : "Google'i dokumentide impordivorming", 27 | "Import directory" : "Impordi kaust", 28 | "Your Google Drive ({formSize} + {formSharedSize} shared with you)" : "Sinu Google Drive ({formSize} + {formSharedSize} jagatud sinuga)", 29 | "Your Google Drive ({formSize})" : "Sinu Google Drive ({formSize})", 30 | "Cancel Google Drive import" : "Katkesta import Google Drive'ist", 31 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["Imporditud on {amount} fail ({progress}%)","Imporditud on {amount} faili ({progress}%)"] 32 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 33 | } -------------------------------------------------------------------------------- /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 | "Drive" : "נהיגה" 21 | }, 22 | "nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;"); 23 | -------------------------------------------------------------------------------- /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 | "Drive" : "נהיגה" 19 | },"pluralForm" :"nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;" 20 | } -------------------------------------------------------------------------------- /l10n/hr.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Missing refresh token in Google response." : "Nedostaje token za osvježavanje u Googleovom odgovoru.", 5 | "Error getting OAuth access token." : "Pogreška pri dohvaćanju tokena za pristup OAuth.", 6 | "Error during OAuth exchanges" : "Pogreška tijekom razmjene radi autentifikacije OAuth", 7 | "Google" : "Google", 8 | "OAuth access token refused" : "Odbijen token za pristup OAuth", 9 | "Bad credentials" : "Pogrešne vjerodajnice", 10 | "Private event" : "Privatni događaj", 11 | "Google Calendar import" : "Uvoz iz sustava Google Calendar", 12 | "Connected accounts" : "Povezani računi", 13 | "Data migration" : "Migracija podataka", 14 | "Google integration" : "Google integracija", 15 | "Import Google data into Nextcloud" : "Uvezi podatke s Googlea u Nextcloud", 16 | "Google admin options saved" : "Administratorske postavke Googlea su spremljene", 17 | "Failed to save Google admin options" : "Spremanje administratorskih postavki Googlea nije uspjelo", 18 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "Ako svojim korisnicima Nextclouda želite omogućiti autentifikaciju putem Googlea, stvorite aplikaciju OAuth u postavkama Googlea.", 19 | "Google API settings" : "Postavke Googleovog API-ja", 20 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "Idite na „API-ji i usluge“ => „Vjerodajnice“ i kliknite na „+ STVORI VJERODAJNICE“ -> „ID OAuth klijenta“.", 21 | "Set the \"Application type\" to \"Web application\" and give a name to the application." : "Postavite „Vrsta aplikacije“ na „Web aplikacija“ i dajte naziv aplikaciji.", 22 | "Make sure you set one \"Authorized redirect URI\" to" : "Obavezno postavite jedan „Ovlašteni URL za preusmjeravanje“ na", 23 | "Put the \"Client ID\" and \"Client secret\" below." : "U nastavku unesite „ID klijenta“ i „Tajni ključ klijenta“.", 24 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "Korisnici Nextclouda sada će u svojim osobnim postavkama vidjeti gumb „Poveži se s Googleom“.", 25 | "Client ID" : "ID klijenta", 26 | "Client ID of your Google application" : "ID klijenta vaše Google aplikacije", 27 | "Client secret" : "Tajni ključ klijenta", 28 | "Client secret of your Google application" : "Tajni ključ klijenta vaše Google aplikacije", 29 | "Last Google Drive import job at {date}" : "Posljednji uvoz iz Google Drivea {date}", 30 | "Google Drive background import process will begin soon." : "Uskoro će početi pozadinski proces uvoza iz Google Drivea.", 31 | "You can close this page. You will be notified when it finishes." : "Možete zatvoriti ovu stranicu. Primit ćete obavijest po završetku.", 32 | "Successfully connected to Google!" : "Uspješno povezivanje s Googleom!", 33 | "Google connection error:" : "Pogreška veze s Googleom:", 34 | "Google options saved" : "Postavke Googlea su spremljene", 35 | "Failed to save Google options" : "Spremanje postavki Googlea nije uspjelo", 36 | "Failed to save Google OAuth state" : "Spremanje stanja Google OAuth nije uspjelo", 37 | "Failed to get Google Drive information" : "Dohvaćanje informacija s Google Drivea nije uspjelo", 38 | "Failed to get calendar list" : "Nije moguće dobiti popis kalendara", 39 | "Failed to get number of Google contacts" : "Nije moguće dobiti broj Google kontakata", 40 | "Failed to get address book list" : "Nije moguće dobiti popis adresara", 41 | "Failed to import Google calendar" : "Uvoz Google kalendara nije uspio", 42 | "Starting importing files in {targetPath} directory" : "Početak uvoza datoteka u direktorij {targetPath}", 43 | "Failed to start importing Google Drive" : "Početak uvoza iz Google Drivea nije uspio", 44 | "Choose where to write imported files" : "Odaberite gdje želite zapisivati uvezene datoteke", 45 | "Google data migration" : "Google migracija podataka", 46 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "Nije konfigurirana aplikacija Google OAuth. Zatražite svog administratora za Nextcloud da konfigurira administratorski odjeljak računa povezanih s Googleom.", 47 | "Authentication" : "Autentifikacija", 48 | "Connected as {user}" : "Povezan kao {user}", 49 | "Disconnect from Google" : "Odspoji se s Googlea", 50 | "Contacts" : "Kontakti", 51 | "{amount} Google contacts" : "{amount} Googleovih kontakata", 52 | "Import Google Contacts in Nextcloud" : "Uvezi kontakte iz Googlea u Nextcloud", 53 | "Choose where to import the contacts" : "Odaberite mjesto za uvoz kontakata", 54 | "New address book" : "Novi adresar", 55 | "address book name" : "naziv adresara", 56 | "Calendars" : "Kalendari", 57 | "Import calendar" : "Uvezi kalendar", 58 | "Drive" : "Vožnja", 59 | "Ignore shared files" : "Zanemari dijeljene datoteke", 60 | "Google documents import format" : "Format za uvoz Googleovih dokumenata", 61 | "Import directory" : "Uvezi direktorij", 62 | "Import Google Drive files" : "Uvezi datoteke iz sustava Google Drive", 63 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "Veličina vašeg Google Drivea veća je od preostalog prostora ({formSpace})", 64 | "Cancel Google Drive import" : "Odustani od uvoza iz Google Drivea", 65 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["{amount} uvezena datoteka ({progress} %)","{amount} uvezene datoteke ({progress} %)","{amount} uvezenih datoteka ({progress} %)"] 66 | }, 67 | "nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"); 68 | -------------------------------------------------------------------------------- /l10n/hr.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Missing refresh token in Google response." : "Nedostaje token za osvježavanje u Googleovom odgovoru.", 3 | "Error getting OAuth access token." : "Pogreška pri dohvaćanju tokena za pristup OAuth.", 4 | "Error during OAuth exchanges" : "Pogreška tijekom razmjene radi autentifikacije OAuth", 5 | "Google" : "Google", 6 | "OAuth access token refused" : "Odbijen token za pristup OAuth", 7 | "Bad credentials" : "Pogrešne vjerodajnice", 8 | "Private event" : "Privatni događaj", 9 | "Google Calendar import" : "Uvoz iz sustava Google Calendar", 10 | "Connected accounts" : "Povezani računi", 11 | "Data migration" : "Migracija podataka", 12 | "Google integration" : "Google integracija", 13 | "Import Google data into Nextcloud" : "Uvezi podatke s Googlea u Nextcloud", 14 | "Google admin options saved" : "Administratorske postavke Googlea su spremljene", 15 | "Failed to save Google admin options" : "Spremanje administratorskih postavki Googlea nije uspjelo", 16 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "Ako svojim korisnicima Nextclouda želite omogućiti autentifikaciju putem Googlea, stvorite aplikaciju OAuth u postavkama Googlea.", 17 | "Google API settings" : "Postavke Googleovog API-ja", 18 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "Idite na „API-ji i usluge“ => „Vjerodajnice“ i kliknite na „+ STVORI VJERODAJNICE“ -> „ID OAuth klijenta“.", 19 | "Set the \"Application type\" to \"Web application\" and give a name to the application." : "Postavite „Vrsta aplikacije“ na „Web aplikacija“ i dajte naziv aplikaciji.", 20 | "Make sure you set one \"Authorized redirect URI\" to" : "Obavezno postavite jedan „Ovlašteni URL za preusmjeravanje“ na", 21 | "Put the \"Client ID\" and \"Client secret\" below." : "U nastavku unesite „ID klijenta“ i „Tajni ključ klijenta“.", 22 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "Korisnici Nextclouda sada će u svojim osobnim postavkama vidjeti gumb „Poveži se s Googleom“.", 23 | "Client ID" : "ID klijenta", 24 | "Client ID of your Google application" : "ID klijenta vaše Google aplikacije", 25 | "Client secret" : "Tajni ključ klijenta", 26 | "Client secret of your Google application" : "Tajni ključ klijenta vaše Google aplikacije", 27 | "Last Google Drive import job at {date}" : "Posljednji uvoz iz Google Drivea {date}", 28 | "Google Drive background import process will begin soon." : "Uskoro će početi pozadinski proces uvoza iz Google Drivea.", 29 | "You can close this page. You will be notified when it finishes." : "Možete zatvoriti ovu stranicu. Primit ćete obavijest po završetku.", 30 | "Successfully connected to Google!" : "Uspješno povezivanje s Googleom!", 31 | "Google connection error:" : "Pogreška veze s Googleom:", 32 | "Google options saved" : "Postavke Googlea su spremljene", 33 | "Failed to save Google options" : "Spremanje postavki Googlea nije uspjelo", 34 | "Failed to save Google OAuth state" : "Spremanje stanja Google OAuth nije uspjelo", 35 | "Failed to get Google Drive information" : "Dohvaćanje informacija s Google Drivea nije uspjelo", 36 | "Failed to get calendar list" : "Nije moguće dobiti popis kalendara", 37 | "Failed to get number of Google contacts" : "Nije moguće dobiti broj Google kontakata", 38 | "Failed to get address book list" : "Nije moguće dobiti popis adresara", 39 | "Failed to import Google calendar" : "Uvoz Google kalendara nije uspio", 40 | "Starting importing files in {targetPath} directory" : "Početak uvoza datoteka u direktorij {targetPath}", 41 | "Failed to start importing Google Drive" : "Početak uvoza iz Google Drivea nije uspio", 42 | "Choose where to write imported files" : "Odaberite gdje želite zapisivati uvezene datoteke", 43 | "Google data migration" : "Google migracija podataka", 44 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "Nije konfigurirana aplikacija Google OAuth. Zatražite svog administratora za Nextcloud da konfigurira administratorski odjeljak računa povezanih s Googleom.", 45 | "Authentication" : "Autentifikacija", 46 | "Connected as {user}" : "Povezan kao {user}", 47 | "Disconnect from Google" : "Odspoji se s Googlea", 48 | "Contacts" : "Kontakti", 49 | "{amount} Google contacts" : "{amount} Googleovih kontakata", 50 | "Import Google Contacts in Nextcloud" : "Uvezi kontakte iz Googlea u Nextcloud", 51 | "Choose where to import the contacts" : "Odaberite mjesto za uvoz kontakata", 52 | "New address book" : "Novi adresar", 53 | "address book name" : "naziv adresara", 54 | "Calendars" : "Kalendari", 55 | "Import calendar" : "Uvezi kalendar", 56 | "Drive" : "Vožnja", 57 | "Ignore shared files" : "Zanemari dijeljene datoteke", 58 | "Google documents import format" : "Format za uvoz Googleovih dokumenata", 59 | "Import directory" : "Uvezi direktorij", 60 | "Import Google Drive files" : "Uvezi datoteke iz sustava Google Drive", 61 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "Veličina vašeg Google Drivea veća je od preostalog prostora ({formSpace})", 62 | "Cancel Google Drive import" : "Odustani od uvoza iz Google Drivea", 63 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["{amount} uvezena datoteka ({progress} %)","{amount} uvezene datoteke ({progress} %)","{amount} uvezenih datoteka ({progress} %)"] 64 | },"pluralForm" :"nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;" 65 | } -------------------------------------------------------------------------------- /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 | }, 16 | "nplurals=1; plural=0;"); 17 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=1; plural=0;" 14 | } -------------------------------------------------------------------------------- /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 | "Drive" : "Keyra", 17 | "Import directory" : "Flytja möppu inn" 18 | }, 19 | "nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"); 20 | -------------------------------------------------------------------------------- /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 | "Drive" : "Keyra", 15 | "Import directory" : "Flytja möppu inn" 16 | },"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);" 17 | } -------------------------------------------------------------------------------- /l10n/it.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Missing refresh token in Google response." : "Token di aggiornamento mancante nella risposta di Google.", 3 | "Error getting OAuth access token." : "Errore durante il recupero del token di accesso OAuth.", 4 | "Error during OAuth exchanges" : "Errore durante le negoziazioni OAuth", 5 | "Google" : "Google", 6 | "OAuth access token refused" : "Token di accesso OAuth rifiutato", 7 | "Bad credentials" : "Credenziali non valide", 8 | "Private event" : "Evento privato", 9 | "Google Calendar import" : "Importazione Google Calendar", 10 | "Connected accounts" : "Account connessi", 11 | "Data migration" : "Migrazione dei dati", 12 | "Google integration" : "Integrazione Google", 13 | "Import Google data into Nextcloud" : "Importa i dati di Google in Nextcloud", 14 | "Google admin options saved" : "Opzioni amministrative di Google salvate", 15 | "Failed to save Google admin options" : "Salvataggio delle opzioni amministrative di Google non riuscito", 16 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "Se desideri consentire ai tuoi utenti Nextcloud di autenticarsi a Google, crea un'applicazione OAuth nelle impostazioni di Google.", 17 | "Google API settings" : "Impostazioni API di Google", 18 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "Vai a \"API e servizi\" => \"Credenziali\" e fai clic su \"+ CREA CREDENZIALI\" -> \"ID client OAuth\".", 19 | "Set the \"Application type\" to \"Web application\" and give a name to the application." : "Imposta il \"Tipo applicazione\" a \"Applicazione web\" e assegna un nome all'applicazione.", 20 | "Make sure you set one \"Authorized redirect URI\" to" : "Assicurati di impostare \"URI di reindirizzamento autorizzato\" a", 21 | "Put the \"Client ID\" and \"Client secret\" below." : "Inserisci sotto \"ID client\" e \"Segreto del client\" di seguito.", 22 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "I tuoi utenti Nextcloud vedranno quindi un pulsante \"Connetti a Google\" nelle loro impostazioni personali.", 23 | "Client ID" : "ID client", 24 | "Client ID of your Google application" : "ID client della tua applicazione Google", 25 | "Client secret" : "Segreto del client", 26 | "Client secret of your Google application" : "Segreto del client della tua applicazione Google", 27 | "Last Google Drive import job at {date}" : "Ultima operazione di importazione da Google Drive il {date}", 28 | "Google Drive background import process will begin soon." : "Il processo di importazione in background da Google Drive inizierà presto.", 29 | "You can close this page. You will be notified when it finishes." : "Puoi chiudere questa pagina. Riceverai una notifica al termine.", 30 | "Successfully connected to Google!" : "Connesso correttamente a Google!", 31 | "Google connection error:" : "Errore di connessione a Google:", 32 | "Google options saved" : "Opzioni di Google salvate", 33 | "Failed to save Google options" : "Salvataggio delle opzioni di Google non riuscito", 34 | "Sign in with Google" : "Accedi con Google", 35 | "Failed to save Google OAuth state" : "Salvataggio dello stato OAuth di Google non riuscito", 36 | "Failed to get Google Drive information" : "Impossibile ottenere le informazioni di Google Drive", 37 | "Failed to get calendar list" : "Impossibile ottenere l'elenco dei calendari", 38 | "Failed to get number of Google contacts" : "Impossibile ottenere il numero dei contatti di Google", 39 | "Failed to get address book list" : "Impossibile ottenere l'elenco delle rubriche", 40 | "Failed to import Google calendar" : "Importazione del calendario di Google non riuscita", 41 | "Starting importing files in {targetPath} directory" : "Avvio dell'importazione file nella cartella {targetPath}", 42 | "Failed to start importing Google Drive" : "Avvio dell'importazione da Google Drive non riuscito", 43 | "Choose where to write imported files" : "Scegli dove scrivere i file importati", 44 | "Google data migration" : "Migrazione dei dati di Google", 45 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "Nessuna applicazione OAuth di Google configurata. Chiedi al tuo amministratore di Nextcloud di configurare la sezione di amministrazione degli account collegati a Google.", 46 | "Authentication" : "Autenticazione", 47 | "Connected as {user}" : "Connesso come {user}", 48 | "Disconnect from Google" : "Disconnetti da Google", 49 | "Contacts" : "Contatti", 50 | "{amount} Google contacts" : "{amount} contatti Google", 51 | "Import Google Contacts in Nextcloud" : "Importa contatti di Google in Nextcloud", 52 | "Choose where to import the contacts" : "Scegli dove importare i contatti", 53 | "New address book" : "Nuova rubrica", 54 | "address book name" : "nome della rubrica", 55 | "Calendars" : "Calendari", 56 | "Import calendar" : "Importa calendario", 57 | "Drive" : "Drive", 58 | "Ignore shared files" : "Ignora i file condivisi", 59 | "Google documents import format" : "Formato di importazione dei documenti Google", 60 | "Import directory" : "Cartella di importazione", 61 | "Import Google Drive files" : "Importa file da Google Drive", 62 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "Il tuo Google Drive è più grande dello spazio rimanente ({formSpace})", 63 | "Cancel Google Drive import" : "Annulla l'importazione da Google Drive", 64 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["{amount} file importato ({progress}%)","{amount} file importati ({progress}%)","{amount} file importati ({progress}%)"] 65 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 66 | } -------------------------------------------------------------------------------- /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 | "Put the \"Client ID\" and \"Client secret\" below." : "下記に「クライアントID」と「クライアントシークレット」を入力してください。", 13 | "Client ID" : "クライアント ID", 14 | "Client secret" : "クライアントシークレット", 15 | "Successfully connected to Google!" : "Google への接続に成功しました!", 16 | "Sign in with Google" : "Googleでサインイン", 17 | "Google data migration" : "Google データの移行", 18 | "Authentication" : "認証", 19 | "Connected as {user}" : "{user} を接続済み", 20 | "Disconnect from Google" : "Google から切断", 21 | "Contacts" : "連絡先", 22 | "Choose where to import the contacts" : "連絡先をインポートする場所を選択してください", 23 | "New address book" : "新しいアドレス帳", 24 | "address book name" : "アドレス帳の名前", 25 | "Calendars" : "カレンダー", 26 | "Import calendar" : "カレンダーのインポート", 27 | "Drive" : "ドライブ", 28 | "Ignore shared files" : "共有済みファイルを無視" 29 | }, 30 | "nplurals=1; plural=0;"); 31 | -------------------------------------------------------------------------------- /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 | "Put the \"Client ID\" and \"Client secret\" below." : "下記に「クライアントID」と「クライアントシークレット」を入力してください。", 11 | "Client ID" : "クライアント ID", 12 | "Client secret" : "クライアントシークレット", 13 | "Successfully connected to Google!" : "Google への接続に成功しました!", 14 | "Sign in with Google" : "Googleでサインイン", 15 | "Google data migration" : "Google データの移行", 16 | "Authentication" : "認証", 17 | "Connected as {user}" : "{user} を接続済み", 18 | "Disconnect from Google" : "Google から切断", 19 | "Contacts" : "連絡先", 20 | "Choose where to import the contacts" : "連絡先をインポートする場所を選択してください", 21 | "New address book" : "新しいアドレス帳", 22 | "address book name" : "アドレス帳の名前", 23 | "Calendars" : "カレンダー", 24 | "Import calendar" : "カレンダーのインポート", 25 | "Drive" : "ドライブ", 26 | "Ignore shared files" : "共有済みファイルを無視" 27 | },"pluralForm" :"nplurals=1; plural=0;" 28 | } -------------------------------------------------------------------------------- /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 | }, 10 | "nplurals=2; plural=(n!=1);"); 11 | -------------------------------------------------------------------------------- /l10n/ka_GE.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "კლიენტის ID", 3 | "Client secret" : "კლიენტის საიდუმლო", 4 | "Authentication" : "აუტენტიფიკაცია", 5 | "Contacts" : "კონტაქტები", 6 | "Import calendar" : "კალენდრის იმპორტი" 7 | },"pluralForm" :"nplurals=2; plural=(n!=1);" 8 | } -------------------------------------------------------------------------------- /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 | "Drive" : "드라이브" 18 | }, 19 | "nplurals=1; plural=0;"); 20 | -------------------------------------------------------------------------------- /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 | "Drive" : "드라이브" 16 | },"pluralForm" :"nplurals=1; plural=0;" 17 | } -------------------------------------------------------------------------------- /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 | }, 9 | "nplurals=2; plural=(n != 1);"); 10 | -------------------------------------------------------------------------------- /l10n/lb.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Client ID" : "Client ID", 3 | "Contacts" : "Kontakter", 4 | "Calendars" : "Kalenneren", 5 | "Import calendar" : "Kalenner importéiren" 6 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 7 | } -------------------------------------------------------------------------------- /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 | "Private event" : "Privatus įvykis", 11 | "Google Calendar import" : "„Google“ kalendoriaus importavimas", 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 Google Drive import job at {date}" : "Paskutinė „Google“ disko importavimo užduotis ties {date}", 26 | "Google Drive background import process will begin soon." : "Netrukus prasidės foninis „Google“ disko 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 | "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 contacts" : "Nepavyko gauti „Google“ adresatų skaičiaus", 37 | "Failed to get address book list" : "Nepavyko gauti adresų knygų sąrašo", 38 | "Failed to import Google calendar" : "Nepavyko importuoti „Google“ kalendoriaus", 39 | "Starting importing files in {targetPath} directory" : "Pradedamas failų importavimas į {targetPath} katalogą", 40 | "Failed to start importing Google Drive" : "Nepavyko pradėti „Google“ disko importavimo", 41 | "Google data migration" : "„Google“ duomenų perkėlimas", 42 | "Authentication" : "Tapatybės nustatymas", 43 | "Connected as {user}" : "Prisijungta kaip {user}", 44 | "Disconnect from Google" : "Atsijungti nuo „Google“", 45 | "Contacts" : "Adresatai", 46 | "{amount} Google contacts" : "„Google“ adresatų: {amount}", 47 | "Import Google Contacts in Nextcloud" : "Importuoti „Google“ adresatus į Nextcloud", 48 | "Choose where to import the contacts" : "Pasirinkite kur importuoti adresatus", 49 | "New address book" : "Nauja adresų knyga", 50 | "address book name" : "adresų knygos pavadinimas", 51 | "Calendars" : "Kalendoriai", 52 | "Import calendar" : "Importuoti kalendorių", 53 | "Drive" : "Vairavimas", 54 | "Ignore shared files" : "Nepaisyti bendrinamų failų", 55 | "Import directory" : "Importuoti katalogą", 56 | "Import Google Drive files" : "Importuoti „Google“ disko failus", 57 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "Jūsų „Google“ diskas yra didesnis, nei jums yra likę laisvos vietos ({formSpace})", 58 | "Cancel Google Drive import" : "Atsisakyti „Google“ disko importavimo", 59 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["Importuotas {amount} failas ({progress}%)","Importuoti {amount} failai ({progress}%)","Importuota {amount} failų ({progress}%)","Importuotas {amount} failas ({progress}%)"] 60 | }, 61 | "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);"); 62 | -------------------------------------------------------------------------------- /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 | "Private event" : "Privatus įvykis", 9 | "Google Calendar import" : "„Google“ kalendoriaus importavimas", 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 Google Drive import job at {date}" : "Paskutinė „Google“ disko importavimo užduotis ties {date}", 24 | "Google Drive background import process will begin soon." : "Netrukus prasidės foninis „Google“ disko 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 | "Successfully connected to Google!" : "Sėkmingai prisijungta prie „Google“!", 27 | "Google connection error:" : "Ryšio su „Google“ klaida:", 28 | "Google options saved" : "„Google“ parinktys įrašytos", 29 | "Failed to save Google options" : "Nepavyko įrašyti „Google“ parinkčių", 30 | "Sign in with Google" : "Prisijungti naudojant „Google“", 31 | "Failed to save Google OAuth state" : "Nepavyko įrašyti „Google“ „OAuth“ būsenos", 32 | "Failed to get Google Drive information" : "Nepavyko gauti informacijos apie „Google“ diską", 33 | "Failed to get calendar list" : "Nepavyko gauti kalendorių sąrašo", 34 | "Failed to get number of Google contacts" : "Nepavyko gauti „Google“ adresatų skaičiaus", 35 | "Failed to get address book list" : "Nepavyko gauti adresų knygų sąrašo", 36 | "Failed to import Google calendar" : "Nepavyko importuoti „Google“ kalendoriaus", 37 | "Starting importing files in {targetPath} directory" : "Pradedamas failų importavimas į {targetPath} katalogą", 38 | "Failed to start importing Google Drive" : "Nepavyko pradėti „Google“ disko importavimo", 39 | "Google data migration" : "„Google“ duomenų perkėlimas", 40 | "Authentication" : "Tapatybės nustatymas", 41 | "Connected as {user}" : "Prisijungta kaip {user}", 42 | "Disconnect from Google" : "Atsijungti nuo „Google“", 43 | "Contacts" : "Adresatai", 44 | "{amount} Google contacts" : "„Google“ adresatų: {amount}", 45 | "Import Google Contacts in Nextcloud" : "Importuoti „Google“ adresatus į Nextcloud", 46 | "Choose where to import the contacts" : "Pasirinkite kur importuoti adresatus", 47 | "New address book" : "Nauja adresų knyga", 48 | "address book name" : "adresų knygos pavadinimas", 49 | "Calendars" : "Kalendoriai", 50 | "Import calendar" : "Importuoti kalendorių", 51 | "Drive" : "Vairavimas", 52 | "Ignore shared files" : "Nepaisyti bendrinamų failų", 53 | "Import directory" : "Importuoti katalogą", 54 | "Import Google Drive files" : "Importuoti „Google“ disko failus", 55 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "Jūsų „Google“ diskas yra didesnis, nei jums yra likę laisvos vietos ({formSpace})", 56 | "Cancel Google Drive import" : "Atsisakyti „Google“ disko importavimo", 57 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["Importuotas {amount} failas ({progress}%)","Importuoti {amount} failai ({progress}%)","Importuota {amount} failų ({progress}%)","Importuotas {amount} failas ({progress}%)"] 58 | },"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);" 59 | } -------------------------------------------------------------------------------- /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 | "Failed to get address book list" : "Neizdevās iegūt adrešu grāmatu sarakstu", 10 | "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.", 11 | "Authentication" : "Autentifikācija", 12 | "Connected as {user}" : "Savienojies kā {user}", 13 | "Contacts" : "Kontakti", 14 | "New address book" : "Jauna adrešu grāmata", 15 | "address book name" : "adrešu grāmatas nosaukums", 16 | "Import in \"{name}\" address book" : "Ievietot adrešu grāmatā \"{name}\"", 17 | "Calendars" : "Kalendāri", 18 | "Import calendar" : "Ievietot kalendāru", 19 | "Drive" : "Braukt" 20 | }, 21 | "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"); 22 | -------------------------------------------------------------------------------- /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 | "Failed to get address book list" : "Neizdevās iegūt adrešu grāmatu sarakstu", 8 | "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.", 9 | "Authentication" : "Autentifikācija", 10 | "Connected as {user}" : "Savienojies kā {user}", 11 | "Contacts" : "Kontakti", 12 | "New address book" : "Jauna adrešu grāmata", 13 | "address book name" : "adrešu grāmatas nosaukums", 14 | "Import in \"{name}\" address book" : "Ievietot adrešu grāmatā \"{name}\"", 15 | "Calendars" : "Kalendāri", 16 | "Import calendar" : "Ievietot kalendāru", 17 | "Drive" : "Braukt" 18 | },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" 19 | } -------------------------------------------------------------------------------- /l10n/nl.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Missing refresh token in Google response." : "Ontbrekend refresh token in Google antwoord.", 5 | "Error getting OAuth access token." : "Fout bij ophalen OAuth access token", 6 | "Error during OAuth exchanges" : "Fout tijdens OAuth uitwisselingen", 7 | "Google" : "Google", 8 | "OAuth access token refused" : "OAuth access token geweigerd", 9 | "Bad credentials" : "Foute inloggegevens", 10 | "Private event" : "Privé-afspraak", 11 | "Google Calendar import" : "Google Agenda-import", 12 | "Connected accounts" : "Verbonden accounts", 13 | "Data migration" : "Gegevensmigratie", 14 | "Google integration" : "Google integratie", 15 | "Import Google data into Nextcloud" : "Importeren Google data in Nextcloud", 16 | "Google admin options saved" : "Google beheeropties bewaard", 17 | "Failed to save Google admin options" : "Kon Google admin-opties niet opslaan", 18 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "Als je wilt dat je Nextcloud-gebruikers bij Google kunnen authentiseren, maak dan een OAuth-applicatie aan in je Google-instellingen.", 19 | "Google API settings" : "Google API instellingen", 20 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "Ga naar \"APIs & Services\" => \"Credentials\" en klik op \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\".", 21 | "Set the \"Application type\" to \"Web application\" and give a name to the application." : "Zet het \"Application type\" in op \"Web application\" en geef de applicatie een naam.", 22 | "Make sure you set one \"Authorized redirect URI\" to" : "Zorg ervoor dat je de \"Authorized redirect URI\" instelt op", 23 | "Put the \"Client ID\" and \"Client secret\" below." : "Zet de \"Client ID\" en \"Client secret\" hieronder.", 24 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "Je Nextcloud gebruikers zien dan een \"Verbinden met Google\" knop in hun persoonlijke instellingen.", 25 | "Client ID" : "Client ID", 26 | "Client ID of your Google application" : "Client ID van je Google applicatie", 27 | "Client secret" : "Client secret", 28 | "Client secret of your Google application" : "Client secret of je Google applicatie", 29 | "Last Google Drive import job at {date}" : "Laatste Google Drive importjob op {date}", 30 | "Google Drive background import process will begin soon." : "Google Drive achtergrond importproces begint zometeen.", 31 | "You can close this page. You will be notified when it finishes." : "Je kunt deze pagina sluiten. Je krijgt een melding wanneer het klaar is.", 32 | "Successfully connected to Google!" : "Succesvol verbonden met Google!", 33 | "Google connection error:" : "Google verbindingsfout:", 34 | "Google options saved" : "Google opties bewaard.", 35 | "Failed to save Google options" : "Kon Google-opties niet opslaan", 36 | "Sign in with Google" : "Inloggen met Google", 37 | "Failed to save Google OAuth state" : "Kan Google OAuth-status niet bewaren", 38 | "Failed to get Google Drive information" : "Kon Google Drive informatie niet ophalen", 39 | "Failed to get calendar list" : "Kalenderlijst ophalen mislukt", 40 | "Failed to get number of Google contacts" : "Kon aantal Google contactpersonen niet ophalen", 41 | "Failed to get address book list" : "Adresboekentlijst ophalen mislukt", 42 | "Failed to import Google calendar" : "Kon Google agenda niet ophalen", 43 | "Starting importing files in {targetPath} directory" : "Beginnen met importeren bestanden in {targetPath} directory", 44 | "Failed to start importing Google Drive" : "Kon import Google drive niet starten", 45 | "Choose where to write imported files" : "Kies waar geïmporteerde bestanden moeten worden weggeschreven", 46 | "Google data migration" : "Google gegevensmigratie", 47 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "Geen Google OAuth app geconfigureerd. Vraag je Nextcloud beheerder om Google verbonden accounts beheersectie te configureren.", 48 | "Authentication" : "Authenticatie", 49 | "Connected as {user}" : "Verbonden als {user}", 50 | "Disconnect from Google" : "Verbinding met Google verbreken", 51 | "Contacts" : "Contactpersonen", 52 | "{amount} Google contacts" : "{amount} Google contactpersonen", 53 | "Import Google Contacts in Nextcloud" : "Importeren Google Contactpersonen in Nextcloud", 54 | "Choose where to import the contacts" : "Kies waar contactpersonen geïmporteerd moeten worden", 55 | "New address book" : "Nieuw adresboek", 56 | "address book name" : "naam adresboek", 57 | "Calendars" : "Kalenders", 58 | "Import calendar" : "Importeer agenda", 59 | "Drive" : "Drive", 60 | "Ignore shared files" : "Negeren gedeelde bestanden", 61 | "Google documents import format" : "Google documents importformaat", 62 | "Import directory" : "Importdirectory", 63 | "Import Google Drive files" : "Import Google Drive bestanden", 64 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "Je Google Drive is groter dan je resterende ruimte in ({formSpace})", 65 | "Cancel Google Drive import" : "Annuleren Google Drive import", 66 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["{amount} bestand geïmporteerd ({progress}%)","{amount} bestanden geïmporteerd ({progress}%)"] 67 | }, 68 | "nplurals=2; plural=(n != 1);"); 69 | -------------------------------------------------------------------------------- /l10n/nl.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Missing refresh token in Google response." : "Ontbrekend refresh token in Google antwoord.", 3 | "Error getting OAuth access token." : "Fout bij ophalen OAuth access token", 4 | "Error during OAuth exchanges" : "Fout tijdens OAuth uitwisselingen", 5 | "Google" : "Google", 6 | "OAuth access token refused" : "OAuth access token geweigerd", 7 | "Bad credentials" : "Foute inloggegevens", 8 | "Private event" : "Privé-afspraak", 9 | "Google Calendar import" : "Google Agenda-import", 10 | "Connected accounts" : "Verbonden accounts", 11 | "Data migration" : "Gegevensmigratie", 12 | "Google integration" : "Google integratie", 13 | "Import Google data into Nextcloud" : "Importeren Google data in Nextcloud", 14 | "Google admin options saved" : "Google beheeropties bewaard", 15 | "Failed to save Google admin options" : "Kon Google admin-opties niet opslaan", 16 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "Als je wilt dat je Nextcloud-gebruikers bij Google kunnen authentiseren, maak dan een OAuth-applicatie aan in je Google-instellingen.", 17 | "Google API settings" : "Google API instellingen", 18 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "Ga naar \"APIs & Services\" => \"Credentials\" en klik op \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\".", 19 | "Set the \"Application type\" to \"Web application\" and give a name to the application." : "Zet het \"Application type\" in op \"Web application\" en geef de applicatie een naam.", 20 | "Make sure you set one \"Authorized redirect URI\" to" : "Zorg ervoor dat je de \"Authorized redirect URI\" instelt op", 21 | "Put the \"Client ID\" and \"Client secret\" below." : "Zet de \"Client ID\" en \"Client secret\" hieronder.", 22 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "Je Nextcloud gebruikers zien dan een \"Verbinden met Google\" knop in hun persoonlijke instellingen.", 23 | "Client ID" : "Client ID", 24 | "Client ID of your Google application" : "Client ID van je Google applicatie", 25 | "Client secret" : "Client secret", 26 | "Client secret of your Google application" : "Client secret of je Google applicatie", 27 | "Last Google Drive import job at {date}" : "Laatste Google Drive importjob op {date}", 28 | "Google Drive background import process will begin soon." : "Google Drive achtergrond importproces begint zometeen.", 29 | "You can close this page. You will be notified when it finishes." : "Je kunt deze pagina sluiten. Je krijgt een melding wanneer het klaar is.", 30 | "Successfully connected to Google!" : "Succesvol verbonden met Google!", 31 | "Google connection error:" : "Google verbindingsfout:", 32 | "Google options saved" : "Google opties bewaard.", 33 | "Failed to save Google options" : "Kon Google-opties niet opslaan", 34 | "Sign in with Google" : "Inloggen met Google", 35 | "Failed to save Google OAuth state" : "Kan Google OAuth-status niet bewaren", 36 | "Failed to get Google Drive information" : "Kon Google Drive informatie niet ophalen", 37 | "Failed to get calendar list" : "Kalenderlijst ophalen mislukt", 38 | "Failed to get number of Google contacts" : "Kon aantal Google contactpersonen niet ophalen", 39 | "Failed to get address book list" : "Adresboekentlijst ophalen mislukt", 40 | "Failed to import Google calendar" : "Kon Google agenda niet ophalen", 41 | "Starting importing files in {targetPath} directory" : "Beginnen met importeren bestanden in {targetPath} directory", 42 | "Failed to start importing Google Drive" : "Kon import Google drive niet starten", 43 | "Choose where to write imported files" : "Kies waar geïmporteerde bestanden moeten worden weggeschreven", 44 | "Google data migration" : "Google gegevensmigratie", 45 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "Geen Google OAuth app geconfigureerd. Vraag je Nextcloud beheerder om Google verbonden accounts beheersectie te configureren.", 46 | "Authentication" : "Authenticatie", 47 | "Connected as {user}" : "Verbonden als {user}", 48 | "Disconnect from Google" : "Verbinding met Google verbreken", 49 | "Contacts" : "Contactpersonen", 50 | "{amount} Google contacts" : "{amount} Google contactpersonen", 51 | "Import Google Contacts in Nextcloud" : "Importeren Google Contactpersonen in Nextcloud", 52 | "Choose where to import the contacts" : "Kies waar contactpersonen geïmporteerd moeten worden", 53 | "New address book" : "Nieuw adresboek", 54 | "address book name" : "naam adresboek", 55 | "Calendars" : "Kalenders", 56 | "Import calendar" : "Importeer agenda", 57 | "Drive" : "Drive", 58 | "Ignore shared files" : "Negeren gedeelde bestanden", 59 | "Google documents import format" : "Google documents importformaat", 60 | "Import directory" : "Importdirectory", 61 | "Import Google Drive files" : "Import Google Drive bestanden", 62 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "Je Google Drive is groter dan je resterende ruimte in ({formSpace})", 63 | "Cancel Google Drive import" : "Annuleren Google Drive import", 64 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["{amount} bestand geïmporteerd ({progress}%)","{amount} bestanden geïmporteerd ({progress}%)"] 65 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 66 | } -------------------------------------------------------------------------------- /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 | }, 9 | "nplurals=2; plural=(n != 1);"); 10 | -------------------------------------------------------------------------------- /l10n/nn_NO.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Connected accounts" : "Tilkopla kontoar", 3 | "Client ID" : "Klient-ID", 4 | "Authentication" : "Godkjenning", 5 | "Contacts" : "Kontaktar" 6 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 7 | } -------------------------------------------------------------------------------- /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 | }, 13 | "nplurals=2; plural=(n > 1);"); 14 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=2; plural=(n > 1);" 11 | } -------------------------------------------------------------------------------- /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 | }, 13 | "nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 14 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 11 | } -------------------------------------------------------------------------------- /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 | "Drive" : "Conducere" 15 | }, 16 | "nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"); 17 | -------------------------------------------------------------------------------- /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 | "Drive" : "Conducere" 13 | },"pluralForm" :"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));" 14 | } -------------------------------------------------------------------------------- /l10n/sc.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Missing refresh token in Google response." : "Token de agiornamentu chi fartat in sa risposta de Google.", 3 | "Error getting OAuth access token." : "Errore recuperende su token de intrada OAuth.", 4 | "Error during OAuth exchanges" : "Errore in is negotziatziones OAuth ", 5 | "Google" : "Google", 6 | "OAuth access token refused" : "Token de intrada OAuth refudadu", 7 | "Bad credentials" : "Credentziales non bàlidas", 8 | "Private event" : "Evntu privadu", 9 | "Google Calendar import" : "Importatzione de Google Calendar ", 10 | "Connected accounts" : "Contos connètidos", 11 | "Data migration" : "Tramudadura de datos", 12 | "Google integration" : "Integratzione Google", 13 | "Import Google data into Nextcloud" : "Importa is datos de Google in Nextcloud", 14 | "Google admin options saved" : "Sèberos amministrativos de Google sarvados", 15 | "Failed to save Google admin options" : "No at fatu a sarvare is sèberos amministrativos de Google", 16 | "If you want to allow your Nextcloud users to authenticate to Google, create an OAuth application in your Google settings." : "Si boles cunsentire a is utentes tuos de Nextcloud de s'autenticare in Google, crea un'aplicatzione OAuth in sa cunfiguratzione de Google.", 17 | "Google API settings" : "Cunfiguratzione de Google API", 18 | "Go to \"APIs & Services\" => \"Credentials\" and click on \"+ CREATE CREDENTIALS\" -> \"OAuth client ID\"." : "Bae a \"APIs & Servìtzios\" => \"Credentziales\" e incarca subra de \"+ CREA CREDENTZIALES\" -> \"OAuth client ID\".", 19 | "Set the \"Application type\" to \"Web application\" and give a name to the application." : "Cunfigura sa \"Genia de aplicatzione\" comente \"Aplicatzione web\" e dona unu nùmene a s'aplicatzione.", 20 | "Make sure you set one \"Authorized redirect URI\" to" : "Assegura·ti de àere cunfiguradu unu \"URI de re-deretamentu autorizadu\" a", 21 | "Put the \"Client ID\" and \"Client secret\" below." : "Inserta·nche suta su \"ID client\" e \"Segreto del client\" in fatu.", 22 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "Is utentes tuos Nextcloud ant a bìdere unu butone \"Connete a Google\" in sa cunfiguratzione personale issoro.", 23 | "Client ID" : "Cliente ID", 24 | "Client ID of your Google application" : "Cliente ID de s'aplicatzione de Google tua", 25 | "Client secret" : "Cliente segretu", 26 | "Client secret of your Google application" : "Segretu de su cliente de s'aplicatzione tua de Google", 27 | "Last Google Drive import job at {date}" : "Ùrtima operatzione de importatzione dae Google Drive il {date}", 28 | "Google Drive background import process will begin soon." : "Sa fase de importatzione in segundu pranu dae Google Drive at a cumintzare de immoe a pagu.", 29 | "You can close this page. You will be notified when it finishes." : "Connetidu a Google in manera curreta!", 30 | "Successfully connected to Google!" : "Connètidu a Google in manera curreta!", 31 | "Google connection error:" : "Errore de connessione a Google:", 32 | "Google options saved" : "Sèberos de Google sarvados", 33 | "Failed to save Google options" : "No at fatu a sarvare is sèberos de Google ", 34 | "Failed to save Google OAuth state" : "No at fatu a sarvare s'istadu OAuth de Google ", 35 | "Failed to get Google Drive information" : "No at fatu a otènnere is informatziones de Google Drive", 36 | "Failed to get calendar list" : "No at fatu a otènnere s'elencu de is calendàrios.", 37 | "Failed to get number of Google contacts" : "No at fatu a otènnere su nùmeru de is cuntatos de Google", 38 | "Failed to get address book list" : "No at fatu a otènnere s'elencu d is rubricas", 39 | "Failed to import Google calendar" : "No at fatu a importare su calendàriu de Google ", 40 | "Starting importing files in {targetPath} directory" : "Aviamentu de s'importatzione de is archìvios in sa cartella {targetPath}", 41 | "Failed to start importing Google Drive" : "No at fatu a cumintzare s'importatzione de Google Drive", 42 | "Choose where to write imported files" : "Sèbera in ue est a pònnere is archìvios importados", 43 | "Google data migration" : "Tràmuda datos de Google ", 44 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "Peruna Google OAuth app configurada. Pedi a s'amministradore tuo de Nextcloud de cunfigurare sa setzione de administradores de is contos ligados a sa Google.", 45 | "Authentication" : "Autenticatzione", 46 | "Connected as {user}" : "Connètidu comente {user}", 47 | "Disconnect from Google" : "Disconnètidu dae Google", 48 | "Contacts" : "Cuntatos", 49 | "{amount} Google contacts" : "{amount} cuntatos Google ", 50 | "Import Google Contacts in Nextcloud" : "Importa Google Contacts in Nextcloud", 51 | "Choose where to import the contacts" : "Sèbera in ue est a importare is cuntatos", 52 | "New address book" : "Rubrica noa", 53 | "address book name" : "Importa calendàriu", 54 | "Calendars" : "Calendàrios", 55 | "Import calendar" : "Importa calendàrios", 56 | "Drive" : "Drive", 57 | "Ignore shared files" : "Ignora archìvios cumpartzidos", 58 | "Google documents import format" : "Formadu de importatzione de is documentos de Google", 59 | "Import directory" : "Importa cartella", 60 | "Import Google Drive files" : "Importas archìvios dae Google Drive", 61 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "Su Google Drive tuo est prus mannu de 's'ispàtziu chi est abarradu ({formSpace})", 62 | "Cancel Google Drive import" : "Annulla importatzione dae Google Drive", 63 | "_{amount} file imported ({progress}%)_::_{amount} files imported ({progress}%)_" : ["{amount} archìvios importados ({progress}%)","{amount} archìvios importados ({progress}%)"] 64 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 65 | } -------------------------------------------------------------------------------- /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 | }, 14 | "nplurals=2; plural=(n != 1);"); 15 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 12 | } -------------------------------------------------------------------------------- /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 | "Private event" : "Zasebni dogodek", 11 | "Google Calendar import" : "Uvoz koledarja Google", 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 Google Drive import job at {date}" : "Zadnji uvoz datotek z računa Goggle Drive je bil izveden {date}", 30 | "Google Drive background import process will begin soon." : "Uvažanje datotek z računa Google Drive bo kmalu začeto.", 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 | "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 contacts" : "Pridobivanje podatka o številu stikov je spodletelo", 41 | "Failed to get address book list" : "Pridobivanje seznama imenika je spodletelo", 42 | "Failed to import Google calendar" : "Uvažanje koledarja Google je spodletelo", 43 | "Starting importing files in {targetPath} directory" : "Začeto je uvažanje datotek v mapo {targetPath}.", 44 | "Failed to start importing Google Drive" : "Uvažanje vsebine Google Drive je spodletelo", 45 | "Choose where to write imported files" : "Izbor mesta za shranjevanje uvoženih datotek", 46 | "Google data migration" : "Preselitev podatkov Google", 47 | "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.", 48 | "Authentication" : "Overitev", 49 | "Connected as {user}" : "Povezan je uporabniški račun {user}", 50 | "Disconnect from Google" : "Odklopi račun Google", 51 | "Contacts" : "Stiki", 52 | "{amount} Google contacts" : "{amount} stikov Google", 53 | "Import Google Contacts in Nextcloud" : "Uvozi Stike Google v Nextcloud", 54 | "Choose where to import the contacts" : "Izbor mesta za uvoz stikov", 55 | "New address book" : "Nov imenik", 56 | "address book name" : "ime imenika", 57 | "Calendars" : "Koledarji", 58 | "Import calendar" : "Uvozi koledar", 59 | "Drive" : "Drive", 60 | "Ignore shared files" : "Prezri datoteke v souporabi", 61 | "Google documents import format" : "Zapis za uvoz dokumentov Google", 62 | "Import directory" : "Uvozi mapo", 63 | "Import Google Drive files" : "Uvozi datoteke z oblaka Google Drive", 64 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "Velikost datotek v oblaku Google Drive je večja od preostalega prostora ({formSpace})", 65 | "Cancel Google Drive import" : "Prekliči uvoz datotek Google Drive", 66 | "_{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}%)"] 67 | }, 68 | "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"); 69 | -------------------------------------------------------------------------------- /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 | "Private event" : "Zasebni dogodek", 9 | "Google Calendar import" : "Uvoz koledarja Google", 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 Google Drive import job at {date}" : "Zadnji uvoz datotek z računa Goggle Drive je bil izveden {date}", 28 | "Google Drive background import process will begin soon." : "Uvažanje datotek z računa Google Drive bo kmalu začeto.", 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 | "Successfully connected to Google!" : "Povezava z računom Google je uspešno vzpostavljena!", 31 | "Google connection error:" : "Napaka povezave Google:", 32 | "Google options saved" : "Nastavitve Google so shranjene", 33 | "Failed to save Google options" : "Shranjevanje nastavitev Google je spodletelo", 34 | "Sign in with Google" : "Prijava z računom Google", 35 | "Failed to save Google OAuth state" : "Shranjevanje stanja Google OAuth je spodletelo", 36 | "Failed to get Google Drive information" : "Pridobivanje podrobnosti datotek Google Drive je spodletelo", 37 | "Failed to get calendar list" : "Pridobivanje seznama koledarja je spodletelo", 38 | "Failed to get number of Google contacts" : "Pridobivanje podatka o številu stikov je spodletelo", 39 | "Failed to get address book list" : "Pridobivanje seznama imenika je spodletelo", 40 | "Failed to import Google calendar" : "Uvažanje koledarja Google je spodletelo", 41 | "Starting importing files in {targetPath} directory" : "Začeto je uvažanje datotek v mapo {targetPath}.", 42 | "Failed to start importing Google Drive" : "Uvažanje vsebine Google Drive je spodletelo", 43 | "Choose where to write imported files" : "Izbor mesta za shranjevanje uvoženih datotek", 44 | "Google data migration" : "Preselitev podatkov Google", 45 | "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.", 46 | "Authentication" : "Overitev", 47 | "Connected as {user}" : "Povezan je uporabniški račun {user}", 48 | "Disconnect from Google" : "Odklopi račun Google", 49 | "Contacts" : "Stiki", 50 | "{amount} Google contacts" : "{amount} stikov Google", 51 | "Import Google Contacts in Nextcloud" : "Uvozi Stike Google v Nextcloud", 52 | "Choose where to import the contacts" : "Izbor mesta za uvoz stikov", 53 | "New address book" : "Nov imenik", 54 | "address book name" : "ime imenika", 55 | "Calendars" : "Koledarji", 56 | "Import calendar" : "Uvozi koledar", 57 | "Drive" : "Drive", 58 | "Ignore shared files" : "Prezri datoteke v souporabi", 59 | "Google documents import format" : "Zapis za uvoz dokumentov Google", 60 | "Import directory" : "Uvozi mapo", 61 | "Import Google Drive files" : "Uvozi datoteke z oblaka Google Drive", 62 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "Velikost datotek v oblaku Google Drive je večja od preostalega prostora ({formSpace})", 63 | "Cancel Google Drive import" : "Prekliči uvoz datotek Google Drive", 64 | "_{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}%)"] 65 | },"pluralForm" :"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" 66 | } -------------------------------------------------------------------------------- /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 | }, 10 | "nplurals=2; plural=(n != 1);"); 11 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 8 | } -------------------------------------------------------------------------------- /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 | "Sign in with Google" : "Sign in with Google", 16 | "Choose where to write imported files" : "Välj var importerade filer ska skrivas", 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 | "Drive" : "Biltur", 28 | "Import directory" : "Importera katalog" 29 | }, 30 | "nplurals=2; plural=(n != 1);"); 31 | -------------------------------------------------------------------------------- /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 | "Sign in with Google" : "Sign in with Google", 14 | "Choose where to write imported files" : "Välj var importerade filer ska skrivas", 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 | "Drive" : "Biltur", 26 | "Import directory" : "Importera katalog" 27 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 28 | } -------------------------------------------------------------------------------- /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 | }, 14 | "nplurals=1; plural=0;"); 15 | -------------------------------------------------------------------------------- /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 | },"pluralForm" :"nplurals=1; plural=0;" 12 | } -------------------------------------------------------------------------------- /l10n/uz.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "integration_google", 3 | { 4 | "Bad credentials" : "Akkaunt ma'lumotlari xato", 5 | "Connected accounts" : "Ulangan akkauntlar", 6 | "Client ID" : "Mijoz identifikatori", 7 | "Authentication" : "Autentifikatsiya", 8 | "Contacts" : "Contacts", 9 | "Calendars" : "Taqvimlar" 10 | }, 11 | "nplurals=1; plural=0;"); 12 | -------------------------------------------------------------------------------- /l10n/uz.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Bad credentials" : "Akkaunt ma'lumotlari xato", 3 | "Connected accounts" : "Ulangan akkauntlar", 4 | "Client ID" : "Mijoz identifikatori", 5 | "Authentication" : "Autentifikatsiya", 6 | "Contacts" : "Contacts", 7 | "Calendars" : "Taqvimlar" 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 | "Drive" : "Lái xe" 13 | }, 14 | "nplurals=1; plural=0;"); 15 | -------------------------------------------------------------------------------- /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 | "Drive" : "Lái xe" 11 | },"pluralForm" :"nplurals=1; plural=0;" 12 | } -------------------------------------------------------------------------------- /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 | "Private event" : "私人活动", 11 | "Google Calendar import" : "导入 Google 日历", 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 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "您的Nextcloud用户将在他们的个人设置中看到一个“连接到Google”按钮。 ", 24 | "Client ID" : "客户端ID", 25 | "Client ID of your Google application" : "您的Google应用程序的客户端ID ", 26 | "Client secret" : "客户端 secret", 27 | "Google Drive background import process will begin soon." : "Google云端硬盘后台导入过程即将开始。", 28 | "You can close this page. You will be notified when it finishes." : "您可以关闭此页面。当它完成时,您将收到通知。", 29 | "Successfully connected to Google!" : "成功连接到Google!", 30 | "Google connection error:" : "Google连接错误:", 31 | "Google options saved" : "Google 选项已保存", 32 | "Failed to save Google options" : "保存Google选项失败", 33 | "Sign in with Google" : "使用Google登录", 34 | "Failed to save Google OAuth state" : "保存Google OAuth状态失败", 35 | "Failed to get Google Drive information" : "无法获取Google云端硬盘信息", 36 | "Failed to get calendar list" : "获取日历列表失败", 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 Drive" : "无法开始导入Google云端硬盘", 41 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "没有配置Google OAuth应用。请求你的Nextcloud管理员配置谷歌连接帐户管理部分。", 42 | "Authentication" : "验证", 43 | "Connected as {user}" : "作为 {user} 已连接", 44 | "Disconnect from Google" : "已从Google断开连接", 45 | "Contacts" : "联系人", 46 | "{amount} Google contacts" : "{amount} 位Google联系人", 47 | "Import Google Contacts in Nextcloud" : "在Nextcloud中导入Google联系人", 48 | "Choose where to import the contacts" : "选择从哪里导入联系人", 49 | "New address book" : "新通讯录", 50 | "address book name" : "通讯录名称", 51 | "Calendars" : "日历", 52 | "Import calendar" : "导入日历", 53 | "Drive" : "驾驶", 54 | "Ignore shared files" : "忽略共享的文件", 55 | "Google documents import format" : "Google 文件导入格式", 56 | "Import directory" : "导入文件夹", 57 | "Import Google Drive files" : "导入 Google Drive 文件", 58 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "您的Google云端硬盘大于你的剩余空间 ({formSpace})", 59 | "Cancel Google Drive import" : "取消 Google Drive 导入" 60 | }, 61 | "nplurals=1; plural=0;"); 62 | -------------------------------------------------------------------------------- /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 | "Private event" : "私人活动", 9 | "Google Calendar import" : "导入 Google 日历", 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 | "Your Nextcloud users will then see a \"Connect to Google\" button in their personal settings." : "您的Nextcloud用户将在他们的个人设置中看到一个“连接到Google”按钮。 ", 22 | "Client ID" : "客户端ID", 23 | "Client ID of your Google application" : "您的Google应用程序的客户端ID ", 24 | "Client secret" : "客户端 secret", 25 | "Google Drive background import process will begin soon." : "Google云端硬盘后台导入过程即将开始。", 26 | "You can close this page. You will be notified when it finishes." : "您可以关闭此页面。当它完成时,您将收到通知。", 27 | "Successfully connected to Google!" : "成功连接到Google!", 28 | "Google connection error:" : "Google连接错误:", 29 | "Google options saved" : "Google 选项已保存", 30 | "Failed to save Google options" : "保存Google选项失败", 31 | "Sign in with Google" : "使用Google登录", 32 | "Failed to save Google OAuth state" : "保存Google OAuth状态失败", 33 | "Failed to get Google Drive information" : "无法获取Google云端硬盘信息", 34 | "Failed to get calendar list" : "获取日历列表失败", 35 | "Failed to get number of Google contacts" : "无法获取Google联系人数量", 36 | "Failed to get address book list" : "获取通讯录列表失败", 37 | "Failed to import Google calendar" : "导入Google日历失败", 38 | "Failed to start importing Google Drive" : "无法开始导入Google云端硬盘", 39 | "No Google OAuth app configured. Ask your Nextcloud administrator to configure Google connected accounts admin section." : "没有配置Google OAuth应用。请求你的Nextcloud管理员配置谷歌连接帐户管理部分。", 40 | "Authentication" : "验证", 41 | "Connected as {user}" : "作为 {user} 已连接", 42 | "Disconnect from Google" : "已从Google断开连接", 43 | "Contacts" : "联系人", 44 | "{amount} Google contacts" : "{amount} 位Google联系人", 45 | "Import Google Contacts in Nextcloud" : "在Nextcloud中导入Google联系人", 46 | "Choose where to import the contacts" : "选择从哪里导入联系人", 47 | "New address book" : "新通讯录", 48 | "address book name" : "通讯录名称", 49 | "Calendars" : "日历", 50 | "Import calendar" : "导入日历", 51 | "Drive" : "驾驶", 52 | "Ignore shared files" : "忽略共享的文件", 53 | "Google documents import format" : "Google 文件导入格式", 54 | "Import directory" : "导入文件夹", 55 | "Import Google Drive files" : "导入 Google Drive 文件", 56 | "Your Google Drive is bigger than your remaining space left ({formSpace})" : "您的Google云端硬盘大于你的剩余空间 ({formSpace})", 57 | "Cancel Google Drive import" : "取消 Google Drive 导入" 58 | },"pluralForm" :"nplurals=1; plural=0;" 59 | } -------------------------------------------------------------------------------- /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/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_drive_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 file was imported from Google Drive.', '%n files were imported from Google Drive.', $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 | default: 78 | // Unknown subject => Unknown notification => throw 79 | throw new InvalidArgumentException(); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /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/Service/Utils/FileUtils.php: -------------------------------------------------------------------------------- 1 | 15) { 39 | $filename = 'Untitled_' . $id; 40 | $this->logger->warning('Maximum recursion depth reached while sanitizing filename: ' . ($originalFilename ?? $filename) . ' renaming to ' . $filename); 41 | return $filename; 42 | } 43 | 44 | if ($originalFilename === null) { 45 | $originalFilename = $filename; 46 | } 47 | 48 | // Use Nextcloud 32+ validator if available 49 | if (version_compare($this->config->getSystemValueString('version', '0.0.0'), '32.0.0', '>=')) { 50 | $this->logger->debug('Using Nextcloud 32+ filename validator for sanitization.'); 51 | try { 52 | return $this->validator->sanitizeFilename($filename); 53 | } catch (\InvalidArgumentException|NotFoundExceptionInterface|ContainerExceptionInterface $exception) { 54 | $this->logger->error('Unable to sanitize filename: ' . $filename, ['exception' => $exception]); 55 | return 'Untitled_' . $id; 56 | } 57 | } else { 58 | $this->logger->debug('Using legacy filename sanitization method.'); 59 | } 60 | 61 | // Trim whitespace and trailing dots 62 | $filename = rtrim(trim($filename), '.'); 63 | 64 | // Append ID if needed 65 | if ($originalFilename !== $filename && strpos($filename, $id) === false) { 66 | $filename = self::appendIdBeforeExtension($filename, $id); 67 | } 68 | 69 | // Enforce max length 70 | $maxLength = 254; 71 | if (mb_strlen($filename) > $maxLength) { 72 | $filename = self::truncateAndAppendId($filename, $id, $maxLength); 73 | } 74 | 75 | try { 76 | $this->validator->validateFilename($filename); 77 | if ($recursionDepth > 0) { 78 | $this->logger->info('Filename sanitized successfully: "' . $filename . '" (original: "' . $originalFilename . '")'); 79 | } 80 | return $filename; 81 | } catch (\Throwable $exception) { 82 | $this->logger->warning('Exception during filename validation: ' . $filename, ['exception' => $exception]); 83 | $filename = self::handleFilenameException($filename, $id, $exception, $this->logger); 84 | if (strpos($filename, $id) === false) { 85 | $filename = self::appendIdBeforeExtension($filename, $id); 86 | } 87 | return $this->sanitizeFilename($filename, $id, $recursionDepth + 1, $originalFilename); 88 | } 89 | } 90 | 91 | private static function appendIdBeforeExtension(string $filename, string $id): string { 92 | $pathInfo = pathinfo($filename); 93 | if (isset($pathInfo['extension'])) { 94 | return $pathInfo['filename'] . '_' . $id . '.' . $pathInfo['extension']; 95 | } 96 | return $filename . '_' . $id; 97 | } 98 | 99 | private static function truncateAndAppendId(string $filename, string $id, int $maxLength): string { 100 | $pathInfo = pathinfo($filename); 101 | $baseLength = $maxLength - mb_strlen($id) - 2; 102 | if (isset($pathInfo['extension'])) { 103 | $baseLength -= mb_strlen($pathInfo['extension']); 104 | return mb_substr($pathInfo['filename'], 0, $baseLength) . '_' . $id . '.' . $pathInfo['extension']; 105 | } 106 | return mb_substr($filename, 0, $baseLength) . '_' . $id; 107 | } 108 | 109 | private static function handleFilenameException(string $filename, string $id, \Throwable $exception, LoggerInterface $logger): string { 110 | if ($exception instanceof FileNameTooLongException) { 111 | return mb_substr($filename, 0, 254 - mb_strlen($id) - 2); 112 | } 113 | if ($exception instanceof EmptyFileNameException) { 114 | return 'Untitled'; 115 | } 116 | if ($exception instanceof InvalidCharacterInPathException) { 117 | if (preg_match('/"(.*?)"/', $exception->getMessage(), $matches)) { 118 | $invalidChars = array_merge(str_split($matches[1]), ['"']); 119 | return str_replace($invalidChars, '-', $filename); 120 | } 121 | } 122 | if ($exception instanceof InvalidDirectoryException) { 123 | $logger->error('Invalid directory detected in filename: ' . $exception->getMessage()); 124 | return 'Untitled'; 125 | } 126 | if ($exception instanceof ReservedWordException) { 127 | if (preg_match('/"(.*?)"/', $exception->getMessage(), $matches)) { 128 | $reservedWord = $matches[1]; 129 | return str_ireplace($reservedWord, '-' . $reservedWord . '-', $filename); 130 | } 131 | } 132 | $logger->error('Unknown exception encountered during filename sanitization: ' . $filename); 133 | return 'Untitled'; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /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) { 41 | return new TemplateResponse(Application::APP_ID, 'personalSettings'); 42 | } 43 | $userName = $this->config->getUserValue($this->userId, Application::APP_ID, 'user_name'); 44 | $driveOutputDir = $this->config->getUserValue($this->userId, Application::APP_ID, 'drive_output_dir', '/Google Drive'); 45 | $driveOutputDir = $driveOutputDir ?: '/Google Drive'; 46 | $considerAllEvents = $this->config->getUserValue($this->userId, Application::APP_ID, 'consider_all_events', '1') === '1'; 47 | $considerSharedFiles = $this->config->getUserValue($this->userId, Application::APP_ID, 'consider_shared_files', '0') === '1'; 48 | $considerSharedAlbums = $this->config->getUserValue($this->userId, Application::APP_ID, 'consider_shared_albums', '0') === '1'; 49 | $considerOtherContacts = $this->config->getUserValue($this->userId, Application::APP_ID, 'consider_other_contacts', '0') === '1'; 50 | $documentFormat = $this->config->getUserValue($this->userId, Application::APP_ID, 'document_format', 'openxml'); 51 | if (!in_array($documentFormat, ['openxml', 'opendoc'])) { 52 | $documentFormat = 'openxml'; 53 | } 54 | 55 | // for OAuth 56 | $clientID = $this->secretService->getEncryptedAppValue('client_id'); 57 | $clientSecret = $this->secretService->getEncryptedAppValue('client_secret') !== ''; 58 | $usePopup = $this->config->getAppValue(Application::APP_ID, 'use_popup', '0'); 59 | 60 | // get free space 61 | $userFolder = $this->root->getUserFolder($this->userId); 62 | $freeSpace = self::getFreeSpace($userFolder, $driveOutputDir); 63 | $user = $this->userManager->get($this->userId); 64 | 65 | // make a request to potentially refresh the token before the settings page is loaded 66 | $accessToken = $this->secretService->getEncryptedUserValue($this->userId, 'token'); 67 | if ($accessToken) { 68 | $this->googleAPIService->request($this->userId, 'oauth2/v1/userinfo', ['alt' => 'json']); 69 | } 70 | 71 | // Get scopes of user 72 | $userScopesString = $this->config->getUserValue($this->userId, Application::APP_ID, 'user_scopes', '{}'); 73 | /** @var bool|null|array $userScopes */ 74 | $userScopes = json_decode($userScopesString, true); 75 | if (!is_array($userScopes)) { 76 | $userScopes = ['nothing' => 'nothing']; 77 | } 78 | 79 | $userConfig = [ 80 | 'client_id' => $clientID, 81 | 'client_secret' => $clientSecret, 82 | 'use_popup' => ($usePopup === '1'), 83 | 'user_name' => $userName, 84 | 'free_space' => $freeSpace, 85 | 'user_quota' => $user === null ? '' : $user->getQuota(), 86 | 'consider_all_events' => $considerAllEvents, 87 | 'consider_shared_files' => $considerSharedFiles, 88 | 'consider_shared_albums' => $considerSharedAlbums, 89 | 'consider_other_contacts' => $considerOtherContacts, 90 | 'document_format' => $documentFormat, 91 | 'drive_output_dir' => $driveOutputDir, 92 | 'user_scopes' => $userScopes, 93 | ]; 94 | $this->initialStateService->provideInitialState('user-config', $userConfig); 95 | return new TemplateResponse(Application::APP_ID, 'personalSettings'); 96 | } 97 | 98 | public function getSection(): string { 99 | return 'migration'; 100 | } 101 | 102 | public function getPriority(): int { 103 | return 10; 104 | } 105 | 106 | /** 107 | * @param Folder $userRoot 108 | * @param string $outputDir 109 | * @return bool|float|int 110 | * @throws NotFoundException 111 | */ 112 | public static function getFreeSpace(Folder $userRoot, string $outputDir) { 113 | try { 114 | // OutputDir can be on an external storage which can have more free space 115 | $freeSpace = $userRoot->get($outputDir)->getStorage()->free_space('/'); 116 | } catch (Throwable $e) { 117 | $freeSpace = false; 118 | } 119 | return $freeSpace !== false && $freeSpace > 0 ? $freeSpace : $userRoot->getStorage()->free_space('/'); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /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 vite --mode production build", 11 | "dev": "NODE_ENV=development vite --mode development build", 12 | "watch": "NODE_ENV=development vite --mode development build --watch", 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 | "type": "module", 26 | "author": "Julien Veyssier", 27 | "license": "AGPL-3.0", 28 | "bugs": { 29 | "url": "https://github.com/nextcloud/integration_google/issues" 30 | }, 31 | "homepage": "https://github.com/nextcloud/integration_google", 32 | "browserslist": [ 33 | "extends @nextcloud/browserslist-config" 34 | ], 35 | "engines": { 36 | "node": "^22.0.0", 37 | "npm": "^10.5.0" 38 | }, 39 | "dependencies": { 40 | "@nextcloud/auth": "^2.5.1", 41 | "@nextcloud/axios": "2.5.1", 42 | "@nextcloud/dialogs": "^7.0.0-rc.1", 43 | "@nextcloud/initial-state": "^2.0.0", 44 | "@nextcloud/l10n": "^3.3.0", 45 | "@nextcloud/moment": "^1.3.4", 46 | "@nextcloud/password-confirmation": "^6.0.0-rc.0", 47 | "@nextcloud/router": "^3.0.1", 48 | "@nextcloud/vue": "^9.0.0-rc.3", 49 | "vue": "^3.5.17", 50 | "vue-material-design-icons": "^5.3.1" 51 | }, 52 | "devDependencies": { 53 | "@nextcloud/babel-config": "^1.2.0", 54 | "@nextcloud/browserslist-config": "^3.0.1", 55 | "@nextcloud/eslint-config": "^8.4.2", 56 | "@nextcloud/stylelint-config": "^3.1.0", 57 | "@nextcloud/vite-config": "^2.3.5", 58 | "vite-plugin-eslint": "^1.8.1", 59 | "vite-plugin-stylelint": "^6.0.0" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /psalm.xml: -------------------------------------------------------------------------------- 1 | 2 | 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 | -------------------------------------------------------------------------------- /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 { createApp } from 'vue' 15 | import AdminSettings from './components/AdminSettings.vue' 16 | import { translate as t, translatePlural as n } from '@nextcloud/l10n' 17 | 18 | // eslint-disable-next-line 19 | 'use strict' 20 | 21 | const app = createApp(AdminSettings) 22 | app.mixin({ methods: { t, n } }) 23 | app.mount('#google_prefs') 24 | -------------------------------------------------------------------------------- /src/components/AdminSettings.vue: -------------------------------------------------------------------------------- 1 | 67 | 68 | 141 | 142 | 173 | -------------------------------------------------------------------------------- /src/components/icons/GoogleIcon.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 41 | -------------------------------------------------------------------------------- /src/components/icons/GoogleIconColor.vue: -------------------------------------------------------------------------------- 1 | 96 | 97 | 116 | -------------------------------------------------------------------------------- /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 { createApp } from 'vue' 15 | import PersonalSettings from './components/PersonalSettings.vue' 16 | import { translate as t, translatePlural as n } from '@nextcloud/l10n' 17 | 18 | // eslint-disable-next-line 19 | 'use strict' 20 | 21 | const app = createApp(PersonalSettings) 22 | app.mixin({ methods: { t, n } }) 23 | app.mount('#google_prefs') 24 | -------------------------------------------------------------------------------- /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.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: '@nextcloud/stylelint-config', 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 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | import { createAppConfig } from '@nextcloud/vite-config' 6 | import eslint from 'vite-plugin-eslint' 7 | import stylelint from 'vite-plugin-stylelint' 8 | import { join } from 'path' 9 | 10 | const isProduction = process.env.NODE_ENV === 'production' 11 | export default createAppConfig({ 12 | personalSettings: join('src', 'personalSettings.js'), 13 | adminSettings: join('src', 'adminSettings.js'), 14 | popupSuccess: join('src', 'popupSuccess.js'), 15 | }, { 16 | config: { 17 | css: { 18 | modules: { 19 | localsConvention: 'camelCase', 20 | }, 21 | preprocessorOptions: { 22 | scss: { api: 'modern-compiler' }, 23 | }, 24 | }, 25 | plugins: [eslint(), stylelint()], 26 | build: { 27 | cssCodeSplit: true, 28 | }, 29 | }, 30 | inlineCSS: { relativeCSSInjection: true }, 31 | minify: isProduction, 32 | }) 33 | --------------------------------------------------------------------------------