Compare commits

..
Author SHA1 Message Date
GitHub Actions bfe2d92619 Auto translate strings 2026-07-25 07:13:46 +00:00
shamoonandGitHub 4f0845b094 Fixhancement: PAPERLESS_ALLAUTH_TRUSTED_PROXY_COUNT (#13281) 2026-07-25 00:12:12 -07:00
shamoonandGitHub dee568e2a6 Tweak: adjust top navbar wrapping when AI chat button visible (#13280) 2026-07-24 23:50:10 -07:00
shamoon f60a2af841 Merge branch 'main' into dev 2026-07-24 19:08:23 -07:00
Trenton HandGitHub 33cd48a17f Fix: preserve document fields during Gotenberg conversion (#13271)
Gotenberg's LibreOffice route enables updateIndexes by default, which refreshes dynamic fields (e.g. auto-dates) to the current date. Disable it so field values are preserved as authored.
2026-07-24 13:59:51 -07:00
Trenton HandGitHub d76dbf5366 Documentation: Add the NumPy CPU baseline increase to the migration guide (#13269) 2026-07-24 09:18:07 -07:00
Trenton HandGitHub b66182cd7b Fix: Makes the email date aware as soon as possible during parsing (#13266) 2026-07-24 15:39:25 +00:00
Trenton HandGitHub 3fe6562c57 Fix: Handle a plain string as Celery sometimes provides for the traceback (#13267) 2026-07-24 15:27:57 +00:00
Trenton HandGitHub 737d568f80 Fix: Emit the torch index into the requirements.txt for people still using it (#13265) 2026-07-24 08:07:52 -07:00
Matthias MastandGitHub b992f9fc05 Fix: handle notes without a user when building the search index (#13260) 2026-07-24 06:39:11 -07:00
github-actions[bot]GitHubgithub-actions <41898282+github-actions[bot]@users.noreply.github.com>
ed714b8a5a Changelog v3.0.2 - GHA (#13244)
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-23 18:56:06 -07:00
shamoon e0ab6a2e75 Merge branch 'dev' 2026-07-23 18:13:49 -07:00
shamoon 6d249b4932 Bump version to 3.0.2 2026-07-23 18:12:59 -07:00
github-actions[bot]GitHubgithub-actions <41898282+github-actions[bot]@users.noreply.github.com>
90ea4f27c4 Changelog v3.0.1 - GHA (#13240)
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-23 17:59:34 -07:00
shamoonandGitHub 371c4f57d3 Fix: fix broken migration in 3.0.1 (#13242) 2026-07-23 17:59:03 -07:00
stumpylog 5569447ea0 Bumps the version to 3.0.1 everywhere 2026-07-23 15:59:53 -07:00
stumpylog 17796357ee Merge remote-tracking branch 'origin/dev' 2026-07-23 15:55:41 -07:00
b47b9800a1 New Crowdin translations by GitHub Action (#13207)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-07-23 15:54:05 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
0be884d441 Chore(deps-dev): Bump postcss (#13236)
Bumps the npm_and_yarn group with 1 update in the /src/paperless_mail/templates directory: [postcss](https://github.com/postcss/postcss).


Updates `postcss` from 8.5.6 to 8.5.22
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.6...8.5.22)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.22
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-23 20:21:15 +00:00
GitHub Actions fce2fbb8f6 Auto translate strings 2026-07-23 19:22:48 +00:00
fa01396dfd Fix: selection_data re-derives the filtered document set 5 times over (#13229)
* Fix: selection_data re-derives the filtered document set 5 times over

_get_selection_data_for_queryset() (powers ?include_selection_data=true on
the document list and search endpoints) computed document_count for
Correspondent/DocumentType/StoragePath/Tag/CustomField by embedding the
caller's full filtered queryset -- filters plus the permission check -- as
a subquery inside 5 separate Count(filter=Q(documents__in=queryset), ...)
calls. Each one re-evaluates that whole queryset from scratch.

Resolve the document ids once into a concrete list and reuse it across all
five annotations instead. For Tag/CustomField specifically (M2M via a
through-model table), also route through annotate_document_count_by_ids()
-- extracted from the tag/custom-field document_count fix (#13203) -- to
avoid the same Count(filter=Q(id__in=...), distinct=True)-on-an-M2M-relation
anti-pattern diagnosed there.

On a 400k-document/1,000-tag corpus, the correspondents portion alone
previously didn't finish within several minutes (killed twice while
investigating, including one run that left a zombie query still consuming
a CPU 30+ minutes later). All five queries together now complete in
~30-35s. Root-caused from a real report (paperless-ngx#13201) via a
different, already-fixed query (#13205) -- this one hasn't been reported
in the wild yet, found by auditing the same call path.

Depends on #13203 for annotate_document_count_by_ids().

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>

* Address review feedback: drop unnecessary ordering before collecting ids

queryset passed into _get_selection_data_for_queryset() carries the
default/user-specified ordering, which is irrelevant once we're only
collecting a flat id list. Clearing it removes a pointless sort.

No measurable change in benchmarking at 400k documents -- the id-list
materialization/IN-clause cost still dominates -- but it's a free,
strictly-correct cleanup, not just noise-neutral in the other direction.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 19:21:20 +00:00
GitHub Actions c9443e890f Auto translate strings 2026-07-23 18:43:46 +00:00
21e4721a82 Chore: reword "Settings > Default permissions" description for clarity (#13232)
---------

Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2026-07-23 18:41:26 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1985da14f8 Chore(deps): Bump pyasn1 in the uv group across 1 directory (#13237)
Bumps the uv group with 1 update in the / directory: [pyasn1](https://github.com/pyasn1/pyasn1).


Updates `pyasn1` from 0.6.3 to 0.6.4
- [Release notes](https://github.com/pyasn1/pyasn1/releases)
- [Changelog](https://github.com/pyasn1/pyasn1/blob/main/CHANGES.rst)
- [Commits](https://github.com/pyasn1/pyasn1/compare/v0.6.3...v0.6.4)

---
updated-dependencies:
- dependency-name: pyasn1
  dependency-version: 0.6.4
  dependency-type: indirect
  dependency-group: uv
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-23 18:26:56 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
59a737f669 Chore(deps): Bump the uv group across 1 directory with 8 updates (#13189)
---
updated-dependencies:
- dependency-name: aiohttp
  dependency-version: 3.14.1
  dependency-type: indirect
- dependency-name: cryptography
  dependency-version: 48.0.1
  dependency-type: indirect
- dependency-name: pi-heif
  dependency-version: 1.3.0
  dependency-type: indirect
- dependency-name: pillow
  dependency-version: 12.3.0
  dependency-type: indirect
- dependency-name: pyjwt
  dependency-version: 2.13.0
  dependency-type: indirect
- dependency-name: setuptools
  dependency-version: 83.0.0
  dependency-type: indirect
- dependency-name: torch
  dependency-version: 2.13.0
  dependency-type: direct:production
- dependency-name: tornado
  dependency-version: 6.5.7
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-23 17:58:06 +00:00
Trenton HandGitHub 90bee4285f Fix: exclude the source document from its own RAG similarity results (#13233)
query_similar_documents() never excluded the querying document itself, so a document could appear in its own "similar documents" context, duplicating its content into the AI-suggestions prompt and inflating prompt size/tokens  unnecessarily. Add NE filter support to the vector store and exclude the source document's id at query time.
2026-07-23 10:25:30 -07:00
Trenton HandGitHub 7dca0bfa6a Fix (#13214): split mailrule maximum_age clamp into its own migration (#13231)
Avoids a Postgres error where the clamp UPDATE and the following ALTER TABLE on paperless_mail_mailrule share a transaction, but the table's FKs are deferrable, so pending trigger events block the ALTER. 

Also fixes a verbose_name mismatch in migration 0013.
2026-07-23 17:09:28 +00:00
GitHub Actions 3a34bdc7b0 Auto translate strings 2026-07-23 16:54:02 +00:00
shamoonandGitHub c7899a9a84 Chore: mark yes in confirm button for translation (#13225) 2026-07-23 16:52:04 +00:00
shamoonandGitHub 82fc1c6cee Fix: correct URL for W001 check (#13220) 2026-07-23 16:39:00 +00:00
shamoonandGitHub cd3c162e6e Fix: ensure create dialog uses correct attribute type (#13221) 2026-07-23 16:22:27 +00:00
FabianandGitHub 50c88dab7a Fix: correct database engine from postgres to postgresql in the Porttainer Compose file (#13213) 2026-07-23 07:40:39 -07:00
GitHub Actions 5744a75e6a Auto translate strings 2026-07-23 14:24:56 +00:00
02c6b5f3e4 Fix (beta): remove unnecessary .distinct() dominating document list queries (#13205)
DocumentViewSet.get_queryset() carried a blanket .distinct() left over from
an older query shape (predating the version-file feature and the
correlated-subquery rewrite of num_notes/effective_content). Nothing in the
current base queryset can produce duplicate document rows: select_related
is all FK-to-PK, and the permission filter is a boolean id__in predicate,
not a join. id (the PK) is also always selected and inherently unique, so
.distinct() was a structural no-op for correctness.

It was not a no-op for cost. EXPLAIN showed it forcing a full sort-then-
dedupe over the entire permission-visible document set before LIMIT could
apply -- 340k rows for a 25-row page, with the effective_content/num_notes
correlated subqueries re-executed once per row as a result. This was the
dominant cost behind the original report's document overview slowness,
well beyond the get_user_can_change N+1 fixed separately.

Removing it isn't safe on its own, though -- auditing found two existing
filters that rely on an M2M join *without* deduping themselves, previously
papered over by the blanket .distinct():
- InboxFilter: a document with two tags both flagged is_inbox_tag=True
  (nothing prevents that) would be returned twice for ?is_in_inbox=true.
- CustomFieldsFilter: a document with multiple custom field instances
  matching different OR-ed branches would be returned once per match.

Fixed both locally, matching the pattern ObjectFilter already used for
tags__id__in/custom_fields__id__in. Added regression tests for both --
confirmed they fail without the local .distinct() calls.

Benchmarked against the same 400k-document/1,000-tag corpus: document list
wall-clock for a permission-restricted user drops from ~15.8s to ~2.25s
(~7x), closing most of the previous gap to a superuser's ~1.8s.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 07:22:46 -07:00
shamoon b566232542 Documentation: correct search docs for v3 2026-07-23 06:25:33 -07:00
shamoonandGitHub be40356d2e Fix: also wrap non-breaking words in chat messages, handle whitespace (#13211) 2026-07-22 22:25:19 -07:00
GitHub Actions 5ea8cf2335 Auto translate strings 2026-07-23 04:30:13 +00:00
84a04301d1 Fix: tag/custom-field document_count scales badly with tag count (#13203)
* Fix (beta): tag/custom-field document_count scales badly with tag count

TagViewSet and CustomFieldViewSet's document_count annotation used a
per-row correlated subquery (annotate_document_count_for_related_queryset),
executed once per tag/custom-field row. Fine at a few dozen rows, but at
~1,000 tags it degrades to a full per-tag GroupAggregate over the tags M2M
table -- 6s+ in production reports, confirmed via EXPLAIN (loops=1000).

Replaced with a single, independent GROUP BY over the through table
(permission filter expressed as a plain WHERE, not an aggregate FILTER),
then injected via Case/When. Also tried a more "obvious" fix -- a plain
Count(filter=Q(id__in=permitted_ids), distinct=True) directly on the M2M
relation -- but that's worse: Postgres fails to plan the id__in check as a
semi-join once a large M2M bridge table is involved, and instead re-checks
subquery membership once per joined row.

Benchmarked against a synthetic corpus (400k documents, 1,000 tags @ ~5/doc,
matching real-world reports in discussion #13161): tag list wall-clock drops
from ~180s to ~8s for a permission-restricted user, ~21s to ~8s for a
superuser. No measurable change at typical home-instance scale (tens of
tags).

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>

* Address review feedback: restore validation, scope aggregation to queryset

- Restore the document_count_source_field validation helper dropped during
  the refactor -- misconfiguring a viewset (document_count_through set
  without document_count_source_field) now fails fast with a clear error
  again instead of an obscure runtime failure.
- Restrict annotate_document_count_for_related_queryset()'s through-table
  aggregation to rows whose related_object_field is one of the annotated
  queryset's pks. No-op for the main tag-list call site (queryset is all
  tags), but avoids unnecessary work for narrower callers like the tag
  descendants branch in TagViewSet.list().

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22 21:28:49 -07:00
GitHub Actions 3edda48324 Auto translate strings 2026-07-23 04:04:23 +00:00
f86bc57880 Fix: batch document user_can_change checks to avoid per-row N+1 (#13204)
* Fix (beta): batch document user_can_change checks to avoid per-row N+1

DocumentSerializer.get_user_can_change() built a fresh
ObjectPermissionChecker and issued a guardian permission-table query for
every document row not owned by the requesting user -- correct, but O(N)
per page load for any non-superuser viewing documents owned by others.

BulkPermissionMixin already batches this exact lookup (2 queries total,
regardless of page size) for Correspondent/Tag/DocumentType/CustomField,
but was gated behind the rarely-used `full_perms` flag and DocumentViewSet
didn't inherit it at all. Changed the gate to "any list action" (cheap:
just two extra queries per page) and added BulkPermissionMixin to
DocumentViewSet, then updated get_user_can_change to consult that batched
context before falling back to a fresh guardian check.

Preserves guardian's own superuser shortcut explicitly (has_perm() special-
cases is_superuser without a query; the batched-context path doesn't, so it
needed its own check) -- covered by a new regression test, since no
existing test exercised a superuser viewing an other-owned document.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>

* Fix (beta): don't batch permissions for tantivy search results

UnifiedSearchViewSet.list() returns SearchHit/dict-like objects for
text/title/query/more_like_id search requests, not Document ORM instances.
Adding BulkPermissionMixin to DocumentViewSet (previous commit) meant its
get_serializer_context() ran for search responses too, and its
_get_object_perms() -- which expects real model instances with .pk --
crashed on the dict-like hits with AttributeError, turning every search
request into a 400.

Skip the batching specifically for search requests (existing
_is_search_request() check) by calling past BulkPermissionMixin in the
MRO; non-search list() calls (which return a real Document queryset) are
unaffected and still get the batching.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 04:02:46 +00:00
GitHub Actions 97662b6c5c Auto translate strings 2026-07-23 01:55:12 +00:00
shamoonandGitHub 6e052d5507 Fix: fix app title restoration (#13208) 2026-07-22 18:53:45 -07:00
shamoonandGitHub afb19fe637 Fix: handle long wrapping titles in AI chat document list (#13206) 2026-07-22 16:15:14 -07:00
153 changed files with 3943 additions and 5232 deletions
+1 -1
View File
@@ -86,7 +86,7 @@ jobs:
# ---- Prepare Release ---- # ---- Prepare Release ----
- name: Generate requirements file - name: Generate requirements file
run: | run: |
uv export --quiet --no-dev --all-extras --format requirements-txt --output-file requirements.txt uv export --quiet --no-dev --all-extras --emit-index-url --format requirements-txt --output-file requirements.txt
- name: Compile messages - name: Compile messages
env: env:
PAPERLESS_SECRET_KEY: "ci-release-not-a-real-secret" PAPERLESS_SECRET_KEY: "ci-release-not-a-real-secret"
+1 -1
View File
@@ -56,7 +56,7 @@ services:
environment: environment:
PAPERLESS_REDIS: redis://broker:6379 PAPERLESS_REDIS: redis://broker:6379
PAPERLESS_DBHOST: db PAPERLESS_DBHOST: db
PAPERLESS_DBENGINE: postgres PAPERLESS_DBENGINE: postgresql
env_file: env_file:
- stack.env - stack.env
volumes: volumes:
-15
View File
@@ -272,8 +272,6 @@ optional arguments:
-sm, --split-manifest -sm, --split-manifest
-z, --zip -z, --zip
-zn, --zip-name -zn, --zip-name
--zip-compression
--zip-compression-level
--data-only --data-only
--no-progress-bar --no-progress-bar
--passphrase --passphrase
@@ -336,19 +334,6 @@ If `-z` or `--zip` is provided, the export will be a zip file
in the target directory, named according to the current local date or the in the target directory, named according to the current local date or the
value set in `-zn` or `--zip-name`. value set in `-zn` or `--zip-name`.
The compression method for the zip can be set with `--zip-compression`
(`stored`, `deflated` (default), `bzip2`, `lzma`, or `zstd`) and tuned with
`--zip-compression-level` (deflated: 09, bzip2: 19, zstd: -2222; ignored
for `stored` and `lzma`). Both options require `--zip`.
!!! warning
`zstd` compression requires Python 3.14 or newer on **both** the machine
creating the export and any machine importing it. An archive compressed with
`zstd` (or `lzma`/`bzip2` where those modules are unavailable) cannot be
imported on a runtime that lacks the codec; the importer will refuse it with
a clear error. The default `deflated` is universally readable.
If `--data-only` is provided, only the database will be exported. This option is intended If `--data-only` is provided, only the database will be exported. This option is intended
to facilitate database upgrades without needing to clean documents and thumbnails from the media directory. to facilitate database upgrades without needing to clean documents and thumbnails from the media directory.
+59
View File
@@ -1,5 +1,64 @@
# Changelog # Changelog
## paperless-ngx 3.0.2
### Bug Fixes
- Fix: fix broken migration in 3.0.1 [@shamoon](https://github.com/shamoon) ([#13242](https://github.com/paperless-ngx/paperless-ngx/pull/13242))
### All App Changes
- Fix: fix broken migration in 3.0.1 [@shamoon](https://github.com/shamoon) ([#13242](https://github.com/paperless-ngx/paperless-ngx/pull/13242))
## paperless-ngx 3.0.1
### Bug Fixes
- Fix: selection\_data re-derives the filtered document set 5 times over [@stumpylog](https://github.com/stumpylog) ([#13229](https://github.com/paperless-ngx/paperless-ngx/pull/13229))
- Fix: exclude source document from its own RAG similarity results [@stumpylog](https://github.com/stumpylog) ([#13233](https://github.com/paperless-ngx/paperless-ngx/pull/13233))
- Fix: split mailrule maximum\_age clamp into its own migration [@stumpylog](https://github.com/stumpylog) ([#13231](https://github.com/paperless-ngx/paperless-ngx/pull/13231))
- Chore: mark yes in confirm button for translation [@shamoon](https://github.com/shamoon) ([#13225](https://github.com/paperless-ngx/paperless-ngx/pull/13225))
- Fix: correct URL for W001 check [@shamoon](https://github.com/shamoon) ([#13220](https://github.com/paperless-ngx/paperless-ngx/pull/13220))
- Fix: ensure create dialog uses correct attribute type [@shamoon](https://github.com/shamoon) ([#13221](https://github.com/paperless-ngx/paperless-ngx/pull/13221))
- Fix: correct database engine from postgres to postgresql [@OberstVonGatow](https://github.com/OberstVonGatow) ([#13213](https://github.com/paperless-ngx/paperless-ngx/pull/13213))
- Fix: remove unnecessary .distinct() dominating document list queries [@stumpylog](https://github.com/stumpylog) ([#13205](https://github.com/paperless-ngx/paperless-ngx/pull/13205))
- Fix: also wrap non-breaking words in chat messages, handle whitespace [@shamoon](https://github.com/shamoon) ([#13211](https://github.com/paperless-ngx/paperless-ngx/pull/13211))
- Fix: tag/custom-field document\_count scales badly with tag count [@stumpylog](https://github.com/stumpylog) ([#13203](https://github.com/paperless-ngx/paperless-ngx/pull/13203))
- Fix: batch document user\_can\_change checks to avoid per-row N+1 [@stumpylog](https://github.com/stumpylog) ([#13204](https://github.com/paperless-ngx/paperless-ngx/pull/13204))
- Fix: fix app title restoration [@shamoon](https://github.com/shamoon) ([#13208](https://github.com/paperless-ngx/paperless-ngx/pull/13208))
- Fix: handle long wrapping titles in AI chat document list [@shamoon](https://github.com/shamoon) ([#13206](https://github.com/paperless-ngx/paperless-ngx/pull/13206))
### Dependencies
- Chore(deps-dev): Bump postcss from 8.5.6 to 8.5.22 in /src/paperless\_mail/templates in the npm\_and\_yarn group across 1 directory @[dependabot[bot]](https://github.com/apps/dependabot) ([#13236](https://github.com/paperless-ngx/paperless-ngx/pull/13236))
- Chore(deps): Bump pyasn1 from 0.6.3 to 0.6.4 in the uv group across 1 directory @[dependabot[bot]](https://github.com/apps/dependabot) ([#13237](https://github.com/paperless-ngx/paperless-ngx/pull/13237))
- Chore(deps): Bump the uv group across 1 directory with 8 updates @[dependabot[bot]](https://github.com/apps/dependabot) ([#13189](https://github.com/paperless-ngx/paperless-ngx/pull/13189))
### All App Changes
<details>
<summary>17 changes</summary>
- Chore(deps-dev): Bump postcss from 8.5.6 to 8.5.22 in /src/paperless\_mail/templates in the npm\_and\_yarn group across 1 directory @[dependabot[bot]](https://github.com/apps/dependabot) ([#13236](https://github.com/paperless-ngx/paperless-ngx/pull/13236))
- Fix: selection\_data re-derives the filtered document set 5 times over [@stumpylog](https://github.com/stumpylog) ([#13229](https://github.com/paperless-ngx/paperless-ngx/pull/13229))
- Chore: reword "Settings > Default permissions" description for clarity [@NotaInutilis](https://github.com/NotaInutilis) ([#13232](https://github.com/paperless-ngx/paperless-ngx/pull/13232))
- Chore(deps): Bump pyasn1 from 0.6.3 to 0.6.4 in the uv group across 1 directory @[dependabot[bot]](https://github.com/apps/dependabot) ([#13237](https://github.com/paperless-ngx/paperless-ngx/pull/13237))
- Chore(deps): Bump the uv group across 1 directory with 8 updates @[dependabot[bot]](https://github.com/apps/dependabot) ([#13189](https://github.com/paperless-ngx/paperless-ngx/pull/13189))
- Fix: exclude source document from its own RAG similarity results [@stumpylog](https://github.com/stumpylog) ([#13233](https://github.com/paperless-ngx/paperless-ngx/pull/13233))
- Fix: split mailrule maximum\_age clamp into its own migration [@stumpylog](https://github.com/stumpylog) ([#13231](https://github.com/paperless-ngx/paperless-ngx/pull/13231))
- Chore: mark yes in confirm button for translation [@shamoon](https://github.com/shamoon) ([#13225](https://github.com/paperless-ngx/paperless-ngx/pull/13225))
- Fix: correct URL for W001 check [@shamoon](https://github.com/shamoon) ([#13220](https://github.com/paperless-ngx/paperless-ngx/pull/13220))
- Fix: ensure create dialog uses correct attribute type [@shamoon](https://github.com/shamoon) ([#13221](https://github.com/paperless-ngx/paperless-ngx/pull/13221))
- Fix: correct database engine from postgres to postgresql [@OberstVonGatow](https://github.com/OberstVonGatow) ([#13213](https://github.com/paperless-ngx/paperless-ngx/pull/13213))
- Fix: remove unnecessary .distinct() dominating document list queries [@stumpylog](https://github.com/stumpylog) ([#13205](https://github.com/paperless-ngx/paperless-ngx/pull/13205))
- Fix: also wrap non-breaking words in chat messages, handle whitespace [@shamoon](https://github.com/shamoon) ([#13211](https://github.com/paperless-ngx/paperless-ngx/pull/13211))
- Fix: tag/custom-field document\_count scales badly with tag count [@stumpylog](https://github.com/stumpylog) ([#13203](https://github.com/paperless-ngx/paperless-ngx/pull/13203))
- Fix: batch document user\_can\_change checks to avoid per-row N+1 [@stumpylog](https://github.com/stumpylog) ([#13204](https://github.com/paperless-ngx/paperless-ngx/pull/13204))
- Fix: fix app title restoration [@shamoon](https://github.com/shamoon) ([#13208](https://github.com/paperless-ngx/paperless-ngx/pull/13208))
- Fix: handle long wrapping titles in AI chat document list [@shamoon](https://github.com/shamoon) ([#13206](https://github.com/paperless-ngx/paperless-ngx/pull/13206))
</details>
## paperless-ngx 3.0.0 ## paperless-ngx 3.0.0
### Breaking Changes ### Breaking Changes
+21 -7
View File
@@ -522,22 +522,36 @@ do CORS calls. Set this to your public domain name.
fail2ban with log entries for failed authorization attempts. Value should be fail2ban with log entries for failed authorization attempts. Value should be
IP address(es). IP address(es).
This setting also controls allauth's By default, this setting also controls allauth's trusted proxy count,
[`ALLAUTH_TRUSTED_PROXY_COUNT`](https://docs.allauth.org/en/latest/account/configuration.html), which is set to the number of proxies listed here. Override that default
which is set to the number of proxies listed here. Without this, with [`PAPERLESS_ALLAUTH_TRUSTED_PROXY_COUNT`](#PAPERLESS_ALLAUTH_TRUSTED_PROXY_COUNT)
allauth cannot determine the client IP address for rate limiting when when the list length does not match the number of proxy hops.
running behind a reverse proxy, resulting in a `403 Forbidden` on login.
Defaults to empty string. Defaults to empty string.
#### [`PAPERLESS_ALLAUTH_TRUSTED_PROXY_COUNT=<integer>`](#PAPERLESS_ALLAUTH_TRUSTED_PROXY_COUNT) {#PAPERLESS_ALLAUTH_TRUSTED_PROXY_COUNT}
: Sets allauth's
[`ALLAUTH_TRUSTED_PROXY_COUNT`](https://docs.allauth.org/en/latest/common/rate_limits.html#configuration).
This is the number of trusted proxy **hops** represented in each
`X-Forwarded-For` header, not the number of IP addresses through which those
proxies may be reached. For example, a single dual-stack proxy is one hop even
when its IPv4 and IPv6 addresses are both listed in
[`PAPERLESS_TRUSTED_PROXIES`](#PAPERLESS_TRUSTED_PROXIES).
Only trust `X-Forwarded-For` when untrusted clients cannot connect directly
to Paperless-ngx.
Defaults to the number of entries in `PAPERLESS_TRUSTED_PROXIES`.
#### [`PAPERLESS_ALLAUTH_TRUSTED_CLIENT_IP_HEADER=<header-name>`](#PAPERLESS_ALLAUTH_TRUSTED_CLIENT_IP_HEADER) {#PAPERLESS_ALLAUTH_TRUSTED_CLIENT_IP_HEADER} #### [`PAPERLESS_ALLAUTH_TRUSTED_CLIENT_IP_HEADER=<header-name>`](#PAPERLESS_ALLAUTH_TRUSTED_CLIENT_IP_HEADER) {#PAPERLESS_ALLAUTH_TRUSTED_CLIENT_IP_HEADER}
: Sets allauth's : Sets allauth's
[`ALLAUTH_TRUSTED_CLIENT_IP_HEADER`](https://docs.allauth.org/en/latest/account/configuration.html). [`ALLAUTH_TRUSTED_CLIENT_IP_HEADER`](https://docs.allauth.org/en/latest/common/rate_limits.html#configuration).
Use this when your reverse proxy sets a dedicated header for the real Use this when your reverse proxy sets a dedicated header for the real
client IP instead of `X-Forwarded-For`, for example `X-Real-IP` (nginx) client IP instead of `X-Forwarded-For`, for example `X-Real-IP` (nginx)
or `CF-Connecting-IP` (Cloudflare). When set, this takes precedence over or `CF-Connecting-IP` (Cloudflare). When set, this takes precedence over
[`PAPERLESS_TRUSTED_PROXIES`](#PAPERLESS_TRUSTED_PROXIES). `PAPERLESS_ALLAUTH_TRUSTED_PROXY_COUNT`.
Defaults to none. Defaults to none.
+65 -4
View File
@@ -133,7 +133,7 @@ PAPERLESS_DB_OPTIONS="sslmode=require,sslrootcert=/certs/ca.pem,pool.max_size=10
## OCR and Archive File Generation Settings ## OCR and Archive File Generation Settings
The settings that control OCR behaviour and archive file generation have been redesigned. The old settings that coupled these two concerns together are **removed** old values are not silently honoured; a startup warning is logged if any removed variable is still set in your environment. The settings that control OCR behaviour and archive file generation have been redesigned. The old settings that coupled these two concerns together are **removed** - old values are not silently honoured; a startup warning is logged if any removed variable is still set in your environment.
### Removed settings ### Removed settings
@@ -166,7 +166,7 @@ Remove any `PAPERLESS_OCR_SKIP_ARCHIVE_FILE` variable from your environment. If
# v2: skip OCR when text present, always archive # v2: skip OCR when text present, always archive
PAPERLESS_OCR_MODE=skip PAPERLESS_OCR_MODE=skip
# v3: equivalent (auto is the new default) # v3: equivalent (auto is the new default)
# No change needed auto is the default # No change needed - auto is the default
# v2: skip OCR when text present, skip archive too # v2: skip OCR when text present, skip archive too
PAPERLESS_OCR_MODE=skip_noarchive PAPERLESS_OCR_MODE=skip_noarchive
@@ -189,7 +189,7 @@ PAPERLESS_ARCHIVE_FILE_GENERATION=auto
If you use the **remote OCR parser** (Azure AI), note that it always produces a If you use the **remote OCR parser** (Azure AI), note that it always produces a
searchable PDF and stores it as the archive copy. `ARCHIVE_FILE_GENERATION=never` searchable PDF and stores it as the archive copy. `ARCHIVE_FILE_GENERATION=never`
has no effect for documents handled by the remote parser the archive is produced has no effect for documents handled by the remote parser - the archive is produced
unconditionally by the remote engine. unconditionally by the remote engine.
## Search Index (Whoosh -> Tantivy) ## Search Index (Whoosh -> Tantivy)
@@ -324,8 +324,69 @@ option since v1.8.0.
Allauth changed how it determines the client IP address for login rate limiting. Users running Allauth changed how it determines the client IP address for login rate limiting. Users running
behind a reverse proxy may need to set behind a reverse proxy may need to set
[`PAPERLESS_TRUSTED_PROXIES`](configuration.md#PAPERLESS_TRUSTED_PROXIES), [`PAPERLESS_TRUSTED_PROXIES`](configuration.md#PAPERLESS_TRUSTED_PROXIES),
[`PAPERLESS_ALLAUTH_TRUSTED_PROXY_COUNT`](configuration.md#PAPERLESS_ALLAUTH_TRUSTED_PROXY_COUNT),
[`PAPERLESS_ALLAUTH_TRUSTED_CLIENT_IP_HEADER`](configuration.md#PAPERLESS_ALLAUTH_TRUSTED_CLIENT_IP_HEADER), [`PAPERLESS_ALLAUTH_TRUSTED_CLIENT_IP_HEADER`](configuration.md#PAPERLESS_ALLAUTH_TRUSTED_CLIENT_IP_HEADER),
or both, to avoid `403 Forbidden` errors on login. or a combination of these settings to avoid `403 Forbidden` errors on login.
The proxy count is the number of proxy hops in `X-Forwarded-For`, which may
differ from the number of configured proxy IP addresses.
## Minimum CPU Requirements (NumPy Baseline)
Starting with NumPy 2.4.0, official `manylinux` x86_64 wheels are compiled with a minimum
CPU baseline of `x86-64-v2`, which requires SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, and
CMPXCHG16B. This is a [deliberate upstream change](https://github.com/numpy/numpy/issues/27851)
citing that these instructions have been present in over 99.7% of CPUs since 2008
([Intel](<https://en.wikipedia.org/wiki/Nehalem_(microarchitecture)>)) or 2011
([AMD](<https://en.wikipedia.org/wiki/Bulldozer_(microarchitecture)>)).
NumPy is a dependency of the document classifier (via scikit-learn), so any CPU that
predates SSE4.2 support will crash with `SIGILL` (illegal instruction) when the classifier
is loaded or trained, regardless of whether AI features are enabled.
This differs from NumPy's optional SIMD dispatch (e.g. AVX2, AVX512), which is detected and
selected safely at runtime - the `x86-64-v2` requirement above is a hard floor baked into the
wheel, with no runtime fallback.
### Affected hardware
CPUs older than roughly 2008 (Intel) or 2011 (AMD) that lack SSE4.2 support. This is more
likely to affect low-power or embedded hardware - e.g. early Atom, Celeron, or pre-Bulldozer
AMD chips - than typical desktop or server hardware from the last decade.
Check for SSE4.2 support with:
```bash
grep -o -m1 sse4_2 /proc/cpuinfo
```
If this prints nothing, your CPU is affected.
### Symptoms
The Celery worker (and potentially the web server) repeatedly crashes and restarts with a
`SIGILL` error, typically visible in `dmesg`/`journalctl` as a `trap invalid opcode` inside
`_multiarray_umath...so`. Because the classifier is trained on a periodic schedule
(hourly, by default), affected instances see intermittent, hard-to-reproduce document
consumption failures whenever that scheduled task runs and takes down the worker process
mid-task.
### Action Required (for affected hardware only)
There is no way to make the classifier itself work on such CPUs - it requires an unofficial
NumPy build with `cpu-baseline=none`, which is not something we can ship. The practical
path forward is to stop the classifier from ever loading or training, which avoids
importing NumPy at all:
```bash
PAPERLESS_TRAIN_TASK_CRON=disable
```
This disables the periodic classifier training task (see
[`PAPERLESS_TRAIN_TASK_CRON`](configuration.md#PAPERLESS_TRAIN_TASK_CRON)). Automatic
matching based on the classifier (suggested correspondents, document types, tags, and
storage paths from trained rules) will no longer be available, but rule-based matching is
unaffected, and document consumption itself will no longer be at risk of crashing the
worker.
## Database Migrations ## Database Migrations
@@ -1,839 +0,0 @@
# Export Zip Compression Control Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Add `--zip-compression {stored,deflated,bzip2,lzma,zstd}` and `--zip-compression-level N` flags to `document_exporter`, threaded into `ZipExportSink`, with import-side safety for codecs the running Python can't read.
**Architecture:** A new pure-data module `documents/export/compression.py` owns the method↔constant map, per-method level bounds, the runtime availability probe, and a compress-type readability check. `ZipExportSink` gains `compression`/`compresslevel` constructor params. The command validates flags up front (fail-fast `CommandError`) and constructs the sink; the importer pre-checks entry compress types before extracting.
**Tech Stack:** Python ≥3.11 (zstd only on 3.14+), `zipfile`, `compression.zstd` (PEP 784), pytest + pytest-mock + factory-boy. Backend tests run on the Linux VM (Python 3.11 — zstd positive tests are `skipif`-guarded); `ruff` runs locally.
**Spec:** `docs/superpowers/specs/2026-06-16-export-zip-compression-design.md`
**PREREQUISITE:** The base refactor `docs/superpowers/plans/2026-06-16-export-sink-architecture.md` MUST be merged first. This plan assumes `src/documents/export/sinks.py` exists with `ZipExportSink(target, zip_name, *, delete=False)` opening its `ZipFile` in `_open()`.
---
## Verified facts (CPython 3.14.3, via `uv run --python 3.14 --no-project`)
- Constants: `ZIP_STORED=0`, `ZIP_DEFLATED=8`, `ZIP_BZIP2=12`, `ZIP_LZMA=14`, `ZIP_ZSTANDARD=93` (zstd added 3.14; absent on < 3.14).
- `ZipFile(file, "w", compression=…, compresslevel=…)` applies both as the default for every `write`/`writestr` — no per-entry args needed (verified).
- Level bounds: `deflated` 09, `bzip2` 19, `lzma`/`stored` ignore level, `zstd` -131072…22 (`compression.zstd.CompressionParameter.compression_level.bounds() == (-131072, 22)`).
- An invalid level fails at the **first write** (`ValueError: Invalid initialization option` / `compresslevel must be between 1 and 9`), plus GC-time `AttributeError` noise on close — hence up-front validation.
- zstd is backed by `compression.zstd`; `zipfile` raises `RuntimeError` if it's unavailable.
## Conventions for every task
- **Run backend tests on the VM:** `bash /c/Users/tholmes/Documents/Coding/paperless/vmtest.sh "<targets>"` (never locally).
- **Lint locally:** `ruff check <paths> && ruff format <paths>` (global ruff, not `uv run`).
- **Tests are pytest-style:** classes, `@pytest.mark.django_db` on the class only where DB is needed (the `compression.py` and sink tests need no DB), factory-boy, `mocker`, `parametrize`, full type annotations.
- The VM runs Python 3.11, so **zstd positive tests must be `@pytest.mark.skipif(...)`-guarded**; they will simply not run there. zstd _rejection_ tests (the < 3.14 path) DO run on the VM.
## File structure
- **Create** `src/documents/export/compression.py` — method map, CLI choices, level bounds, `compression_available()`, `level_error()`, `compress_type_readable()`, `unreadable_method_names()`. Pure, no Django.
- **Create** `src/documents/tests/export/test_compression.py` — unit tests for the above.
- **Modify** `src/documents/export/sinks.py``ZipExportSink.__init__` gains `compression`/`compresslevel`; `_open()` passes them to `ZipFile`.
- **Modify** `src/documents/tests/export/test_sinks.py` — assert the chosen `compress_type` is applied.
- **Modify** `src/documents/management/commands/document_exporter.py` — add the two CLI flags, up-front validation, and pass resolved values to `ZipExportSink`.
- **Modify** `src/documents/tests/test_management_exporter.py` — flag validation + default-unchanged tests.
- **Modify** `src/documents/management/commands/document_importer.py` — pre-extract compress-type check.
- **Modify** `src/documents/tests/test_management_importer.py` — unsupported-codec → `CommandError`.
- **Modify** `docs/administration.md` — document both flags + zstd portability caveat.
---
## Task 1: `documents/export/compression.py` (pure compression policy)
**Files:**
- Create: `src/documents/export/compression.py`
- Test: `src/documents/tests/export/test_compression.py`
- [ ] **Step 1: Write the failing tests**
Create `src/documents/tests/export/test_compression.py`:
```python
import sys
import zipfile
import pytest
from documents.export import compression
class TestCompressionMethods:
def test_choices_always_include_zstd(self) -> None:
# zstd is offered regardless of runtime; availability is checked separately
assert compression.COMPRESSION_CHOICES == (
"stored",
"deflated",
"bzip2",
"lzma",
"zstd",
)
@pytest.mark.parametrize(
("name", "constant"),
[
("stored", zipfile.ZIP_STORED),
("deflated", zipfile.ZIP_DEFLATED),
("bzip2", zipfile.ZIP_BZIP2),
("lzma", zipfile.ZIP_LZMA),
],
)
def test_method_maps_to_zipfile_constant(self, name: str, constant: int) -> None:
assert compression.COMPRESSION_METHODS[name] == constant
def test_stored_and_deflated_always_available(self) -> None:
assert compression.compression_available("stored")
assert compression.compression_available("deflated")
def test_zstd_availability_tracks_runtime(self) -> None:
expected: bool = sys.version_info >= (3, 14)
assert compression.compression_available("zstd") == expected
class TestLevelError:
@pytest.mark.parametrize(
("method", "level"),
[
("deflated", 0),
("deflated", 9),
("bzip2", 1),
("bzip2", 9),
("deflated", None),
("stored", None),
],
)
def test_valid_levels_return_none(self, method: str, level: int | None) -> None:
assert compression.level_error(method, level) is None
@pytest.mark.parametrize(
("method", "level"),
[
("deflated", 10),
("deflated", -1),
("bzip2", 0),
("bzip2", 10),
],
)
def test_out_of_range_levels_return_message(
self,
method: str,
level: int,
) -> None:
msg: str | None = compression.level_error(method, level)
assert msg is not None
assert "between" in msg
@pytest.mark.parametrize("method", ["stored", "lzma"])
def test_level_on_levelless_method_is_rejected(self, method: str) -> None:
msg: str | None = compression.level_error(method, 5)
assert msg is not None
assert "no effect" in msg
class TestCompressTypeReadable:
@pytest.mark.parametrize("ct", [zipfile.ZIP_STORED, zipfile.ZIP_DEFLATED])
def test_stored_and_deflated_always_readable(self, ct: int) -> None:
assert compression.compress_type_readable(ct)
def test_zstd_compress_type_readability_tracks_runtime(self) -> None:
# 93 = ZIP_ZSTANDARD; 20 = legacy zstd method id (read-only)
expected: bool = sys.version_info >= (3, 14)
assert compression.compress_type_readable(93) == expected
assert compression.compress_type_readable(20) == expected
def test_unknown_compress_type_is_unreadable(self) -> None:
assert not compression.compress_type_readable(9999)
def test_unreadable_method_names_lists_methods(self) -> None:
# An unknown method id maps to no name and is reported generically.
names: set[str] = compression.unreadable_method_names({9999})
assert names == {"method 9999"}
```
- [ ] **Step 2: Run to verify it fails**
Run: `bash /c/Users/tholmes/Documents/Coding/paperless/vmtest.sh "src/documents/tests/export/test_compression.py -v"`
Expected: FAIL with `ModuleNotFoundError: No module named 'documents.export.compression'`.
- [ ] **Step 3: Implement `compression.py`**
Create `src/documents/export/compression.py`:
```python
from __future__ import annotations
import importlib
import zipfile
# ZIP_ZSTANDARD exists only on Python 3.14+ (PEP 784). None elsewhere.
ZSTD: int | None = getattr(zipfile, "ZIP_ZSTANDARD", None)
# CLI choices are fixed across runtimes so argparse never hides zstd; runtime
# availability is enforced separately in compression_available().
COMPRESSION_CHOICES: tuple[str, ...] = (
"stored",
"deflated",
"bzip2",
"lzma",
"zstd",
)
# Method name -> zipfile compression constant (zstd only when supported).
COMPRESSION_METHODS: dict[str, int] = {
"stored": zipfile.ZIP_STORED,
"deflated": zipfile.ZIP_DEFLATED,
"bzip2": zipfile.ZIP_BZIP2,
"lzma": zipfile.ZIP_LZMA,
}
if ZSTD is not None:
COMPRESSION_METHODS["zstd"] = ZSTD
# Inclusive (min, max) level bounds per method; None => level not applicable.
# Verified on CPython 3.14.3.
LEVEL_BOUNDS: dict[str, tuple[int, int] | None] = {
"stored": None,
"deflated": (0, 9),
"bzip2": (1, 9),
"lzma": None,
"zstd": (-131072, 22),
}
# zipfile compress_type id -> method name. 93 = current zstd id, 20 = legacy
# zstd id that zipfile can still read.
_COMPRESS_TYPE_TO_METHOD: dict[int, str] = {
zipfile.ZIP_STORED: "stored",
zipfile.ZIP_DEFLATED: "deflated",
zipfile.ZIP_BZIP2: "bzip2",
zipfile.ZIP_LZMA: "lzma",
93: "zstd",
20: "zstd",
}
def compression_available(method: str) -> bool:
"""Whether the running interpreter can actually use the given method."""
if method in ("stored", "deflated"):
# zlib is a hard CPython dependency; stored needs nothing.
return True
if method == "bzip2":
return _module_importable("bz2")
if method == "lzma":
return _module_importable("lzma")
if method == "zstd":
return ZSTD is not None and _module_importable("compression.zstd")
return False
def _module_importable(name: str) -> bool:
try:
importlib.import_module(name)
except ImportError:
return False
return True
def level_error(method: str, level: int | None) -> str | None:
"""Return a human message if (method, level) is invalid, else None."""
if level is None:
return None
bounds = LEVEL_BOUNDS[method]
if bounds is None:
return f"--zip-compression-level has no effect for '{method}'"
low, high = bounds
if not (low <= level <= high):
return (
f"--zip-compression-level for '{method}' must be between "
f"{low} and {high}"
)
return None
def compress_type_readable(compress_type: int) -> bool:
"""Whether this interpreter can decompress an entry of the given type."""
method = _COMPRESS_TYPE_TO_METHOD.get(compress_type)
if method is None:
return False
return compression_available(method)
def unreadable_method_names(compress_types: set[int]) -> set[str]:
"""Map a set of compress_type ids to human method names for error messages."""
names: set[str] = set()
for ct in compress_types:
names.add(_COMPRESS_TYPE_TO_METHOD.get(ct, f"method {ct}"))
return names
```
- [ ] **Step 4: Run to verify it passes**
Run: `bash /c/Users/tholmes/Documents/Coding/paperless/vmtest.sh "src/documents/tests/export/test_compression.py -v"`
Expected: PASS (on the 3.11 VM, `test_zstd_availability_tracks_runtime` and `test_zstd_compress_type_readability_tracks_runtime` assert `False`).
- [ ] **Step 5: Lint**
Run: `ruff check src/documents/export/compression.py src/documents/tests/export/test_compression.py && ruff format src/documents/export/compression.py src/documents/tests/export/test_compression.py`
Expected: no errors.
- [ ] **Step 6: Commit**
```bash
git add src/documents/export/compression.py src/documents/tests/export/test_compression.py
git commit -m "Feature: add export compression policy module"
```
---
## Task 2: `ZipExportSink` accepts compression method + level
**Files:**
- Modify: `src/documents/export/sinks.py`
- Test: `src/documents/tests/export/test_sinks.py`
- [ ] **Step 1: Write the failing test**
Append to `src/documents/tests/export/test_sinks.py` (the top-of-file block already imports `zipfile`, `Path`, `pytest`, `ZipExportSink`, `StreamingManifestWriter` from the base-refactor plan):
```python
class TestZipExportSinkCompression:
@pytest.fixture()
def source_file(self, tmp_path: Path) -> Path:
src: Path = tmp_path / "src" / "doc.pdf"
src.parent.mkdir(parents=True)
src.write_bytes(b"PDF-CONTENT" * 100)
return src
@pytest.mark.parametrize(
("method", "constant"),
[
("stored", zipfile.ZIP_STORED),
("deflated", zipfile.ZIP_DEFLATED),
("bzip2", zipfile.ZIP_BZIP2),
("lzma", zipfile.ZIP_LZMA),
],
)
def test_compression_method_is_applied_to_file_entries(
self,
tmp_path: Path,
source_file: Path,
method: str,
constant: int,
) -> None:
target: Path = tmp_path / "out"
target.mkdir()
with ZipExportSink(
target,
"export",
delete=False,
compression=constant,
) as sink:
sink.add_file(source_file, "doc.pdf")
with zipfile.ZipFile(target / "export.zip") as zf:
info = zf.getinfo("doc.pdf")
assert info.compress_type == constant
def test_compressing_method_beats_stored(
self,
tmp_path: Path,
source_file: Path,
) -> None:
# Robust size invariant: a compressing method must be <= stored on
# compressible content (avoids flaky level-9-vs-level-1 comparisons).
sizes: dict[str, int] = {}
for name, constant in (("stored", zipfile.ZIP_STORED), ("deflated", zipfile.ZIP_DEFLATED)):
target: Path = tmp_path / name
target.mkdir()
with ZipExportSink(target, "export", delete=False, compression=constant) as sink:
sink.add_file(source_file, "doc.pdf")
sizes[name] = (target / "export.zip").stat().st_size
assert sizes["deflated"] <= sizes["stored"]
```
- [ ] **Step 2: Run to verify it fails**
Run: `bash /c/Users/tholmes/Documents/Coding/paperless/vmtest.sh "src/documents/tests/export/test_sinks.py::TestZipExportSinkCompression -v"`
Expected: FAIL with `TypeError: __init__() got an unexpected keyword argument 'compression'`.
- [ ] **Step 3: Add the params to `ZipExportSink`**
In `src/documents/export/sinks.py`, change `ZipExportSink.__init__` to accept the new keyword-only params and store them, and pass them in `_open()`:
```python
def __init__(
self,
target: Path,
zip_name: str,
*,
delete: bool = False,
compression: int = zipfile.ZIP_DEFLATED,
compresslevel: int | None = None,
) -> None:
self._target = target.resolve()
self._zip_path = (self._target / zip_name).with_suffix(".zip")
self._tmp_path = self._zip_path.with_name(self._zip_path.name + ".tmp")
self._delete = delete
self._compression = compression
self._compresslevel = compresslevel
self._zip: zipfile.ZipFile | None = None
self._dirs: set[str] = set()
self._pending_manifest: tuple[Path, str] | None = None
self._stream_open = False
```
And in `_open()`:
```python
def _open(self) -> None:
settings.SCRATCH_DIR.mkdir(parents=True, exist_ok=True)
self._zip = zipfile.ZipFile(
self._tmp_path,
"w",
compression=self._compression,
compresslevel=self._compresslevel,
allowZip64=True,
)
```
- [ ] **Step 4: Run to verify it passes**
Run: `bash /c/Users/tholmes/Documents/Coding/paperless/vmtest.sh "src/documents/tests/export/test_sinks.py -v"`
Expected: PASS (all sink tests, including the four method params and the size invariant). `bzip2`/`lzma` are present on the VM's CPython, so those params pass.
- [ ] **Step 5: Lint**
Run: `ruff check src/documents/export/sinks.py && ruff format src/documents/export/sinks.py`
Expected: no errors.
- [ ] **Step 6: Commit**
```bash
git add src/documents/export/sinks.py src/documents/tests/export/test_sinks.py
git commit -m "Feature: ZipExportSink accepts compression method and level"
```
---
## Task 3: Wire CLI flags + validation into `document_exporter`
**Files:**
- Modify: `src/documents/management/commands/document_exporter.py`
- Test: `src/documents/tests/test_management_exporter.py`
- [ ] **Step 1: Add the argparse flags**
In `document_exporter.py`, add the import near the other `documents.export` import:
```python
from documents.export.compression import COMPRESSION_CHOICES
from documents.export.compression import COMPRESSION_METHODS
from documents.export.compression import compression_available
from documents.export.compression import level_error
from documents.export.compression import ZSTD
```
In `add_arguments`, after the `--zip-name` argument, add:
```python
parser.add_argument(
"--zip-compression",
choices=COMPRESSION_CHOICES,
default=None,
help=(
"Compression method for the export zip (requires --zip). "
"Default: deflated. 'zstd' requires Python 3.14+ on both the "
"exporting and importing machine."
),
)
parser.add_argument(
"--zip-compression-level",
type=int,
default=None,
help=(
"Compression level for the export zip (requires --zip). "
"deflated: 0-9, bzip2: 1-9, zstd: -131072..22; ignored for "
"stored/lzma."
),
)
```
- [ ] **Step 2: Read + validate the flags in `handle()`**
In `handle()`, after the existing `--compare-*` + `--zip` guard, add the compression flag handling. Insert before the sink construction:
```python
zip_compression: str | None = options["zip_compression"]
zip_compression_level: int | None = options["zip_compression_level"]
if not self.zip_export and (
zip_compression is not None or zip_compression_level is not None
):
raise CommandError(
"--zip-compression and --zip-compression-level require --zip",
)
compression_method = zip_compression or "deflated"
if self.zip_export:
if not compression_available(compression_method):
if compression_method == "zstd" and ZSTD is None:
raise CommandError(
"zstd compression requires Python 3.14 or newer",
)
raise CommandError(
f"Compression method '{compression_method}' is not "
f"available on this Python runtime",
)
level_msg = level_error(compression_method, zip_compression_level)
if level_msg is not None:
raise CommandError(level_msg)
```
- [ ] **Step 3: Pass the resolved values into `ZipExportSink`**
Change the `ZipExportSink(...)` construction in `handle()` to:
```python
if self.zip_export:
sink = ZipExportSink(
self.target,
options["zip_name"],
delete=self.delete,
compression=COMPRESSION_METHODS[compression_method],
compresslevel=zip_compression_level,
)
else:
sink = DirectoryExportSink(
self.target,
compare_checksums=self.compare_checksums,
compare_json=self.compare_json,
delete=self.delete,
)
```
- [ ] **Step 4: Write the command-level tests**
Add to the `TestExportImport` class in `src/documents/tests/test_management_exporter.py` (imports `call_command`, `CommandError`, `ZipFile`, `timezone` already present):
```python
def test_compression_flags_require_zip(self) -> None:
for args in (
["--zip-compression", "lzma"],
["--zip-compression-level", "5"],
):
with self.assertRaises(CommandError):
call_command(
"document_exporter",
self.target,
*args,
skip_checks=True,
)
def test_zip_compression_level_out_of_range_raises(self) -> None:
with self.assertRaises(CommandError):
call_command(
"document_exporter",
self.target,
"--zip",
"--zip-compression",
"deflated",
"--zip-compression-level",
"99",
skip_checks=True,
)
def test_zip_compression_level_rejected_for_stored(self) -> None:
with self.assertRaises(CommandError):
call_command(
"document_exporter",
self.target,
"--zip",
"--zip-compression",
"stored",
"--zip-compression-level",
"5",
skip_checks=True,
)
def test_zip_lzma_compression_round_trips(self) -> None:
call_command(
"document_exporter",
self.target,
"--zip",
"--zip-compression",
"lzma",
skip_checks=True,
)
expected = str(
self.target / f"export-{timezone.localdate().isoformat()}.zip",
)
self.assertIsFile(expected)
with ZipFile(expected) as zip_file:
info = zip_file.getinfo("manifest.json")
# manifest.json carries the chosen method; deflated is the default
self.assertEqual(info.compress_type, 14) # ZIP_LZMA
def test_default_zip_uses_deflate(self) -> None:
call_command(
"document_exporter",
self.target,
"--zip",
skip_checks=True,
)
expected = str(
self.target / f"export-{timezone.localdate().isoformat()}.zip",
)
with ZipFile(expected) as zip_file:
info = zip_file.getinfo("manifest.json")
self.assertEqual(info.compress_type, 8) # ZIP_DEFLATED
```
- [ ] **Step 5: Run the tests**
Run: `bash /c/Users/tholmes/Documents/Coding/paperless/vmtest.sh "src/documents/tests/test_management_exporter.py -v"`
Expected: PASS — the new tests plus all existing exporter tests stay green.
- [ ] **Step 6: Lint**
Run: `ruff check src/documents/management/commands/document_exporter.py src/documents/tests/test_management_exporter.py && ruff format src/documents/management/commands/document_exporter.py src/documents/tests/test_management_exporter.py`
Expected: no errors.
- [ ] **Step 7: Commit**
```bash
git add src/documents/management/commands/document_exporter.py src/documents/tests/test_management_exporter.py
git commit -m "Feature: add --zip-compression and --zip-compression-level flags"
```
---
## Task 4: Importer pre-check for unreadable codecs
**Files:**
- Modify: `src/documents/management/commands/document_importer.py`
- Test: `src/documents/tests/test_management_importer.py`
- [ ] **Step 1: Write the failing test**
The importer test file `src/documents/tests/test_management_importer.py` is
`TestCase`-style (`class TestCommandImport(... TestCase)`, `self.assertRaises`,
`DirectoriesMixin` gives `self.dirs.scratch_dir`). Match that style. Add this
method to `TestCommandImport`. It builds a valid zip and patches the readability
probe so the check fires deterministically on any runtime:
```python
def test_import_rejects_unreadable_compression(self) -> None:
"""
GIVEN:
- A zip archive with an entry whose compression this Python can't read
WHEN:
- Import is attempted
THEN:
- A CommandError naming the issue is raised, before extraction
"""
import zipfile
from unittest import mock
archive = Path(self.dirs.scratch_dir) / "export.zip"
with zipfile.ZipFile(archive, "w") as zf:
zf.writestr("manifest.json", "[]")
with mock.patch(
"documents.management.commands.document_importer.compress_type_readable",
return_value=False,
):
with self.assertRaises(CommandError) as e:
call_command(
"document_importer",
str(archive),
"--no-progress-bar",
skip_checks=True,
)
self.assertIn("compression", str(e.exception))
```
- [ ] **Step 2: Run to verify it fails**
Run: `bash /c/Users/tholmes/Documents/Coding/paperless/vmtest.sh "src/documents/tests/test_management_importer.py -k unreadable_compression -v"`
Expected: FAIL — no pre-check exists yet, so the import proceeds (or fails with a different error).
- [ ] **Step 3: Implement the pre-check**
In `document_importer.py`, add the import:
```python
from documents.export.compression import compress_type_readable
from documents.export.compression import unreadable_method_names
```
Find the zip-handling block (around `document_importer.py:453`):
```python
with ZipFile(self.source) as zf:
zf.extractall(tmp_dir)
```
Replace it with a pre-check before extraction:
```python
with ZipFile(self.source) as zf:
unsupported = {
info.compress_type
for info in zf.infolist()
if not compress_type_readable(info.compress_type)
}
if unsupported:
names = ", ".join(sorted(unreadable_method_names(unsupported)))
raise CommandError(
f"This archive uses compression this Python cannot "
f"read ({names}). zstd archives require Python 3.14+.",
)
zf.extractall(tmp_dir)
```
Confirm `CommandError` is imported in `document_importer.py` (it is used elsewhere; if not, add `from django.core.management.base import CommandError`).
- [ ] **Step 4: Run to verify it passes**
Run: `bash /c/Users/tholmes/Documents/Coding/paperless/vmtest.sh "src/documents/tests/test_management_importer.py -v"`
Expected: PASS — the new test plus all existing importer tests (normal deflated/stored archives still import).
- [ ] **Step 5: Lint**
Run: `ruff check src/documents/management/commands/document_importer.py src/documents/tests/test_management_importer.py && ruff format src/documents/management/commands/document_importer.py src/documents/tests/test_management_importer.py`
Expected: no errors.
- [ ] **Step 6: Commit**
```bash
git add src/documents/management/commands/document_importer.py src/documents/tests/test_management_importer.py
git commit -m "Feature: importer rejects archives with unreadable compression"
```
---
## Task 5: Document the flags
**Files:**
- Modify: `docs/administration.md`
- [ ] **Step 1: Add the flags to the option list**
In `docs/administration.md`, update the usage block (around line 257) to include the new flags:
```
document_exporter target [-c] [-d] [-f] [-na] [-nt] [-p] [-sm] [-z]
optional arguments:
-c, --compare-checksums
-cj, --compare-json
-d, --delete
-f, --use-filename-format
-na, --no-archive
-nt, --no-thumbnail
-p, --use-folder-prefix
-sm, --split-manifest
-z, --zip
-zn, --zip-name
--zip-compression
--zip-compression-level
--data-only
--no-progress-bar
--passphrase
```
- [ ] **Step 2: Add the prose**
After the `-z`/`--zip` paragraph (around line 330), add:
```markdown
The compression method for the zip can be set with `--zip-compression`
(`stored`, `deflated` (default), `bzip2`, `lzma`, or `zstd`) and tuned with
`--zip-compression-level` (deflated: 09, bzip2: 19, zstd: -13107222; ignored
for `stored` and `lzma`). Both options require `--zip`.
!!! warning
`zstd` compression requires Python 3.14 or newer on **both** the machine
creating the export and any machine importing it. An archive compressed with
`zstd` (or `lzma`/`bzip2` where those modules are unavailable) cannot be
imported on a runtime that lacks the codec; the importer will refuse it with
a clear error. The default `deflated` is universally readable.
```
- [ ] **Step 3: Verify the docs build is not broken (lint markdown)**
Run: `ruff check docs/ 2>/dev/null; echo "docs are markdown; rely on prettier pre-commit"`
(No code to test. The prettier pre-commit hook will reformat on commit.)
- [ ] **Step 4: Commit**
```bash
git add docs/administration.md
git commit -m "Docs: document --zip-compression and --zip-compression-level"
```
---
## Task 6: Final verification
**Files:** none (verification only).
- [ ] **Step 1: Full backend suites on the VM**
Run: `bash /c/Users/tholmes/Documents/Coding/paperless/vmtest.sh "src/documents/tests/export/ src/documents/tests/test_management_exporter.py src/documents/tests/test_management_importer.py -v"`
Expected: PASS, no failures.
- [ ] **Step 2: Spot-check the zstd happy path on Python 3.14 (cannot run under Django on the 3.11 VM)**
The zstd positive round-trip can't run in the 3.11 test env. Confirm the policy module behaves on a real 3.14 interpreter with a standalone check (no Django needed):
Run:
```bash
uv run --python 3.14 --no-project python -c "import sys; sys.path.insert(0,'src'); import django; print('skip')" 2>/dev/null || \
uv run --python 3.14 --no-project python -c "
import zipfile, io
from compression.zstd import CompressionParameter as CP
print('zstd const', zipfile.ZIP_ZSTANDARD, 'bounds', CP.compression_level.bounds())
buf = io.BytesIO()
with zipfile.ZipFile(buf,'w',compression=zipfile.ZIP_ZSTANDARD,compresslevel=19) as zf:
zf.writestr('a.txt','x'*1000)
with zipfile.ZipFile(buf) as zf:
assert zf.getinfo('a.txt').compress_type == zipfile.ZIP_ZSTANDARD
assert zf.read('a.txt') == b'x'*1000
print('zstd round-trip OK')
"
```
Expected: prints `zstd const 93 bounds (-131072, 22)` and `zstd round-trip OK`. This validates the constant, bounds, and that a zstd archive round-trips — the parts the 3.11 CI cannot exercise.
- [ ] **Step 3: Type-check on the VM (pyrefly)**
```bash
tar czf - src pyproject.toml uv.lock .pyrefly-baseline.json | ssh -o BatchMode=yes -p 2244 trenton@localhost 'tar xzf - -C ~/projects/paperless-ngx'
ssh -o BatchMode=yes -p 2244 trenton@localhost 'bash -lc "cd ~/projects/paperless-ngx && uv run pyrefly check"'
```
Expected: no new type errors beyond the baseline. (Note: `import compression.zstd` is guarded behind `importlib.import_module`, so it is never statically resolved on the 3.11 baseline.)
- [ ] **Step 4: Final lint**
Run: `ruff check src/documents/export/ src/documents/management/commands/document_exporter.py src/documents/management/commands/document_importer.py && ruff format --check src/documents/export/ src/documents/management/commands/document_exporter.py src/documents/management/commands/document_importer.py`
Expected: clean.
---
## Notes for the implementer
- **Default behavior is unchanged:** with no flags, the sink is constructed with `compression=ZIP_DEFLATED, compresslevel=None` — byte-method-identical to today (`shutil.make_archive` used `ZIP_DEFLATED` with no level). `test_default_zip_uses_deflate` pins this.
- **zstd availability is gated three ways and never imported statically:** the constant via `getattr`, the codec via `importlib.import_module("compression.zstd")`, and the CLI value rejected with a friendly message on < 3.14. The choices list always contains `zstd` so argparse doesn't hide it.
- **The importer pre-check is the safety net** for portability foot-guns — without it an unreadable entry raises a bare `NotImplementedError` mid-`extractall`. The check runs on `infolist()` (metadata only) before any extraction.
- **Why `--zip-compression` defaults to `None`, not `"deflated"`:** so `handle()` can detect "user passed it without `--zip`" and fail fast. The effective default is resolved as `zip_compression or "deflated"`.
@@ -1,236 +0,0 @@
# Export Zip Compression Control — Design
**Date:** 2026-06-16
**Branch base:** `dev`
**Status:** Design complete (zstd facts verified on CPython 3.14.3) — **depends on**
`2026-06-16-export-sink-architecture-design.md` being implemented first.
## Prerequisite
This builds directly on the export sink refactor. It assumes `ZipExportSink`
already exists and is the single place that owns `zipfile.ZipFile` creation and
entry writes. Do not start this until that refactor has landed; without it, the
change would have to touch the command's zip branches again.
## Problem
Zip export is hardwired to `ZIP_DEFLATED` at the library default level. Users
have no way to trade speed against archive size — a fast `ZIP_STORED` pass for a
quick local copy, or a maximal `ZIP_LZMA` pass for the smallest off-site backup.
The sink refactor turns "which compression" into a single constructor argument,
so exposing it is now a small, isolated change.
## Goal
Let the operator choose the zip compression method and level from the CLI, with
behavior identical to today when the flags are omitted. All knowledge of
compression stays inside `ZipExportSink`; the command only parses flags and maps
them to sink arguments.
## Scope
In scope:
- `ZipExportSink` gains `compression: int` and `compresslevel: int | None`
constructor parameters (default `ZIP_DEFLATED`, `None` → library default),
passed straight to `zipfile.ZipFile(...)`.
- New `document_exporter` flags: `--zip-compression` and
`--zip-compression-level`, valid only with `--zip`.
- Validation: method availability, level range per method, and the
requires-`--zip` guard.
- Import-side: a pre-extract support check in `document_importer` that turns an
unsupported codec into a clear `CommandError` (the importer otherwise decompresses
transparently via `ZipFile.extractall`).
- Docs: add both flags and the zstd-portability caveat to `docs/administration.md`
(the `document_exporter` option list, lines ~257-270 and the `-z`/`-zn` section,
lines ~328-330). New flags are long-form only (`--zip-compression`,
`--zip-compression-level`) — no short aliases, to avoid `-zc`/`-zl` collisions
with the existing `-z`/`-zn`.
Out of scope:
- Compression for any non-zip sink (folder has none; a future S3 sink would
handle its own object storage compression separately).
- Changing the default. Omitting the flags must produce a byte-compatible-method
archive to today's (`ZIP_DEFLATED`, default level).
## Design
### `ZipExportSink` changes
The base sink's signature is `ZipExportSink(target, zip_name, *, delete)`; this
adds two keyword-only params after `delete`:
```python
def __init__(
self,
target: Path,
zip_name: str,
*,
delete: bool = False,
compression: int = zipfile.ZIP_DEFLATED,
compresslevel: int | None = None,
) -> None:
...
# opened in __enter__:
self._zip = zipfile.ZipFile(
self._tmp_path,
"w",
compression=compression,
compresslevel=compresslevel,
allowZip64=True,
)
```
`ZipFile` applies `compression`/`compresslevel` as the default for every
`write`/`writestr` (verified: a `ZipFile(..., compression=ZIP_BZIP2)` yields
entries with `compress_type == ZIP_BZIP2` without per-call args), so `add_file` /
`add_json` / the manifest entry need no changes. Directory marker entries are
empty so their compressed payload is zero, but they are still _tagged_ with the
chosen `compress_type` — harmless, but tests that read `infolist()` should filter
or account for marker entries (see Testing).
### CLI flags (`document_exporter`)
- `--zip-compression {stored,deflated,bzip2,lzma}` — and `zstd` **when the
runtime supports it** (see below). Maps to the matching `zipfile.ZIP_*`
constant. Default `deflated`.
- `--zip-compression-level N` — integer. Per-method accepted ranges (verified
against the [3.14 `zipfile` docs](https://docs.python.org/3.14/library/zipfile.html#zipfile.ZipFile)):
- `deflated`: **09** (`zlib` also accepts `-1` = "default", identical to
omitting the flag / `compresslevel=None`).
- `bzip2`: **19** (`0` is invalid for bzip2).
- `lzma`, `stored`: level has **no effect** — passing `--zip-compression-level`
with either is a `CommandError`, not a silent accept (consistent with the
base refactor's fail-fast posture).
- `zstd`: **-131072 … 22** (the documented commonly-accepted range; the
authoritative bounds are
`compression.zstd.CompressionParameter.compression_level.bounds()`).
Default: unset → library default (`compresslevel=None`).
Both flags require `--zip`; passing either without `--zip` raises a
`CommandError`, matching the incremental-flag rule from the base refactor.
**Why validate up front (not let `zipfile` raise) — verified on 3.14.3:** an
invalid level does _not_ fail at `ZipFile(...)` construction — it fails at the
**first `write`/`writestr` call**, with an opaque message
(`ValueError: Invalid initialization option` for deflated > 9, or
`ValueError: compresslevel must be between 1 and 9` for bzip2). Worse, on context
exit the half-initialized write handle emits a secondary
`AttributeError: '_ZipWriteFile' object has no attribute '_compressor'` during GC
finalization, so the user sees stack-trace noise unrelated to the real cause.
Up-front validation turns all of that into a single clean `CommandError`.
### Validation (in `handle()`, before constructing the sink)
1. **Requires `--zip`.** Either flag without `--zip``CommandError`.
2. **Method availability — via a named, patchable seam.** Expose a module-level
helper `compression_available(method: str) -> bool` that does
`try: import bz2 / import lzma / from compression import zstd except ImportError:
return False`**not** `importlib.util.find_spec`, which can report a stdlib
C-extension as present when importing it actually fails. `stored`/`deflated`
are always available (`zlib` is a hard CPython dependency). For `zstd` the probe
must import `compression.zstd` (3.14+), not merely check that
`zipfile.ZIP_ZSTANDARD` exists. Making this a named function is also what lets
the test patch "method unavailable" with `mocker`. If the chosen method is
unavailable, raise a `CommandError` naming the missing capability — `zipfile`
itself would otherwise raise a bare `RuntimeError`
("Compression requires the (missing) … module").
3. **Level range.** Reject an out-of-range `--zip-compression-level` for the
chosen method with a clear `CommandError`; reject the flag entirely for
`stored`/`lzma` (see above).
### zstd (Python 3.14+)
**Verified empirically on CPython 3.14.3** (via `uv run --python 3.14 --no-project`)
and against [PEP 784](https://peps.python.org/pep-0784/) +
[the 3.14 `zipfile` docs](https://docs.python.org/3.14/library/zipfile.html):
- The compression-method constant is **`zipfile.ZIP_ZSTANDARD`** (added 3.14; its
numeric value is `93`). It does **not** exist on < 3.14.
- It is backed by the new **`compression.zstd`** stdlib module (PEP 784 added a
`compression` namespace package; legacy `bz2`/`lzma`/`zlib` imports are
unchanged). `zipfile` raises `RuntimeError` if `compression.zstd` is
unavailable when zstd is requested.
- Accepted `compresslevel` is **`-131072 … 22`**, confirmed at runtime via
`compression.zstd.CompressionParameter.compression_level.bounds() == (-131072, 22)`.
Gate everything zstd-related at runtime so nothing is imported or referenced on
< 3.14 (the project targets Python ≥ 3.11):
```python
_ZSTD: int | None = getattr(zipfile, "ZIP_ZSTANDARD", None) # None before 3.14
```
Presence of the _constant_ does not guarantee the _codec_ is usable, so the
availability probe (validation step 2) imports `compression.zstd`, not merely
checks the constant.
Keep `zstd` in the `--zip-compression` `choices` **always** (even on < 3.14), and
reject it in validation with a friendly "zstd requires Python 3.14+" message. If
it were dropped from `choices` on older runtimes, argparse would emit a generic
"invalid choice" that reads as though the option never existed — worse UX.
### Import-side compatibility
`document_importer` reads zips with `ZipFile(self.source).extractall(...)`
(`document_importer.py:453`), which decompresses each entry transparently using
whatever method it was stored with — **provided the matching module exists on the
importing machine.**
The failure mode when it doesn't is unfriendly and must be handled: a zstd (or
otherwise unsupported) entry raises a bare `NotImplementedError` **per-entry,
during `extractall`** — _not_ at `ZipFile(self.source)` open, and `is_zipfile()`
still returns true (a zstd archive is a valid zip container). So the importer
enters the zip branch, creates its temp dir, may partially extract other entries,
then blows up mid-extract with no context. **Mitigation (in scope here):** before
extracting, inspect `ZipFile(self.source).infolist()` compress types and, if any
is unsupported on this runtime, raise a `CommandError` naming the method and the
requirement (e.g. "this archive uses zstd, which needs Python 3.14+") instead of
letting `NotImplementedError` escape.
Per-method summary (document in help text + `administration.md`):
- `deflated`/`stored`: universally importable.
- `bzip2`/`lzma`: importable wherever the `bz2`/`lzma` modules are present
(essentially always).
- `zstd`: importable only on Python 3.14+. An archive compressed with `zstd` is
**not** importable on older runtimes.
## Testing
New cases in the sink tests and an export→import round-trip
(pytest classes, factory-boy, `mocker`, `parametrize`, typed; run on the VM):
- **Round-trip per method.** Parametrize over the available methods (skip `zstd`
below 3.14, skip `bzip2`/`lzma` if the module is somehow absent): export a
small library, import it back, assert documents/manifest match.
- **Method is applied.** Assert each written _file_ entry's `compress_type`
equals the requested method (read back via `ZipFile.infolist()`), filtering out
directory marker entries (which are tagged but empty).
- **Level affects size — robustly.** Do **not** compare deflate level 9 vs 1
(on small or incompressible fixtures level 9 can equal or slightly exceed level
1, causing flaky CI). Instead assert that a compressing method on a
moderately-compressible fixture yields a total smaller than `stored`
(`ZIP_STORED`), which is a stable invariant.
- **Validation.** Each flag without `--zip``CommandError`; out-of-range level
(`--zip-compression-level 99`) → a clean `CommandError` from validation
(asserting we never reach the `writestr` that would raise the masked
`ValueError`); `--zip-compression-level` with `stored`/`lzma``CommandError`;
unavailable method (patch the named availability seam with `mocker`) →
`CommandError`; on < 3.14, `--zip-compression zstd` → the friendly
"requires 3.14+" `CommandError`.
- **Import pre-check.** An archive containing an unsupported compress type
produces a `CommandError` from the importer naming the method, not a raw
`NotImplementedError` (simulate by patching the importer's support probe).
- **Default unchanged.** Omitting both flags yields file entries with
`compress_type == ZIP_DEFLATED`, identical to pre-feature behavior.
## Risks
- **Foot-gun archives.** A user could produce a `zstd`/`lzma` archive their
import target can't read. Mitigation: explicit help text and the import-side
notes above; the default stays the universally-readable `deflated`.
- **Optional-module assumptions.** Don't assume `bz2`/`lzma` are always compiled
in; probe and error clearly. Mitigation: the availability validation step.
+10 -9
View File
@@ -833,10 +833,10 @@ contract you signed 8 years ago).
When you search paperless for a document, it tries to match this query When you search paperless for a document, it tries to match this query
against your documents. Paperless will look for matching documents by against your documents. Paperless will look for matching documents by
inspecting their content, title, correspondent, type, tags, notes, and inspecting their content, title, correspondent, type, and tags. Paperless
custom field values. Paperless returns a scored list of results, so that returns a scored list of results, so that documents matching your query
documents matching your query better will appear further up in the search better will appear further up in the search results. Notes and custom field
results. values can be searched using the advanced search syntax described below.
By default, paperless returns only documents which contain all words By default, paperless returns only documents which contain all words
typed in the search bar. A few things to know about how matching works: typed in the search bar. A few things to know about how matching works:
@@ -891,9 +891,9 @@ Supported date keywords: `today`, `yesterday`, `previous week`,
#### Searching custom fields #### Searching custom fields
Custom field values are included in the full-text index, so a plain search Custom field names and values are included in the full-text index, but they
already matches documents whose custom field values contain your search terms. are not searched by a plain, unqualified query. Use the advanced search syntax
To narrow by field name or value specifically: to search by field name or value:
``` ```
custom_fields.value:policy custom_fields.value:policy
@@ -921,8 +921,9 @@ custom_fields.name:"Contract Number" custom_fields.value:1312
#### Searching notes #### Searching notes
Notes content is included in full-text search automatically. To search Notes are included in the full-text index, but they are not searched by a
by note author or content specifically: plain, unqualified query. Use the advanced search syntax to search by note
author or content:
``` ```
notes.user:alice notes.user:alice
+2 -2
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "paperless-ngx" name = "paperless-ngx"
version = "3.0.0" version = "3.0.2"
description = "A community-supported supercharged document management system: scan, index and archive all your physical documents" description = "A community-supported supercharged document management system: scan, index and archive all your physical documents"
readme = "README.md" readme = "README.md"
requires-python = ">=3.11" requires-python = ">=3.11"
@@ -75,7 +75,7 @@ dependencies = [
"sqlite-vec==0.1.9", "sqlite-vec==0.1.9",
"tantivy~=0.26.0", "tantivy~=0.26.0",
"tika-client~=0.11.0", "tika-client~=0.11.0",
"torch~=2.12.0", "torch~=2.13.0",
"watchfiles>=1.1.1", "watchfiles>=1.1.1",
"whitenoise~=6.11", "whitenoise~=6.11",
"zxing-cpp~=3.0.0", "zxing-cpp~=3.0.0",
+20 -16
View File
@@ -1393,8 +1393,8 @@
<context context-type="linenumber">302</context> <context context-type="linenumber">302</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
@@ -3647,6 +3647,21 @@
<context context-type="linenumber">85</context> <context context-type="linenumber">85</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -7444,17 +7459,6 @@
<context context-type="linenumber">92</context> <context context-type="linenumber">92</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -11515,21 +11519,21 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5558341108007064934" datatype="html"> <trans-unit id="5558341108007064934" datatype="html">
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1168781785897678748" datatype="html"> <trans-unit id="1168781785897678748" datatype="html">
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3852289441366561594" datatype="html"> <trans-unit id="3852289441366561594" datatype="html">
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "paperless-ngx-ui", "name": "paperless-ngx-ui",
"version": "3.0.0", "version": "3.0.2",
"scripts": { "scripts": {
"preinstall": "npx only-allow pnpm", "preinstall": "npx only-allow pnpm",
"ng": "ng", "ng": "ng",
@@ -304,7 +304,7 @@
<div class="row mb-3"> <div class="row mb-3">
<div class="col"> <div class="col">
<p i18n> <p i18n>
Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents.
</p> </p>
</div> </div>
</div> </div>
@@ -281,7 +281,7 @@ main {
} }
@media screen and (min-width: 376px) and (max-width: 768px) { @media screen and (min-width: 376px) and (max-width: 768px) {
.navbar-toggler { .navbar:not(:has(pngx-chat)) .navbar-toggler {
// compensate for 2 buttons on the right // compensate for 2 buttons on the right
margin-right: 45px; margin-right: 45px;
} }
@@ -9,14 +9,14 @@
@for (message of messages(); track message) { @for (message of messages(); track message) {
<div class="message d-flex flex-row small" [class.justify-content-end]="message.role === 'user'"> <div class="message d-flex flex-row small" [class.justify-content-end]="message.role === 'user'">
<div class="p-2 m-2" [class.bg-body]="message.role === 'user'"> <div class="p-2 m-2" [class.bg-body]="message.role === 'user'">
<span> <span class="text-break">
{{ message.content }} {{ message.content }}
@if (message.isStreaming) { <span class="blinking-cursor">|</span> } @if (message.isStreaming) { <span class="blinking-cursor">|</span> }
</span> </span>
@if (message.role === 'assistant' && message.references?.length) { @if (message.role === 'assistant' && message.references?.length) {
<div class="chat-references list-group mt-3"> <div class="chat-references list-group mt-3">
@for (reference of message.references; track reference.id) { @for (reference of message.references; track reference.id) {
<a class="list-group-item list-group-item-action text-primary" [routerLink]="['/documents', reference.id]"> <a class="list-group-item list-group-item-action d-flex text-primary text-break" [routerLink]="['/documents', reference.id]">
<i-bs width="0.9em" height="0.9em" name="file-text" class="me-1"></i-bs><span>{{ reference.title }}</span> <i-bs width="0.9em" height="0.9em" name="file-text" class="me-1"></i-bs><span>{{ reference.title }}</span>
</a> </a>
} }
@@ -5,6 +5,7 @@
.chat-messages { .chat-messages {
max-height: 350px; max-height: 350px;
overflow-y: auto; overflow-y: auto;
white-space: pre-wrap;
} }
.chat-references { .chat-references {
@@ -17,6 +17,6 @@
<ng-template #popoverContent> <ng-template #popoverContent>
<div> <div>
{{confirmMessage}}&nbsp;<button class="btn btn-link btn-sm text-danger p-0 m-0 lh-1" type="button" (click)="onConfirm($event)">Yes</button> {{confirmMessage}}&nbsp;<button class="btn btn-link btn-sm text-danger p-0 m-0 lh-1" type="button" (click)="onConfirm($event)" i18n>Yes</button>
</div> </div>
</ng-template> </ng-template>
@@ -18,6 +18,7 @@ import {
DocumentAttributesComponent, DocumentAttributesComponent,
DocumentAttributesSectionKind, DocumentAttributesSectionKind,
} from './document-attributes.component' } from './document-attributes.component'
import { ManagementListComponent } from './management-list/management-list.component'
@Component({ @Component({
selector: 'pngx-dummy-section', selector: 'pngx-dummy-section',
@@ -170,10 +171,32 @@ describe('DocumentAttributesComponent', () => {
expect(component.activeManagementList).toBeNull() expect(component.activeManagementList).toBeNull()
component.activeNavID.set(1) component.activeNavID.set(1)
const managementList = Object.create(ManagementListComponent.prototype)
component.activeOutlet = {
componentInstance: managementList,
} as any
expect(component.activeSection.kind).toBe( expect(component.activeSection.kind).toBe(
DocumentAttributesSectionKind.ManagementList DocumentAttributesSectionKind.ManagementList
) )
expect(component.activeManagementList).toBeDefined() expect(component.activeManagementList).toBe(managementList)
})
it('should use the current component instance when the outlet is reused', () => {
jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(true)
component.activeNavID.set(1)
const firstManagementList = Object.create(ManagementListComponent.prototype)
const secondManagementList = Object.create(
ManagementListComponent.prototype
)
component.activeOutlet = {
componentInstance: firstManagementList,
} as any
expect(component.activeManagementList).toBe(firstManagementList)
component.activeOutlet.componentInstance = secondManagementList
expect(component.activeManagementList).toBe(secondManagementList)
}) })
it('should return activeCustomFields correctly', () => { it('should return activeCustomFields correctly', () => {
@@ -132,11 +132,8 @@ export class DocumentAttributesComponent implements OnInit, OnDestroy {
] ]
@ViewChild('activeOutlet', { read: NgComponentOutlet }) @ViewChild('activeOutlet', { read: NgComponentOutlet })
set activeOutlet(outlet: NgComponentOutlet | undefined) { activeOutlet: NgComponentOutlet
this.activeComponent.set(outlet?.componentInstance ?? null)
}
readonly activeComponent = signal<unknown>(null)
readonly activeNavID = signal<number>(null) readonly activeNavID = signal<number>(null)
get visibleSections(): DocumentAttributesSection[] { get visibleSections(): DocumentAttributesSection[] {
@@ -161,14 +158,14 @@ export class DocumentAttributesComponent implements OnInit, OnDestroy {
this.activeSection?.kind !== DocumentAttributesSectionKind.ManagementList this.activeSection?.kind !== DocumentAttributesSectionKind.ManagementList
) )
return null return null
const instance = this.activeComponent() const instance = this.activeOutlet?.componentInstance
return instance instanceof ManagementListComponent ? instance : null return instance instanceof ManagementListComponent ? instance : null
} }
get activeCustomFields(): CustomFieldsComponent | null { get activeCustomFields(): CustomFieldsComponent | null {
if (this.activeSection?.kind !== DocumentAttributesSectionKind.CustomFields) if (this.activeSection?.kind !== DocumentAttributesSectionKind.CustomFields)
return null return null
const instance = this.activeComponent() const instance = this.activeOutlet?.componentInstance
return instance instanceof CustomFieldsComponent ? instance : null return instance instanceof CustomFieldsComponent ? instance : null
} }
+3 -4
View File
@@ -17,7 +17,7 @@ import {
estimateBrightnessForColor, estimateBrightnessForColor,
hexToHsl, hexToHsl,
} from 'src/app/utils/color' } from 'src/app/utils/color'
import { environment } from 'src/environments/environment' import { DEFAULT_APP_TITLE, environment } from 'src/environments/environment'
import { DEFAULT_DISPLAY_FIELDS, DisplayField } from '../data/document' import { DEFAULT_DISPLAY_FIELDS, DisplayField } from '../data/document'
import { SavedView } from '../data/saved-view' import { SavedView } from '../data/saved-view'
import { import {
@@ -359,9 +359,8 @@ export class SettingsService {
}), }),
tap((uisettings) => { tap((uisettings) => {
this.assignSafeSettings(uisettings.settings) this.assignSafeSettings(uisettings.settings)
if (this.get(SETTINGS_KEYS.APP_TITLE)?.length) { environment.appTitle =
environment.appTitle = this.get(SETTINGS_KEYS.APP_TITLE) this.get(SETTINGS_KEYS.APP_TITLE) || DEFAULT_APP_TITLE
}
this.maybeMigrateSettings() this.maybeMigrateSettings()
// to update lang cookie // to update lang cookie
if (this.settings['language']?.length) if (this.settings['language']?.length)
+4 -2
View File
@@ -1,12 +1,14 @@
const base_url = new URL(document.baseURI) const base_url = new URL(document.baseURI)
export const DEFAULT_APP_TITLE = 'Paperless-ngx'
export const environment = { export const environment = {
production: true, production: true,
apiBaseUrl: document.baseURI + 'api/', apiBaseUrl: document.baseURI + 'api/',
apiVersion: '10', // match src/paperless/settings.py apiVersion: '10', // match src/paperless/settings.py
appTitle: 'Paperless-ngx', appTitle: DEFAULT_APP_TITLE,
tag: 'prod', tag: 'prod',
version: '3.0.0', version: '3.0.2',
webSocketHost: window.location.host, webSocketHost: window.location.host,
webSocketProtocol: window.location.protocol == 'https:' ? 'wss:' : 'ws:', webSocketProtocol: window.location.protocol == 'https:' ? 'wss:' : 'ws:',
webSocketBaseUrl: base_url.pathname + 'ws/', webSocketBaseUrl: base_url.pathname + 'ws/',
+3 -1
View File
@@ -2,11 +2,13 @@
// `ng build --configuration production` replaces `environment.ts` with `environment.prod.ts`. // `ng build --configuration production` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`. // The list of file replacements can be found in `angular.json`.
export const DEFAULT_APP_TITLE = 'Paperless-ngx'
export const environment = { export const environment = {
production: false, production: false,
apiBaseUrl: 'http://localhost:8000/api/', apiBaseUrl: 'http://localhost:8000/api/',
apiVersion: '10', apiVersion: '10',
appTitle: 'Paperless-ngx', appTitle: DEFAULT_APP_TITLE,
tag: 'dev', tag: 'dev',
version: 'DEVELOPMENT', version: 'DEVELOPMENT',
webSocketHost: 'localhost:8000', webSocketHost: 'localhost:8000',
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="needs-translation">Default Permissions</target> <target state="needs-translation">Default Permissions</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Wis</target> <target state="translated">Wis</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Ja</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="needs-translation">Filter by owner</target> <target state="needs-translation">Filter by owner</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Ja</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Eenmalige migrasie van instellings na die databasis is suksesvol voltooi!</target> <target state="translated">Eenmalige migrasie van instellings na die databasis is suksesvol voltooi!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Kan nie instellings na die databasis migreer nie, probeer handmatig bewaar.</target> <target state="translated">Kan nie instellings na die databasis migreer nie, probeer handmatig bewaar.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">U kan die toer weer vanuit die instellingsblad begin.</target> <target state="translated">U kan die toer weer vanuit die instellingsblad begin.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="needs-translation">Default Permissions</target> <target state="needs-translation">Default Permissions</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="needs-translation">Clear</target> <target state="needs-translation">Clear</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="needs-translation">Yes</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="needs-translation">Filter by owner</target> <target state="needs-translation">Filter by owner</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="needs-translation">Yes</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target> <target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target> <target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="needs-translation">You can restart the tour from the settings page.</target> <target state="needs-translation">You can restart the tour from the settings page.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">الصلاحيات الافتراضية</target> <target state="translated">الصلاحيات الافتراضية</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">تنظيف</target> <target state="translated">تنظيف</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">نعم</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">تصفية حسب المالك</target> <target state="translated">تصفية حسب المالك</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">نعم</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html" approved="yes"> <trans-unit id="3542042671420335679" datatype="html" approved="yes">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">تم بنجاح ترحيل الإعدادات مرة واحدة إلى قاعدة البيانات!</target> <target state="translated">تم بنجاح ترحيل الإعدادات مرة واحدة إلى قاعدة البيانات!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">غير قادر على ترحيل الإعدادات إلى قاعدة البيانات، الرجاء محاولة الحفظ يدوياً.</target> <target state="translated">غير قادر على ترحيل الإعدادات إلى قاعدة البيانات، الرجاء محاولة الحفظ يدوياً.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">يمكنك إعادة تشغيل الجولة من صفحة الإعدادات.</target> <target state="translated">يمكنك إعادة تشغيل الجولة من صفحة الإعدادات.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="needs-translation">Default Permissions</target> <target state="needs-translation">Default Permissions</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Ачысціць</target> <target state="translated">Ачысціць</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Так</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="needs-translation">Filter by owner</target> <target state="needs-translation">Filter by owner</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Так</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Паспяхова выканана аднаразовая міграцыя налад у базу!</target> <target state="translated">Паспяхова выканана аднаразовая міграцыя налад у базу!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Немагчыма перанесці налады ў базу дадзеных, паспрабуйце захаваць уручную.</target> <target state="translated">Немагчыма перанесці налады ў базу дадзеных, паспрабуйце захаваць уручную.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="needs-translation">You can restart the tour from the settings page.</target> <target state="needs-translation">You can restart the tour from the settings page.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Права по подразбиране</target> <target state="translated">Права по подразбиране</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> Настройките се прилагат към този потребителски акаунт за обекти (маркери, правила за поща и т. н., но не и документи), създадени чрез уеб интерфейса. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Изчистване</target> <target state="translated">Изчистване</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Да</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Филтър по собственик</target> <target state="translated">Филтър по собственик</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Да</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Успешно завършена еднократна миграция на настройките към базата данни!</target> <target state="translated">Успешно завършена еднократна миграция на настройките към базата данни!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Неуспешно мигриране на настройки в база данни, моля опитайте ръчно запазване.</target> <target state="translated">Неуспешно мигриране на настройки в база данни, моля опитайте ръчно запазване.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Можете да рестартирате обиколката от страницата с настройки.</target> <target state="translated">Можете да рестартирате обиколката от страницата с настройки.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Permisos per defecte</target> <target state="translated">Permisos per defecte</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> S'apliquen a aquest compte d'usuari per als objectes (etiquetes, regles de correu, etc.) creats des de la interfície web. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Neteja</target> <target state="translated">Neteja</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Sí</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Filtrar per propietari</target> <target state="translated">Filtrar per propietari</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Sí</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Completat correctament la migració de la configuració de la base de dades!</target> <target state="translated">Completat correctament la migració de la configuració de la base de dades!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">No es pot migrar la configuració de la base de dades, prova manualment.</target> <target state="translated">No es pot migrar la configuració de la base de dades, prova manualment.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Pots reiniciar el tour des de les opcions.</target> <target state="translated">Pots reiniciar el tour des de les opcions.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Výchozí oprávnění</target> <target state="translated">Výchozí oprávnění</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> Nastavení se vztahují na tento uživatelský účet pro objekty (štítky, pravidla pošty atd. ale ne dokumenty) vytvořené prostřednictvím webového uživatelského rozhraní. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="final">Smazat</target> <target state="final">Smazat</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Ano</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Filtrovat podle vlastníka</target> <target state="translated">Filtrovat podle vlastníka</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Ano</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html" approved="yes"> <trans-unit id="3542042671420335679" datatype="html" approved="yes">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12770,7 +12774,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Úspěšně dokončena jednorázová migrace nastavení do databáze!</target> <target state="translated">Úspěšně dokončena jednorázová migrace nastavení do databáze!</target>
</trans-unit> </trans-unit>
@@ -12778,7 +12782,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Nelze přesunout nastavení do databáze, zkuste ho uložit ručně.</target> <target state="translated">Nelze přesunout nastavení do databáze, zkuste ho uložit ručně.</target>
</trans-unit> </trans-unit>
@@ -12786,7 +12790,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Prohlídku můžete znovu spustit ze stránky s nastavením.</target> <target state="translated">Prohlídku můžete znovu spustit ze stránky s nastavením.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="needs-translation">Default Permissions</target> <target state="needs-translation">Default Permissions</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Ryd</target> <target state="translated">Ryd</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Ja</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="needs-translation">Filter by owner</target> <target state="needs-translation">Filter by owner</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Ja</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html" approved="yes"> <trans-unit id="3542042671420335679" datatype="html" approved="yes">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target> <target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target> <target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="needs-translation">You can restart the tour from the settings page.</target> <target state="needs-translation">You can restart the tour from the settings page.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Standardberechtigungen</target> <target state="translated">Standardberechtigungen</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> Einstellungen gelten für dieses Benutzerkonto für Objekte (Tags, E-Mail-Regeln, etc. - jedoch nicht für Dokumente), die über die Weboberfläche erstellt wurden. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Zurücksetzen</target> <target state="translated">Zurücksetzen</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Ja</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Nach Eigentümer filtern</target> <target state="translated">Nach Eigentümer filtern</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Ja</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12770,7 +12774,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Einmalige Migration der Einstellungen in die Datenbank erfolgreich abgeschlossen!</target> <target state="translated">Einmalige Migration der Einstellungen in die Datenbank erfolgreich abgeschlossen!</target>
</trans-unit> </trans-unit>
@@ -12778,7 +12782,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Einstellungen konnten nicht in die Datenbank migriert werden. Bitte versuchen Sie, manuell zu speichern.</target> <target state="translated">Einstellungen konnten nicht in die Datenbank migriert werden. Bitte versuchen Sie, manuell zu speichern.</target>
</trans-unit> </trans-unit>
@@ -12786,7 +12790,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Sie können die Tour in den Einstellungen erneut starten.</target> <target state="translated">Sie können die Tour in den Einstellungen erneut starten.</target>
</trans-unit> </trans-unit>
+25 -21
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="final">Standardberechtigungen</target> <target state="final">Standardberechtigungen</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html" approved="yes"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="final"> Einstellungen gelten für dieses Benutzerkonto für Objekte (Tags, E-Mail-Regeln, etc. - jedoch nicht für Dokumente), die über die Weboberfläche erstellt wurden. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html" approved="yes"> <trans-unit id="4292903881380648974" datatype="html" approved="yes">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="final">Zurücksetzen</target> <target state="final">Zurücksetzen</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Ja</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html" approved="yes"> <trans-unit id="7515883357904500238" datatype="html" approved="yes">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="final">Nach Eigentümer filtern</target> <target state="final">Nach Eigentümer filtern</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Ja</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html" approved="yes"> <trans-unit id="3542042671420335679" datatype="html" approved="yes">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -9715,7 +9719,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context> <context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
<context context-type="linenumber">8</context> <context context-type="linenumber">8</context>
</context-group> </context-group>
<target state="needs-translation"><x id="INTERPOLATION" equiv-text="document().title | documentTitle }}"/> thumbnail</target> <target state="translated"><x id="INTERPOLATION" equiv-text="document().title | documentTitle }}"/> Vorschau</target>
</trans-unit> </trans-unit>
<trans-unit id="2784168796433474565" datatype="html" approved="yes"> <trans-unit id="2784168796433474565" datatype="html" approved="yes">
<source>Filter by tag</source> <source>Filter by tag</source>
@@ -12078,13 +12082,13 @@
</context-group> </context-group>
<target state="final">KI aktiviert</target> <target state="final">KI aktiviert</target>
</trans-unit> </trans-unit>
<trans-unit id="8028880048909383956" datatype="html"> <trans-unit id="8028880048909383956" datatype="html" approved="yes">
<source>Consider privacy implications when enabling AI features, especially if using a remote model.</source> <source>Consider privacy implications when enabling AI features, especially if using a remote model.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/data/paperless-config.ts</context> <context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">288</context> <context context-type="linenumber">288</context>
</context-group> </context-group>
<target state="translated">Berücksichtigen Sie die Auswirkungen auf die Privatsphäre der Benutzer, wenn Sie KI-Funktionen aktivieren, insbesondere wenn Sie ein nicht lokales Modell verwenden.</target> <target state="final">Berücksichtigen Sie die Auswirkungen auf die Privatsphäre der Benutzer, wenn Sie KI-Funktionen aktivieren, insbesondere wenn Sie kein lokales Modell verwenden.</target>
</trans-unit> </trans-unit>
<trans-unit id="8131374115579345652" datatype="html"> <trans-unit id="8131374115579345652" datatype="html">
<source>LLM Embedding Backend</source> <source>LLM Embedding Backend</source>
@@ -12770,7 +12774,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="final">Einmalige Migration der Einstellungen in die Datenbank erfolgreich abgeschlossen!</target> <target state="final">Einmalige Migration der Einstellungen in die Datenbank erfolgreich abgeschlossen!</target>
</trans-unit> </trans-unit>
@@ -12778,7 +12782,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="final">Einstellungen konnten nicht in die Datenbank migriert werden. Bitte versuchen Sie, manuell zu speichern.</target> <target state="final">Einstellungen konnten nicht in die Datenbank migriert werden. Bitte versuchen Sie, manuell zu speichern.</target>
</trans-unit> </trans-unit>
@@ -12786,7 +12790,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="final">Sie können die Tour in den Einstellungen erneut starten.</target> <target state="final">Sie können die Tour in den Einstellungen erneut starten.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Προεπιλεγμένα δικαιώματα</target> <target state="translated">Προεπιλεγμένα δικαιώματα</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Καθαρισμός</target> <target state="translated">Καθαρισμός</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Ναι</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="needs-translation">Filter by owner</target> <target state="needs-translation">Filter by owner</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Ναι</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Ολοκληρώθηκε με επιτυχία η μετεγκατάσταση των ρυθμίσεων στη βάση δεδομένων!</target> <target state="translated">Ολοκληρώθηκε με επιτυχία η μετεγκατάσταση των ρυθμίσεων στη βάση δεδομένων!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Δεν είναι δυνατή η μετεγκατάσταση των ρυθμίσεων στη βάση δεδομένων, παρακαλώ δοκιμάστε χειροκίνητα.</target> <target state="translated">Δεν είναι δυνατή η μετεγκατάσταση των ρυθμίσεων στη βάση δεδομένων, παρακαλώ δοκιμάστε χειροκίνητα.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Μπορείτε να επανεκκινήσετε την περιήγηση από τη σελίδα ρυθμίσεων.</target> <target state="translated">Μπορείτε να επανεκκινήσετε την περιήγηση από τη σελίδα ρυθμίσεων.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Permisos por defecto</target> <target state="translated">Permisos por defecto</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> La configuración aplica a esta cuenta de usuario para objetos (Etiquetas, Reglas de correo, etc. pero no documentos) creados a través de la interfaz web. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="final">Limpiar</target> <target state="final">Limpiar</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Si</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Filtrar por propietario</target> <target state="translated">Filtrar por propietario</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Si</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">¡Se completó con éxito la migración única de la configuración a la base de datos!</target> <target state="translated">¡Se completó con éxito la migración única de la configuración a la base de datos!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">No se puede migrar la configuración a la base de datos, por favor intente guardarla manualmente.</target> <target state="translated">No se puede migrar la configuración a la base de datos, por favor intente guardarla manualmente.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Puede reiniciar la visita desde la página de configuración.</target> <target state="translated">Puede reiniciar la visita desde la página de configuración.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="needs-translation">Default Permissions</target> <target state="needs-translation">Default Permissions</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="needs-translation">Clear</target> <target state="needs-translation">Clear</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="needs-translation">Yes</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="needs-translation">Filter by owner</target> <target state="needs-translation">Filter by owner</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="needs-translation">Yes</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target> <target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target> <target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="needs-translation">You can restart the tour from the settings page.</target> <target state="needs-translation">You can restart the tour from the settings page.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">مجوزهای پیش فرض</target> <target state="translated">مجوزهای پیش فرض</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated">تنظیمات برای این حساب کاربری برای اشیاء (برچسب ها ، قوانین نامه و غیره اما نه اسناد) ایجاد شده از طریق UI وب اعمال می شود.</target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">پاک کردن</target> <target state="translated">پاک کردن</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">بله</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">فیلتر توسط مالک</target> <target state="translated">فیلتر توسط مالک</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">بله</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">با موفقیت مهاجرت یک بار تنظیمات به پایگاه داده را تکمیل کرد!</target> <target state="translated">با موفقیت مهاجرت یک بار تنظیمات به پایگاه داده را تکمیل کرد!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">برای انتقال تنظیمات به پایگاه داده امکان پذیر نیست ، لطفاً به صورت دستی ذخیره کنید.</target> <target state="translated">برای انتقال تنظیمات به پایگاه داده امکان پذیر نیست ، لطفاً به صورت دستی ذخیره کنید.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">می توانید تور را از صفحه تنظیمات مجدداً راه اندازی کنید.</target> <target state="translated">می توانید تور را از صفحه تنظیمات مجدداً راه اندازی کنید.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Oletusoikeudet</target> <target state="translated">Oletusoikeudet</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Tyhjennä</target> <target state="translated">Tyhjennä</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Kyllä</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="needs-translation">Filter by owner</target> <target state="needs-translation">Filter by owner</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Kyllä</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Kertaluontoinen asetusten migratointi tietokantaan suoritettu onnistuneesti!</target> <target state="translated">Kertaluontoinen asetusten migratointi tietokantaan suoritettu onnistuneesti!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Asetuksia ei saatu migratoitua tietokantaan. Yritä tallennusta manuaalisesti.</target> <target state="translated">Asetuksia ei saatu migratoitua tietokantaan. Yritä tallennusta manuaalisesti.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Voit käynnistää opastuksen uudelleen asetussivulta.</target> <target state="translated">Voit käynnistää opastuksen uudelleen asetussivulta.</target>
</trans-unit> </trans-unit>
+55 -51
View File
@@ -432,7 +432,7 @@
<context context-type="sourcefile">src/app/app.component.ts</context> <context context-type="sourcefile">src/app/app.component.ts</context>
<context context-type="linenumber">171</context> <context context-type="linenumber">171</context>
</context-group> </context-group>
<target state="translated">Le tableau de bord peut être utilisé pour afficher les vues enregistrées, comme une boîte de réception. Les vues se trouvent dans Paramètres &gt; Vues enregistrées une fois que vous en avez créées.</target> <target state="translated">Le tableau de bord peut être utilisé pour afficher les vues enregistrées, comme une boîte de réception. Les vues se trouvent dans Paramètres &gt; Vues enregistrées une fois que vous en avez créé.</target>
</trans-unit> </trans-unit>
<trans-unit id="9075755296812854717" datatype="html" approved="yes"> <trans-unit id="9075755296812854717" datatype="html" approved="yes">
<source>Drag-and-drop documents here to start uploading or place them in the consume folder. You can also drag-and-drop documents anywhere on all other pages of the web app. Once you do, Paperless-ngx will start training its machine learning algorithms.</source> <source>Drag-and-drop documents here to start uploading or place them in the consume folder. You can also drag-and-drop documents anywhere on all other pages of the web app. Once you do, Paperless-ngx will start training its machine learning algorithms.</source>
@@ -1264,7 +1264,7 @@
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">185</context> <context context-type="linenumber">185</context>
</context-group> </context-group>
<target state="translated">Afficher le nombre de documents dans la barre latérale vues enregistrées</target> <target state="translated">Afficher le nombre de documents dans les vues enregistrées dans la barre latérale</target>
</trans-unit> </trans-unit>
<trans-unit id="8939587804990976924" datatype="html" approved="yes"> <trans-unit id="8939587804990976924" datatype="html" approved="yes">
<source>Items per page</source> <source>Items per page</source>
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="final">Droits d'accès par défaut</target> <target state="final">Droits d'accès par défaut</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> Les paramètres sappliquent à ce compte utilisateur pour les objets (étiquettes, règles de courriel, etc. à lexception des documents) créés via linterface web. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html" approved="yes"> <trans-unit id="4292903881380648974" datatype="html" approved="yes">
<source>Default Owner</source> <source>Default Owner</source>
@@ -2484,7 +2484,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">66</context> <context context-type="linenumber">66</context>
</context-group> </context-group>
<target state="needs-translation">Consume File</target> <target state="translated">Fichier à consommer</target>
</trans-unit> </trans-unit>
<trans-unit id="5622386857946132209" datatype="html"> <trans-unit id="5622386857946132209" datatype="html">
<source>Train Classifier</source> <source>Train Classifier</source>
@@ -2492,7 +2492,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">70</context> <context context-type="linenumber">70</context>
</context-group> </context-group>
<target state="needs-translation">Train Classifier</target> <target state="translated">Entrainer le classificateur</target>
</trans-unit> </trans-unit>
<trans-unit id="776309955507105337" datatype="html"> <trans-unit id="776309955507105337" datatype="html">
<source>Sanity Check</source> <source>Sanity Check</source>
@@ -2520,7 +2520,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">77</context> <context context-type="linenumber">77</context>
</context-group> </context-group>
<target state="needs-translation">LLM Index</target> <target state="translated">Index LLM</target>
</trans-unit> </trans-unit>
<trans-unit id="6402092370576716734" datatype="html"> <trans-unit id="6402092370576716734" datatype="html">
<source>Empty Trash</source> <source>Empty Trash</source>
@@ -2528,7 +2528,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">80</context> <context context-type="linenumber">80</context>
</context-group> </context-group>
<target state="translated">Vider la poubelle</target> <target state="translated">Vider la corbeille</target>
</trans-unit> </trans-unit>
<trans-unit id="4173754487295857311" datatype="html"> <trans-unit id="4173754487295857311" datatype="html">
<source>Check Workflows</source> <source>Check Workflows</source>
@@ -2536,7 +2536,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">84</context> <context context-type="linenumber">84</context>
</context-group> </context-group>
<target state="needs-translation">Check Workflows</target> <target state="translated">Processus de contrôle</target>
</trans-unit> </trans-unit>
<trans-unit id="2065831805515896240" datatype="html"> <trans-unit id="2065831805515896240" datatype="html">
<source>Bulk Update</source> <source>Bulk Update</source>
@@ -2560,7 +2560,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">96</context> <context context-type="linenumber">96</context>
</context-group> </context-group>
<target state="needs-translation">Build Share Link</target> <target state="translated">Créer un lien de partage</target>
</trans-unit> </trans-unit>
<trans-unit id="6581973658756561124" datatype="html"> <trans-unit id="6581973658756561124" datatype="html">
<source>Bulk Delete</source> <source>Bulk Delete</source>
@@ -2696,7 +2696,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">348</context> <context context-type="linenumber">348</context>
</context-group> </context-group>
<target state="needs-translation">Confirm Dismiss All</target> <target state="translated">Confirmer « Tout ignorer »</target>
</trans-unit> </trans-unit>
<trans-unit id="4157200209636243740" datatype="html"> <trans-unit id="4157200209636243740" datatype="html">
<source>Dismiss all <x id="PH" equiv-text="this.totalTasks()"/> tasks?</source> <source>Dismiss all <x id="PH" equiv-text="this.totalTasks()"/> tasks?</source>
@@ -2704,7 +2704,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">349</context> <context context-type="linenumber">349</context>
</context-group> </context-group>
<target state="needs-translation">Dismiss all <x id="PH" equiv-text="this.totalTasks()"/> tasks?</target> <target state="translated">Ignorer toutes (<x id="PH" equiv-text="this.totalTasks()"/>) les tâches ?</target>
</trans-unit> </trans-unit>
<trans-unit id="8149502458056418229" datatype="html"> <trans-unit id="8149502458056418229" datatype="html">
<source>Success. New document id <x id="PH" equiv-text="documentId"/> created</source> <source>Success. New document id <x id="PH" equiv-text="documentId"/> created</source>
@@ -2724,7 +2724,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context> <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">452</context> <context context-type="linenumber">452</context>
</context-group> </context-group>
<target state="needs-translation">Duplicate of document #<x id="PH" equiv-text="duplicateOf"/></target> <target state="translated">Doublon du document #<x id="PH" equiv-text="duplicateOf"/></target>
</trans-unit> </trans-unit>
<trans-unit id="3418677553313974490" datatype="html" approved="yes"> <trans-unit id="3418677553313974490" datatype="html" approved="yes">
<source>Trash</source> <source>Trash</source>
@@ -2772,7 +2772,7 @@
<context context-type="sourcefile">src/app/components/manage/mail/processed-mail-dialog/processed-mail-dialog.component.html</context> <context context-type="sourcefile">src/app/components/manage/mail/processed-mail-dialog/processed-mail-dialog.component.html</context>
<context context-type="linenumber">89</context> <context context-type="linenumber">89</context>
</context-group> </context-group>
<target state="translated">Effacer le(s) sélectionné(s)</target> <target state="translated">Supprimer la sélection</target>
</trans-unit> </trans-unit>
<trans-unit id="8597030111956627342" datatype="html" approved="yes"> <trans-unit id="8597030111956627342" datatype="html" approved="yes">
<source>Empty trash</source> <source>Empty trash</source>
@@ -2984,7 +2984,7 @@
<context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context> <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
<context context-type="linenumber">78</context> <context context-type="linenumber">78</context>
</context-group> </context-group>
<target state="translated">Cette opération effacera définitivement ce document.</target> <target state="translated">Cette opération supprimera définitivement ce document.</target>
</trans-unit> </trans-unit>
<trans-unit id="5641451190833696892" datatype="html" approved="yes"> <trans-unit id="5641451190833696892" datatype="html" approved="yes">
<source>This operation cannot be undone.</source> <source>This operation cannot be undone.</source>
@@ -3048,7 +3048,7 @@
<context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context> <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
<context context-type="linenumber">111</context> <context context-type="linenumber">111</context>
</context-group> </context-group>
<target state="translated">Cette action effacera définitivement les documents sélectionnés.</target> <target state="translated">Cette action supprimera définitivement les documents sélectionnés.</target>
</trans-unit> </trans-unit>
<trans-unit id="6804051092296228130" datatype="html"> <trans-unit id="6804051092296228130" datatype="html">
<source>This operation will permanently delete all documents in the trash.</source> <source>This operation will permanently delete all documents in the trash.</source>
@@ -3056,7 +3056,7 @@
<context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context> <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
<context context-type="linenumber">112</context> <context context-type="linenumber">112</context>
</context-group> </context-group>
<target state="translated">Cette opération effacera définitivement tous les documents de la corbeille.</target> <target state="translated">Cette opération supprimera définitivement tous les documents de la corbeille.</target>
</trans-unit> </trans-unit>
<trans-unit id="6996183233986182894" datatype="html"> <trans-unit id="6996183233986182894" datatype="html">
<source>Document(s) deleted</source> <source>Document(s) deleted</source>
@@ -3064,7 +3064,7 @@
<context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context> <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
<context context-type="linenumber">123</context> <context context-type="linenumber">123</context>
</context-group> </context-group>
<target state="translated">Document(s) effacé(s)</target> <target state="translated">Document(s) supprimé(s)</target>
</trans-unit> </trans-unit>
<trans-unit id="6962724852893361467" datatype="html"> <trans-unit id="6962724852893361467" datatype="html">
<source>Error deleting document(s)</source> <source>Error deleting document(s)</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="final">Réinitialiser</target> <target state="final">Réinitialiser</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Oui</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html" approved="yes"> <trans-unit id="7515883357904500238" datatype="html" approved="yes">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -5764,7 +5780,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">158</context> <context context-type="linenumber">158</context>
</context-group> </context-group>
<target state="translated">Déclenche pour les documents qui correspondent à <x id="START_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;em&gt;"/>tous<x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/>les filtres spécifiés ci-dessous.</target> <target state="translated">Déclenche pour les documents qui correspondent à <x id="START_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;em&gt;"/>tous<x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/> les filtres spécifiés ci-dessous.</target>
</trans-unit> </trans-unit>
<trans-unit id="7467799586957602479" datatype="html"> <trans-unit id="7467799586957602479" datatype="html">
<source>Filter filename</source> <source>Filter filename</source>
@@ -6084,7 +6100,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">418</context> <context context-type="linenumber">418</context>
</context-group> </context-group>
<target state="translated">URL du Webhook</target> <target state="translated">URL du webhook</target>
</trans-unit> </trans-unit>
<trans-unit id="7491983459027245019" datatype="html"> <trans-unit id="7491983459027245019" datatype="html">
<source>Use parameters for webhook body</source> <source>Use parameters for webhook body</source>
@@ -6116,7 +6132,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">426</context> <context context-type="linenumber">426</context>
</context-group> </context-group>
<target state="translated">Corps du Webhook</target> <target state="translated">Corps du webhook</target>
</trans-unit> </trans-unit>
<trans-unit id="3829826512656746316" datatype="html"> <trans-unit id="3829826512656746316" datatype="html">
<source>Webhook headers</source> <source>Webhook headers</source>
@@ -6124,7 +6140,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">428</context> <context context-type="linenumber">428</context>
</context-group> </context-group>
<target state="translated">En-têtes Webhook</target> <target state="translated">En-têtes du webhook</target>
</trans-unit> </trans-unit>
<trans-unit id="2114525789021600887" datatype="html"> <trans-unit id="2114525789021600887" datatype="html">
<source>Include document</source> <source>Include document</source>
@@ -6140,7 +6156,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">436,438</context> <context context-type="linenumber">436,438</context>
</context-group> </context-group>
<target state="translated"> Un mot de passe par ligne. Le workflow va les essayer dans l'ordre jusqu'à ce que l'un d'entre eux réussisse. </target> <target state="translated"> Un mot de passe par ligne. Le workflow les essaiera dans l'ordre jusqu'à ce qu'un réussisse. </target>
</trans-unit> </trans-unit>
<trans-unit id="3853121441237751087" datatype="html"> <trans-unit id="3853121441237751087" datatype="html">
<source>Passwords</source> <source>Passwords</source>
@@ -7598,7 +7614,7 @@
<context context-type="sourcefile">src/app/components/common/share-link-bundle-manage-dialog/share-link-bundle-manage-dialog.component.html</context> <context context-type="sourcefile">src/app/components/common/share-link-bundle-manage-dialog/share-link-bundle-manage-dialog.component.html</context>
<context context-type="linenumber">62</context> <context context-type="linenumber">62</context>
</context-group> </context-group>
<target state="needs-translation">View error details</target> <target state="translated">Afficher les détails de l'erreur</target>
</trans-unit> </trans-unit>
<trans-unit id="2057574872309338088" datatype="html"> <trans-unit id="2057574872309338088" datatype="html">
<source>Copy share link</source> <source>Copy share link</source>
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Filtrer par propriétaire</target> <target state="translated">Filtrer par propriétaire</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Oui</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html" approved="yes"> <trans-unit id="3542042671420335679" datatype="html" approved="yes">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8656,7 +8660,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
<context context-type="linenumber">318</context> <context context-type="linenumber">318</context>
</context-group> </context-group>
<target state="needs-translation">Original SHA256 checksum</target> <target state="translated">Somme de contrôle SHA256 de l'original</target>
</trans-unit> </trans-unit>
<trans-unit id="5888243105821763422" datatype="html" approved="yes"> <trans-unit id="5888243105821763422" datatype="html" approved="yes">
<source>Original file size</source> <source>Original file size</source>
@@ -8680,7 +8684,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
<context context-type="linenumber">331</context> <context context-type="linenumber">331</context>
</context-group> </context-group>
<target state="needs-translation">Archive SHA256 checksum</target> <target state="translated">Somme de contrôle SHA256 de l'archive</target>
</trans-unit> </trans-unit>
<trans-unit id="6033581412811562084" datatype="html" approved="yes"> <trans-unit id="6033581412811562084" datatype="html" approved="yes">
<source>Archive file size</source> <source>Archive file size</source>
@@ -8736,7 +8740,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
<context context-type="linenumber">407</context> <context context-type="linenumber">407</context>
</context-group> </context-group>
<target state="translated">Documents en double détectés:</target> <target state="translated">Documents en double détectés :</target>
</trans-unit> </trans-unit>
<trans-unit id="14058600336670816" datatype="html"> <trans-unit id="14058600336670816" datatype="html">
<source>In trash</source> <source>In trash</source>
@@ -8932,7 +8936,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1271</context> <context context-type="linenumber">1271</context>
</context-group> </context-group>
<target state="needs-translation">Error saving document "<x id="PH" equiv-text="this.document().title"/>"</target> <target state="translated">Erreur lors de la sauvegarde du document "<x id="PH" equiv-text="this.document().title"/>"</target>
</trans-unit> </trans-unit>
<trans-unit id="448882439049417053" datatype="html" approved="yes"> <trans-unit id="448882439049417053" datatype="html" approved="yes">
<source>Error saving document</source> <source>Error saving document</source>
@@ -9228,7 +9232,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-version-dropdown/document-version-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-version-dropdown/document-version-dropdown.component.ts</context>
<context context-type="linenumber">224</context> <context context-type="linenumber">224</context>
</context-group> </context-group>
<target state="needs-translation">Missing task ID.</target> <target state="translated">ID de tâche manquant.</target>
</trans-unit> </trans-unit>
<trans-unit id="205445381296663832" datatype="html"> <trans-unit id="205445381296663832" datatype="html">
<source>Upload failed.</source> <source>Upload failed.</source>
@@ -9248,7 +9252,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-version-dropdown/document-version-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-version-dropdown/document-version-dropdown.component.ts</context>
<context context-type="linenumber">274</context> <context context-type="linenumber">274</context>
</context-group> </context-group>
<target state="needs-translation">Error uploading new version</target> <target state="translated">Erreur lors du téléversement de la nouvelle version</target>
</trans-unit> </trans-unit>
<trans-unit id="6299008920007331381" datatype="html" approved="yes"> <trans-unit id="6299008920007331381" datatype="html" approved="yes">
<source>Edit:</source> <source>Edit:</source>
@@ -10275,7 +10279,7 @@
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">212</context> <context context-type="linenumber">212</context>
</context-group> </context-group>
<target state="needs-translation">Custom fields (Deprecated)</target> <target state="translated">Champs personnalisés (Obsolète)</target>
</trans-unit> </trans-unit>
<trans-unit id="2649431021108393503" datatype="html" approved="yes"> <trans-unit id="2649431021108393503" datatype="html" approved="yes">
<source>More like</source> <source>More like</source>
@@ -10411,7 +10415,7 @@
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
<context context-type="linenumber">332</context> <context context-type="linenumber">332</context>
</context-group> </context-group>
<target state="needs-translation">Title &amp; content: <x id="PH" equiv-text="rule.value"/></target> <target state="translated">Titre &amp; contenu : <x id="PH" equiv-text="rule.value"/></target>
</trans-unit> </trans-unit>
<trans-unit id="1872523635812236432" datatype="html" approved="yes"> <trans-unit id="1872523635812236432" datatype="html" approved="yes">
<source>ASN: <x id="PH" equiv-text="rule.value"/></source> <source>ASN: <x id="PH" equiv-text="rule.value"/></source>
@@ -10935,7 +10939,7 @@
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.ts</context> <context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.ts</context>
<context context-type="linenumber">453</context> <context context-type="linenumber">453</context>
</context-group> </context-group>
<target state="translated">Cette action effacera définitivement les <x id="PH" equiv-text="this.typeNamePlural"/> documents sélectionnés.</target> <target state="translated">Cette action supprimera définitivement les <x id="PH" equiv-text="this.typeNamePlural"/> documents sélectionnés.</target>
</trans-unit> </trans-unit>
<trans-unit id="5897787932098828336" datatype="html"> <trans-unit id="5897787932098828336" datatype="html">
<source>Objects deleted successfully</source> <source>Objects deleted successfully</source>
@@ -12180,7 +12184,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context> <context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">365</context> <context context-type="linenumber">365</context>
</context-group> </context-group>
<target state="needs-translation">LLM Request Timeout</target> <target state="translated">Délai d'attente des requêtes LLM</target>
</trans-unit> </trans-unit>
<trans-unit id="483994032066441287" datatype="html"> <trans-unit id="483994032066441287" datatype="html">
<source>Timeout in seconds for LLM requests.</source> <source>Timeout in seconds for LLM requests.</source>
@@ -12188,7 +12192,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context> <context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">369</context> <context context-type="linenumber">369</context>
</context-group> </context-group>
<target state="needs-translation">Timeout in seconds for LLM requests.</target> <target state="translated">Délai d'attente en secondes pour les requêtes LLM.</target>
</trans-unit> </trans-unit>
<trans-unit id="9155387182259025015" datatype="html"> <trans-unit id="9155387182259025015" datatype="html">
<source>Processing</source> <source>Processing</source>
@@ -12770,7 +12774,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="final">La migration des paramètres vers la base de données a été effectuée avec succès !</target> <target state="final">La migration des paramètres vers la base de données a été effectuée avec succès !</target>
</trans-unit> </trans-unit>
@@ -12778,7 +12782,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="final">Impossible de migrer les paramètres vers la base de données, veuillez essayer denregistrer manuellement.</target> <target state="final">Impossible de migrer les paramètres vers la base de données, veuillez essayer denregistrer manuellement.</target>
</trans-unit> </trans-unit>
@@ -12786,7 +12790,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="final">Vous pouvez recommencer la visite depuis les paramètres.</target> <target state="final">Vous pouvez recommencer la visite depuis les paramètres.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">הרשאות ברירת מחדל</target> <target state="translated">הרשאות ברירת מחדל</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> ההגדרות חלות על חשבון משתמש זה עבור אובייקטים (תגים, כללי דואר וכו'. אבל לא מסמכים) שנוצרו באמצעות ממשק המשתמש באינטרנט. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">ניקוי</target> <target state="translated">ניקוי</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">כן</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">סינון לפי בעלים</target> <target state="translated">סינון לפי בעלים</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">כן</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12770,7 +12774,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">הושלמה בהצלחה העברה חד פעמית של הגדרות למסד הנתונים!</target> <target state="translated">הושלמה בהצלחה העברה חד פעמית של הגדרות למסד הנתונים!</target>
</trans-unit> </trans-unit>
@@ -12778,7 +12782,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">לא ניתן לבצע העברה של הגדרות למסד הנתונים, נסה לשמור באופן ידני.</target> <target state="translated">לא ניתן לבצע העברה של הגדרות למסד הנתונים, נסה לשמור באופן ידני.</target>
</trans-unit> </trans-unit>
@@ -12786,7 +12790,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="needs-translation">You can restart the tour from the settings page.</target> <target state="needs-translation">You can restart the tour from the settings page.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="needs-translation">Default Permissions</target> <target state="needs-translation">Default Permissions</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="needs-translation">Clear</target> <target state="needs-translation">Clear</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="needs-translation">Yes</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="needs-translation">Filter by owner</target> <target state="needs-translation">Filter by owner</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="needs-translation">Yes</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target> <target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target> <target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="needs-translation">You can restart the tour from the settings page.</target> <target state="needs-translation">You can restart the tour from the settings page.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Zadane ovlasti</target> <target state="translated">Zadane ovlasti</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated">Postavke se primjenjuju na ovaj korisnički račun za objekte (oznake, pravila pošte, itd. ali ne i dokumente) stvorene putem web sučelja.</target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Očisti</target> <target state="translated">Očisti</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Da</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Filtriraj po vlasniku</target> <target state="translated">Filtriraj po vlasniku</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Da</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Jednokratna migracija postavki u bazu podataka uspješno završena!</target> <target state="translated">Jednokratna migracija postavki u bazu podataka uspješno završena!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Nije moguće migrirati postavke u bazu podataka, pokušajte ručno spremiti.</target> <target state="translated">Nije moguće migrirati postavke u bazu podataka, pokušajte ručno spremiti.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Možete ponovo pokrenuti obilazak sa stranice postavki.</target> <target state="translated">Možete ponovo pokrenuti obilazak sa stranice postavki.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Alapértelmezett engedélyek</target> <target state="translated">Alapértelmezett engedélyek</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> A beállítások erre a felhasználói fiókra vonatkoznak a webes felületen létrehozott objektumok (címkék, levelezési szabályok stb. de nem a dokumentumok) esetében. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Törlés</target> <target state="translated">Törlés</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Igen</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Szűrés tulajdonos szerint</target> <target state="translated">Szűrés tulajdonos szerint</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Igen</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Sikeresen befejeződött a beállítások egyszeri migrálása az adatbázisba!</target> <target state="translated">Sikeresen befejeződött a beállítások egyszeri migrálása az adatbázisba!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Nem sikerült a beállításokat az adatbázisba migrálni, kérjük, próbálja meg manuálisan menteni.</target> <target state="translated">Nem sikerült a beállításokat az adatbázisba migrálni, kérjük, próbálja meg manuálisan menteni.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">A túrát a beállítások oldalról indíthatja újra.</target> <target state="translated">A túrát a beállítások oldalról indíthatja újra.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Izin bawaan</target> <target state="translated">Izin bawaan</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> Pengaturan berlaku untuk akun pengguna ini pada objek (Tag, Aturan Email, dsb. namun bukan dokumen) yang dibuat lewat antarmuka web. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Bersihkan</target> <target state="translated">Bersihkan</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Ya</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Saring berdasarkan pemilik</target> <target state="translated">Saring berdasarkan pemilik</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Ya</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12770,7 +12774,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Berhasil menyelesaikan migrasi pengaturan satu kali ke basis data!</target> <target state="translated">Berhasil menyelesaikan migrasi pengaturan satu kali ke basis data!</target>
</trans-unit> </trans-unit>
@@ -12778,7 +12782,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Tidak dapat memigrasikan pengaturan ke basis data, silakan coba simpan secara manual.</target> <target state="translated">Tidak dapat memigrasikan pengaturan ke basis data, silakan coba simpan secara manual.</target>
</trans-unit> </trans-unit>
@@ -12786,7 +12790,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Anda dapat memulai ulang tur dari halaman pengaturan.</target> <target state="translated">Anda dapat memulai ulang tur dari halaman pengaturan.</target>
</trans-unit> </trans-unit>
+23 -19
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Autorizzazioni predefinite</target> <target state="translated">Autorizzazioni predefinite</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> Le impostazioni si applicano a questo account utente per gli oggetti (tag, regole di posta, ecc. ma non documenti) creati tramite l'interfaccia utente web. </target> <target state="translated"> Le impostazioni si applicano a questo account utente per oggetti (Tag, Regole postali, ecc.) creati tramite l'interfaccia utente web. Queste impostazioni non sono applicabili ai documenti. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="final">Pulisci</target> <target state="final">Pulisci</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Sì</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Filtra per proprietario</target> <target state="translated">Filtra per proprietario</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Sì</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -9716,7 +9720,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context> <context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
<context context-type="linenumber">8</context> <context context-type="linenumber">8</context>
</context-group> </context-group>
<target state="needs-translation"><x id="INTERPOLATION" equiv-text="document().title | documentTitle }}"/> thumbnail</target> <target state="translated"><x id="INTERPOLATION" equiv-text="document().title | documentTitle }}"/> miniatura</target>
</trans-unit> </trans-unit>
<trans-unit id="2784168796433474565" datatype="html" approved="yes"> <trans-unit id="2784168796433474565" datatype="html" approved="yes">
<source>Filter by tag</source> <source>Filter by tag</source>
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Migrazione una tantum delle impostazioni al database completata con successo!</target> <target state="translated">Migrazione una tantum delle impostazioni al database completata con successo!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Impossibile migrare le impostazioni nel database. Prova a salvarle manualmente.</target> <target state="translated">Impossibile migrare le impostazioni nel database. Prova a salvarle manualmente.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Puoi riavviare il tour dalla pagina delle impostazioni.</target> <target state="translated">Puoi riavviare il tour dalla pagina delle impostazioni.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">デフォルト権限</target> <target state="translated">デフォルト権限</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> 設定はWeb UI 経由で作成されたオブジェクト (タグ、メール ルールなど、ドキュメントは除く) に対してこのユーザー アカウントに適用されます。 </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">解除</target> <target state="translated">解除</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">はい</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">所有者で絞り込む</target> <target state="translated">所有者で絞り込む</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">はい</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12770,7 +12774,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">データベースへのワンタイム設定移行が正常に完了しました!</target> <target state="translated">データベースへのワンタイム設定移行が正常に完了しました!</target>
</trans-unit> </trans-unit>
@@ -12778,7 +12782,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">データベースに設定を移行できません。手動で保存してみてください。</target> <target state="translated">データベースに設定を移行できません。手動で保存してみてください。</target>
</trans-unit> </trans-unit>
@@ -12786,7 +12790,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">設定ページからツアーを再開することができます</target> <target state="translated">設定ページからツアーを再開することができます</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">기본 권한</target> <target state="translated">기본 권한</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> 이 사용자 계정에는 웹 UI를 통해 만든 개체(문서가 아닌 태그, 메일 규칙 등)에 대한 설정이 적용됩니다 </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">지우기</target> <target state="translated">지우기</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">예</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="needs-translation">Filter by owner</target> <target state="needs-translation">Filter by owner</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">예</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">데이터베이스에 대한 설정의 일회성 마이그레이션을 성공적으로 완료했습니다!</target> <target state="translated">데이터베이스에 대한 설정의 일회성 마이그레이션을 성공적으로 완료했습니다!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">설정을 데이터베이스로 마이그레이션할 수 없는 경우 수동으로 저장해 보세요.</target> <target state="translated">설정을 데이터베이스로 마이그레이션할 수 없는 경우 수동으로 저장해 보세요.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">나중에 설정 페이지에서 다시 둘러보기를 할 수 있습니다.</target> <target state="translated">나중에 설정 페이지에서 다시 둘러보기를 할 수 있습니다.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Standardberechtegungen</target> <target state="translated">Standardberechtegungen</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="final">Läschen</target> <target state="final">Läschen</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Jo</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="needs-translation">Filter by owner</target> <target state="needs-translation">Filter by owner</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Jo</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html" approved="yes"> <trans-unit id="3542042671420335679" datatype="html" approved="yes">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target> <target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target> <target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="needs-translation">You can restart the tour from the settings page.</target> <target state="needs-translation">You can restart the tour from the settings page.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="needs-translation">Default Permissions</target> <target state="needs-translation">Default Permissions</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Išvalyti</target> <target state="translated">Išvalyti</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Taip</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="needs-translation">Filter by owner</target> <target state="needs-translation">Filter by owner</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Taip</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Nustatymų perkėlimas į duomenų bazę sėkmingai atliktas!</target> <target state="translated">Nustatymų perkėlimas į duomenų bazę sėkmingai atliktas!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Nepavyko perkelti nustatymų į duomenų bazę, pabandykite išsaugoti rankiniu būdu.</target> <target state="translated">Nepavyko perkelti nustatymų į duomenų bazę, pabandykite išsaugoti rankiniu būdu.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Ekskursiją galite paleisti iš naujo nustatymų puslapyje.</target> <target state="translated">Ekskursiją galite paleisti iš naujo nustatymų puslapyje.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Noklusētās atļaujas</target> <target state="translated">Noklusētās atļaujas</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Notīrīt</target> <target state="translated">Notīrīt</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="needs-translation">Yes</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="needs-translation">Filter by owner</target> <target state="needs-translation">Filter by owner</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="needs-translation">Yes</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target> <target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target> <target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="needs-translation">You can restart the tour from the settings page.</target> <target state="needs-translation">You can restart the tour from the settings page.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="needs-translation">Default Permissions</target> <target state="needs-translation">Default Permissions</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="needs-translation">Clear</target> <target state="needs-translation">Clear</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="needs-translation">Yes</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="needs-translation">Filter by owner</target> <target state="needs-translation">Filter by owner</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="needs-translation">Yes</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target> <target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target> <target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="needs-translation">You can restart the tour from the settings page.</target> <target state="needs-translation">You can restart the tour from the settings page.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="needs-translation">Default Permissions</target> <target state="needs-translation">Default Permissions</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="needs-translation">Clear</target> <target state="needs-translation">Clear</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="needs-translation">Yes</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="needs-translation">Filter by owner</target> <target state="needs-translation">Filter by owner</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="needs-translation">Yes</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target> <target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target> <target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="needs-translation">You can restart the tour from the settings page.</target> <target state="needs-translation">You can restart the tour from the settings page.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Standaard rechten</target> <target state="translated">Standaard rechten</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> Instellingen zijn van toepassing op dit account voor objecten (tags, mailregels, enz., maar niet op documenten) die via de webinterface zijn aangemaakt. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="final">Leegmaken</target> <target state="final">Leegmaken</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Ja</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Filter op eigenaar</target> <target state="translated">Filter op eigenaar</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Ja</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html" approved="yes"> <trans-unit id="3542042671420335679" datatype="html" approved="yes">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12770,7 +12774,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Eenmalige migratie van instellingen naar de database is succesvol voltooid!</target> <target state="translated">Eenmalige migratie van instellingen naar de database is succesvol voltooid!</target>
</trans-unit> </trans-unit>
@@ -12778,7 +12782,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Kan instellingen niet migreren naar de database, probeer handmatig op te slaan.</target> <target state="translated">Kan instellingen niet migreren naar de database, probeer handmatig op te slaan.</target>
</trans-unit> </trans-unit>
@@ -12786,7 +12790,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Je kan de rondleiding herstarten vanaf de instellingen pagina.</target> <target state="translated">Je kan de rondleiding herstarten vanaf de instellingen pagina.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Standardtillatelser</target> <target state="translated">Standardtillatelser</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> Innstillingene gjelder denne brukerkontoen for objekter (Merker, postregler, etc. men ikke dokumenter) opprettet via webgrensesnittet. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Tøm</target> <target state="translated">Tøm</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Ja</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Filtrer etter eier</target> <target state="translated">Filtrer etter eier</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Ja</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Engangs migrering av innstillinger ble fullført til databasen!</target> <target state="translated">Engangs migrering av innstillinger ble fullført til databasen!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Kunne ikke overføre innstillinger til databasen, prøv å lagre manuelt.</target> <target state="translated">Kunne ikke overføre innstillinger til databasen, prøv å lagre manuelt.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Du kan starte omvisningen på nytt fra innstillingssiden.</target> <target state="translated">Du kan starte omvisningen på nytt fra innstillingssiden.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Domyślnie uprawnienia</target> <target state="translated">Domyślnie uprawnienia</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated">Ustawienia dotyczą tego konta użytkownika dla obiektów (tagów, reguł poczty itd., ale nie dokumentów) tworzonych przez interfejs webowy.</target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="final">Wyczyść</target> <target state="final">Wyczyść</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Tak</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Filtruj wg właściciela</target> <target state="translated">Filtruj wg właściciela</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Tak</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html" approved="yes"> <trans-unit id="3542042671420335679" datatype="html" approved="yes">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12770,7 +12774,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Pomyślnie zakończona jednorazowa migracja ustawień do bazy danych!</target> <target state="translated">Pomyślnie zakończona jednorazowa migracja ustawień do bazy danych!</target>
</trans-unit> </trans-unit>
@@ -12778,7 +12782,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Nie można przenieść ustawień do bazy danych, spróbuj zapisać ręcznie.</target> <target state="translated">Nie można przenieść ustawień do bazy danych, spróbuj zapisać ręcznie.</target>
</trans-unit> </trans-unit>
@@ -12786,7 +12790,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Możesz ponownie uruchomić przegląd aplikacji ze strony ustawień.</target> <target state="translated">Możesz ponownie uruchomić przegląd aplikacji ze strony ustawień.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Permissões Padrão</target> <target state="translated">Permissões Padrão</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> As configurações se aplicam a esta conta de usuário para objetos (Tags, Regras de Mail, etc. mas não para documentos) criados através da interface web. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="final">Limpar</target> <target state="final">Limpar</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Sim</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8201,18 +8217,6 @@ Erro ao enviar documentos por e-mail</target>
</context-group> </context-group>
<target state="translated">Filtrar por proprietário</target> <target state="translated">Filtrar por proprietário</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Sim</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html" approved="yes"> <trans-unit id="3542042671420335679" datatype="html" approved="yes">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12772,7 +12776,7 @@ Erro ao enviar documentos por e-mail</target>
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">A migração de configurações para o banco de dados foi concluída com sucesso!</target> <target state="translated">A migração de configurações para o banco de dados foi concluída com sucesso!</target>
</trans-unit> </trans-unit>
@@ -12780,7 +12784,7 @@ Erro ao enviar documentos por e-mail</target>
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Não foi possível migrar as configurações para o banco de dados, por favor tente salvar manualmente.</target> <target state="translated">Não foi possível migrar as configurações para o banco de dados, por favor tente salvar manualmente.</target>
</trans-unit> </trans-unit>
@@ -12788,7 +12792,7 @@ Erro ao enviar documentos por e-mail</target>
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Você pode reiniciar o tour na página de configurações..</target> <target state="translated">Você pode reiniciar o tour na página de configurações..</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Permissões predefinidas</target> <target state="translated">Permissões predefinidas</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated">As configurações se aplicam a esta conta de utilizador para objetos (Etiquetas, Regras de Mail, etc. mas não documentos) criados através da interface web.</target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="final">Limpar</target> <target state="final">Limpar</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Sim</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="needs-translation">Filter by owner</target> <target state="needs-translation">Filter by owner</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Sim</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html" approved="yes"> <trans-unit id="3542042671420335679" datatype="html" approved="yes">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Terminado com sucesso a migração única das definições na base de dados!</target> <target state="translated">Terminado com sucesso a migração única das definições na base de dados!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Incapaz de migrar as definições na base de dados, por favor, tente gravar manualmente.</target> <target state="translated">Incapaz de migrar as definições na base de dados, por favor, tente gravar manualmente.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Pode reiniciar o tutorial através da página das Configurações.</target> <target state="translated">Pode reiniciar o tutorial através da página das Configurações.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Permisiuni implicite</target> <target state="translated">Permisiuni implicite</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> Setările se aplică acestui cont de utilizator pentru obiecte (Etichete, Reguli de Mail etc. dar nu documente) create prin interfața web. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="final">Curăță</target> <target state="final">Curăță</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Da</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Filtrare după proprietar</target> <target state="translated">Filtrare după proprietar</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Da</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html" approved="yes"> <trans-unit id="3542042671420335679" datatype="html" approved="yes">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12770,7 +12774,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Migrarea unică a setărilor în baza de date a fost finalizată cu succes!</target> <target state="translated">Migrarea unică a setărilor în baza de date a fost finalizată cu succes!</target>
</trans-unit> </trans-unit>
@@ -12778,7 +12782,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Nu s-a putut migra setările în baza de date. Te rugăm să încerci să le salvezi manual.</target> <target state="translated">Nu s-a putut migra setările în baza de date. Te rugăm să încerci să le salvezi manual.</target>
</trans-unit> </trans-unit>
@@ -12786,7 +12790,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Poți reporni turul din pagina de setări.</target> <target state="translated">Poți reporni turul din pagina de setări.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Права по умолчанию</target> <target state="translated">Права по умолчанию</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated">Настройки применятся для этой учеткой записи к объектам (Теги, Почтовые правила, и т.д, но не к документам), созданным через Веб-интерфейс</target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="final">Очистить</target> <target state="final">Очистить</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Да</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Фильтровать по владельцу</target> <target state="translated">Фильтровать по владельцу</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Да</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html" approved="yes"> <trans-unit id="3542042671420335679" datatype="html" approved="yes">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12770,7 +12774,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Одноразовая миграция настроек в базу данных завершена!</target> <target state="translated">Одноразовая миграция настроек в базу данных завершена!</target>
</trans-unit> </trans-unit>
@@ -12778,7 +12782,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Не удается перенести настройки в базу данных, пожалуйста, попробуйте сохранить вручную.</target> <target state="translated">Не удается перенести настройки в базу данных, пожалуйста, попробуйте сохранить вручную.</target>
</trans-unit> </trans-unit>
@@ -12786,7 +12790,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Вы можете перезапустить тур со страницы настроек.</target> <target state="translated">Вы можете перезапустить тур со страницы настроек.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Predvolené povolenia</target> <target state="translated">Predvolené povolenia</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Vymazať</target> <target state="translated">Vymazať</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Áno</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Filtrovať podľa vlastníka</target> <target state="translated">Filtrovať podľa vlastníka</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Áno</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Migrácia nastavení do databázy úspešne ukončená!</target> <target state="translated">Migrácia nastavení do databázy úspešne ukončená!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Nie je možné migrovať nastavenia do databázy, skúste uložiť manuálne.</target> <target state="translated">Nie je možné migrovať nastavenia do databázy, skúste uložiť manuálne.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Sprievodcu môžete znova spustiť z nastavení.</target> <target state="translated">Sprievodcu môžete znova spustiť z nastavení.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Privzeta dovoljenja</target> <target state="translated">Privzeta dovoljenja</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> Nastavitve veljajo za ta uporabniški račun za objekte (oznake, pravila za pošto itd., ne pa za dokumente), ustvarjene prek spletnega uporabniškega vmesnika. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Počisti</target> <target state="translated">Počisti</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Da</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Filtriraj po lastniku</target> <target state="translated">Filtriraj po lastniku</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Da</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Uspešno opravljena enkratna migracija nastavitev v bazo!</target> <target state="translated">Uspešno opravljena enkratna migracija nastavitev v bazo!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Nastavitev ni mogoče preseliti v bazo podatkov, poskusite jih shraniti ročno.</target> <target state="translated">Nastavitev ni mogoče preseliti v bazo podatkov, poskusite jih shraniti ročno.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Ogled lahko ponovite v nastavitvah.</target> <target state="translated">Ogled lahko ponovite v nastavitvah.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1523,13 +1523,13 @@
</context-group> </context-group>
<target state="translated">[SQ] Default Permissions</target> <target state="translated">[SQ] Default Permissions</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3959,6 +3959,22 @@
</context-group> </context-group>
<target state="translated">[SQ] Clear</target> <target state="translated">[SQ] Clear</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">[SQ] Yes</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8201,18 +8217,6 @@
</context-group> </context-group>
<target state="translated">[SQ] Filter by owner</target> <target state="translated">[SQ] Filter by owner</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">[SQ] Yes</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12772,7 +12776,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">[SQ] Successfully completed one-time migratration of settings to the database!</target> <target state="translated">[SQ] Successfully completed one-time migratration of settings to the database!</target>
</trans-unit> </trans-unit>
@@ -12780,7 +12784,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">[SQ] Unable to migrate settings to the database, please try saving manually.</target> <target state="translated">[SQ] Unable to migrate settings to the database, please try saving manually.</target>
</trans-unit> </trans-unit>
@@ -12788,7 +12792,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">[SQ] You can restart the tour from the settings page.</target> <target state="translated">[SQ] You can restart the tour from the settings page.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Podrazumevane dozvole</target> <target state="translated">Podrazumevane dozvole</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> Podešavanja se primenjuju na ovaj korisnički nalog za objekte (oznake, pravila za poštu i slično, ali ne i za dokumente) kreirane putem veb interfejsa. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Očisti</target> <target state="translated">Očisti</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Da</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Filtriraj po vlasniku</target> <target state="translated">Filtriraj po vlasniku</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Da</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12772,7 +12776,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Uspešno završena jednokratna migracija podešavanja u bazu podataka!</target> <target state="translated">Uspešno završena jednokratna migracija podešavanja u bazu podataka!</target>
</trans-unit> </trans-unit>
@@ -12780,7 +12784,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Nije moguće preneti podešavanja u bazu podataka, pokušajte da ih sačuvate ručno.</target> <target state="translated">Nije moguće preneti podešavanja u bazu podataka, pokušajte da ih sačuvate ručno.</target>
</trans-unit> </trans-unit>
@@ -12788,7 +12792,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Možete ponovo da pokrenete obilazak sa stranice sa podešavanjima.</target> <target state="translated">Možete ponovo da pokrenete obilazak sa stranice sa podešavanjima.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Standardbehörigheter</target> <target state="translated">Standardbehörigheter</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="final">Rensa</target> <target state="final">Rensa</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Ja</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Filtrera efter ägare</target> <target state="translated">Filtrera efter ägare</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Ja</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html" approved="yes"> <trans-unit id="3542042671420335679" datatype="html" approved="yes">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Slutförde engångsmigreringen av inställningarna till databasen!</target> <target state="translated">Slutförde engångsmigreringen av inställningarna till databasen!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Kunde inte migrera inställningarna till databasen, försök spara manuellt.</target> <target state="translated">Kunde inte migrera inställningarna till databasen, försök spara manuellt.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Du kan starta om rundturen från inställningssidan.</target> <target state="translated">Du kan starta om rundturen från inställningssidan.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="needs-translation">Default Permissions</target> <target state="needs-translation">Default Permissions</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">ล้าง</target> <target state="translated">ล้าง</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">ใช่</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="needs-translation">Filter by owner</target> <target state="needs-translation">Filter by owner</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">ใช่</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target> <target state="needs-translation">Successfully completed one-time migratration of settings to the database!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target> <target state="needs-translation">Unable to migrate settings to the database, please try saving manually.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="needs-translation">You can restart the tour from the settings page.</target> <target state="needs-translation">You can restart the tour from the settings page.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Varsayılan İzinler</target> <target state="translated">Varsayılan İzinler</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> Ayarlar, web kullanıcı arayüzü üzerinden oluşturulan nesneler (Etiketler, Posta Kuralları vb., ancak belgeler hariç) bu kullanıcı hesabına uygulanır </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Temizle</target> <target state="translated">Temizle</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Evet</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8202,18 +8218,6 @@ tüm <x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/> krite
</context-group> </context-group>
<target state="translated">Sahibine göre filtrele</target> <target state="translated">Sahibine göre filtrele</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Evet</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12772,7 +12776,7 @@ tüm <x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/> krite
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Ayarların veritabanına tek seferlik taşıma işlemi başarıyla tamamlandı!</target> <target state="translated">Ayarların veritabanına tek seferlik taşıma işlemi başarıyla tamamlandı!</target>
</trans-unit> </trans-unit>
@@ -12780,7 +12784,7 @@ tüm <x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/> krite
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Ayarları veritabanına taşıyamıyoruz, lütfen manuel olarak kaydetmeyi deneyin.</target> <target state="translated">Ayarları veritabanına taşıyamıyoruz, lütfen manuel olarak kaydetmeyi deneyin.</target>
</trans-unit> </trans-unit>
@@ -12788,7 +12792,7 @@ tüm <x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/> krite
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Ayarlar sayfasından turu yeniden başlatabilirsiniz.</target> <target state="translated">Ayarlar sayfasından turu yeniden başlatabilirsiniz.</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">Типові дозволи</target> <target state="translated">Типові дозволи</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">Очистити</target> <target state="translated">Очистити</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Так</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">Фільтрувати за власником</target> <target state="translated">Фільтрувати за власником</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">Так</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">Успішно завершено одноразову міграцію параметрів до бази даних!</target> <target state="translated">Успішно завершено одноразову міграцію параметрів до бази даних!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">Не вдається перенести налаштування в базу даних, спробуйте зберегти вручну.</target> <target state="translated">Не вдається перенести налаштування в базу даних, спробуйте зберегти вручну.</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">Ви можете пройти знайомство ще раз зі сторінки налаштувань.</target> <target state="translated">Ви можете пройти знайомство ще раз зі сторінки налаштувань.</target>
</trans-unit> </trans-unit>
+22 -20
View File
@@ -1522,15 +1522,13 @@
</context-group> </context-group>
<target state="final">Phân quyền mặc định</target> <target state="final">Phân quyền mặc định</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html" approved="yes"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="final"> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
Cài đặt áp dụng cho tài khoản người dùng này cho các đối tượng (thẻ, quy tắc thư, v.v. nhưng không phải tài liệu) được tạo thông qua giao diện người dùng web.
</target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html" approved="yes"> <trans-unit id="4292903881380648974" datatype="html" approved="yes">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3978,6 +3976,22 @@
</context-group> </context-group>
<target state="final">Xóa bỏ</target> <target state="final">Xóa bỏ</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Đúng</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html" approved="yes"> <trans-unit id="7515883357904500238" datatype="html" approved="yes">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8248,18 +8262,6 @@
</context-group> </context-group>
<target state="final">Lọc theo chủ sở hữu</target> <target state="final">Lọc theo chủ sở hữu</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html" approved="yes">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="final">Đúng</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html" approved="yes"> <trans-unit id="3542042671420335679" datatype="html" approved="yes">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12907,7 +12909,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="final">quá trình cập nhật dữ liệu cấu hình</target> <target state="final">quá trình cập nhật dữ liệu cấu hình</target>
</trans-unit> </trans-unit>
@@ -12915,7 +12917,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="final">cập nhật dữ liệu cấu hình</target> <target state="final">cập nhật dữ liệu cấu hình</target>
</trans-unit> </trans-unit>
@@ -12923,7 +12925,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="final">khởi động lại hướng dẫn nhanh</target> <target state="final">khởi động lại hướng dẫn nhanh</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">默认权限</target> <target state="translated">默认权限</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> 对于通过网页界面创建的对象 (标签、邮件规则等,但不包括文档),这些设置将应用于此用户帐户。 </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">清除</target> <target state="translated">清除</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">是</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">按所有者筛选</target> <target state="translated">按所有者筛选</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">是</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">成功完成设置一次性迁移到数据库!</target> <target state="translated">成功完成设置一次性迁移到数据库!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">无法将设置迁移到数据库,请尝试手动保存。</target> <target state="translated">无法将设置迁移到数据库,请尝试手动保存。</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">你可以从设置页面重新开始导览。</target> <target state="translated">你可以从设置页面重新开始导览。</target>
</trans-unit> </trans-unit>
+22 -18
View File
@@ -1522,13 +1522,13 @@
</context-group> </context-group>
<target state="translated">預設權限</target> <target state="translated">預設權限</target>
</trans-unit> </trans-unit>
<trans-unit id="6544153565064275581" datatype="html"> <trans-unit id="1267490156259885391" datatype="html">
<source> Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI. </source> <source> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context> <context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context> <context context-type="linenumber">306,308</context>
</context-group> </context-group>
<target state="translated"> 此設定將套用至該使用者帳號,適用於透過網頁介面建立的項目(標籤、郵件規則等,但不包含文件)。 </target> <target state="needs-translation"> Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. </target>
</trans-unit> </trans-unit>
<trans-unit id="4292903881380648974" datatype="html"> <trans-unit id="4292903881380648974" datatype="html">
<source>Default Owner</source> <source>Default Owner</source>
@@ -3958,6 +3958,22 @@
</context-group> </context-group>
<target state="translated">清除</target> <target state="translated">清除</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/confirm-button/confirm-button.component.html</context>
<context context-type="linenumber">20</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">是</target>
</trans-unit>
<trans-unit id="7515883357904500238" datatype="html"> <trans-unit id="7515883357904500238" datatype="html">
<source>Are you sure?</source> <source>Are you sure?</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -8200,18 +8216,6 @@
</context-group> </context-group>
<target state="translated">以擁有者篩選</target> <target state="translated">以擁有者篩選</target>
</trans-unit> </trans-unit>
<trans-unit id="2807800733729323332" datatype="html">
<source>Yes</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
<context context-type="linenumber">386</context>
</context-group>
<target state="translated">是</target>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html"> <trans-unit id="3542042671420335679" datatype="html">
<source>No</source> <source>No</source>
<context-group purpose="location"> <context-group purpose="location">
@@ -12771,7 +12775,7 @@
<source>Successfully completed one-time migratration of settings to the database!</source> <source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">636</context> <context context-type="linenumber">635</context>
</context-group> </context-group>
<target state="translated">設定值已成功移轉到資料庫!</target> <target state="translated">設定值已成功移轉到資料庫!</target>
</trans-unit> </trans-unit>
@@ -12779,7 +12783,7 @@
<source>Unable to migrate settings to the database, please try saving manually.</source> <source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">637</context> <context context-type="linenumber">636</context>
</context-group> </context-group>
<target state="translated">無法將設定遷移至資料庫,請嘗試手動儲存。</target> <target state="translated">無法將設定遷移至資料庫,請嘗試手動儲存。</target>
</trans-unit> </trans-unit>
@@ -12787,7 +12791,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">709</context> <context context-type="linenumber">708</context>
</context-group> </context-group>
<target state="translated">可以從設定頁面重新開始導覽。</target> <target state="translated">可以從設定頁面重新開始導覽。</target>
</trans-unit> </trans-unit>
View File
-108
View File
@@ -1,108 +0,0 @@
from __future__ import annotations
import importlib
import zipfile
# ZIP_ZSTANDARD exists only on Python 3.14+ (PEP 784). None elsewhere.
ZSTD: int | None = getattr(zipfile, "ZIP_ZSTANDARD", None)
# CLI choices are fixed across runtimes so argparse never hides zstd; runtime
# availability is enforced separately in compression_available().
COMPRESSION_CHOICES: tuple[str, ...] = (
"stored",
"deflated",
"bzip2",
"lzma",
"zstd",
)
# Method name -> zipfile compression constant (zstd only when supported).
COMPRESSION_METHODS: dict[str, int] = {
"stored": zipfile.ZIP_STORED,
"deflated": zipfile.ZIP_DEFLATED,
"bzip2": zipfile.ZIP_BZIP2,
"lzma": zipfile.ZIP_LZMA,
}
if ZSTD is not None:
COMPRESSION_METHODS["zstd"] = ZSTD
# Inclusive (min, max) level bounds per method; None => level not applicable.
# Verified on CPython 3.14.3.
#
# zstd's raw library bounds are (-131072, 22)
# (compression.zstd.CompressionParameter.compression_level.bounds()) — the
# minimum is an internal implementation constant (-ZSTD_TARGETLENGTH_MAX),
# not a meaningful distinct "level"; deeper negative values than -22 buy
# nothing over -22 in practice. We expose the conventional zstd CLI range
# instead of the raw library bounds.
LEVEL_BOUNDS: dict[str, tuple[int, int] | None] = {
"stored": None,
"deflated": (0, 9),
"bzip2": (1, 9),
"lzma": None,
"zstd": (-22, 22),
}
# zipfile compress_type id -> method name. 93 = current zstd id, 20 = legacy
# zstd id that zipfile can still read.
_COMPRESS_TYPE_TO_METHOD: dict[int, str] = {
zipfile.ZIP_STORED: "stored",
zipfile.ZIP_DEFLATED: "deflated",
zipfile.ZIP_BZIP2: "bzip2",
zipfile.ZIP_LZMA: "lzma",
93: "zstd",
20: "zstd",
}
def compression_available(method: str) -> bool:
"""Whether the running interpreter can actually use the given method."""
if method in ("stored", "deflated"):
# zlib is a hard CPython dependency; stored needs nothing.
return True
if method == "bzip2":
return _module_importable("bz2")
if method == "lzma":
return _module_importable("lzma")
if method == "zstd":
return ZSTD is not None and _module_importable("compression.zstd")
return False
def _module_importable(name: str) -> bool:
try:
importlib.import_module(name)
except ImportError:
return False
return True
def level_error(method: str, level: int | None) -> str | None:
"""Return a human message if (method, level) is invalid, else None."""
if level is None:
return None
bounds = LEVEL_BOUNDS[method]
if bounds is None:
return f"--zip-compression-level has no effect for '{method}'"
low, high = bounds
if not (low <= level <= high):
return (
f"--zip-compression-level for '{method}' must be between {low} and {high}"
)
return None
def compress_type_readable(compress_type: int) -> bool:
"""Whether this interpreter can decompress an entry of the given type."""
method = _COMPRESS_TYPE_TO_METHOD.get(compress_type)
if method is None:
return False
return compression_available(method)
def unreadable_method_names(compress_types: set[int]) -> set[str]:
"""Map a set of compress_type ids to human method names for error messages."""
names: set[str] = set()
for ct in compress_types:
names.add(_COMPRESS_TYPE_TO_METHOD.get(ct, f"method {ct}"))
return names
-353
View File
@@ -1,353 +0,0 @@
from __future__ import annotations
import abc
import hashlib
import json
import os
import shutil
import tempfile
import zipfile
from contextlib import AbstractContextManager
from contextlib import contextmanager
from pathlib import Path
from pathlib import PurePosixPath
from typing import TYPE_CHECKING
from django.conf import settings
from django.core.serializers.json import DjangoJSONEncoder
from documents.file_handling import delete_empty_directories
from documents.utils import compute_checksum
from documents.utils import copy_file_with_basic_stats
if TYPE_CHECKING:
from collections.abc import Iterator
from typing import TextIO
def _dumps(content: list | dict) -> str:
"""Serialize export JSON consistently across all sinks."""
return json.dumps(content, cls=DjangoJSONEncoder, indent=2, ensure_ascii=False)
class StreamingManifestWriter:
"""Incrementally writes a JSON array to a text handle, one record at a time.
Knows nothing about folders or zips: it writes the array framing and records
to whatever handle the sink's ``stream()`` yields. The sink owns the handle's
lifecycle (atomic rename, compare, spooling).
"""
def __init__(self, handle: TextIO) -> None:
self._file = handle
self._first = True
self._file.write("[")
def write_record(self, record: dict) -> None:
if not self._first:
self._file.write(",\n")
else:
self._first = False
self._file.write(_dumps(record))
def write_batch(self, records: list[dict]) -> None:
for record in records:
self.write_record(record)
def close(self) -> None:
"""Write the closing bracket. Does NOT close the handle (the sink owns it)."""
self._file.write("\n]")
class ExportSink(AbstractContextManager, abc.ABC):
"""Destination for a document export.
The command declares export contents via three verbs; the sink decides how to
persist each. ``arcname`` is always a relative POSIX path
(e.g. ``"manifest.json"``, ``"originals/foo.pdf"``).
Contract:
* At most one ``stream()`` open at a time (it is the manifest);
``add_file``/``add_json`` may be called while it is open.
* Context-manager: normal exit finalizes, an exception aborts. No partial or
failed run leaves a complete-looking artifact.
"""
@abc.abstractmethod
def add_file(
self,
source: Path,
arcname: str,
*,
checksum: str | None = None,
) -> None: ...
@abc.abstractmethod
def add_json(self, content: list | dict, arcname: str) -> None: ...
@abc.abstractmethod
def stream(self, arcname: str) -> AbstractContextManager[TextIO]: ...
def _open(self) -> None:
"""Hook called on context entry. Override as needed."""
@abc.abstractmethod
def _finalize(self) -> None:
"""Commit on clean exit."""
@abc.abstractmethod
def _abort(self) -> None:
"""Roll back on exception."""
def __enter__(self) -> ExportSink:
self._open()
return self
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
if exc_type is not None:
self._abort()
else:
self._finalize()
class DirectoryExportSink(ExportSink):
"""Writes loose files into a target directory, with incremental sync.
Owns the snapshot/skip/compare/prune machinery that used to live in the
command (``files_in_export_dir``, ``check_and_copy``, ``check_and_write_json``,
and the ``--delete`` pass).
"""
def __init__(
self,
target: Path,
*,
compare_checksums: bool,
compare_json: bool,
delete: bool,
) -> None:
self._target = target.resolve()
self._compare_checksums = compare_checksums
self._compare_json = compare_json
self._delete = delete
self._snapshot: set[Path] = set()
self._stream_open = False
def _open(self) -> None:
for x in self._target.glob("**/*"):
if x.is_file():
self._snapshot.add(x.resolve())
def add_file(
self,
source: Path,
arcname: str,
*,
checksum: str | None = None,
) -> None:
target = (self._target / arcname).resolve()
self._snapshot.discard(target)
perform_copy = False
if target.exists():
source_stat = source.stat()
target_stat = target.stat()
if self._compare_checksums and checksum:
perform_copy = compute_checksum(target) != checksum
elif (
source_stat.st_mtime != target_stat.st_mtime
or source_stat.st_size != target_stat.st_size
):
perform_copy = True
else:
perform_copy = True
if perform_copy:
target.parent.mkdir(parents=True, exist_ok=True)
copy_file_with_basic_stats(source, target)
@staticmethod
def _content_unchanged(target: Path, new_bytes: bytes) -> bool:
"""True if ``target`` already holds byte-identical content (BLAKE2b)."""
return (
hashlib.blake2b(target.read_bytes()).hexdigest()
== hashlib.blake2b(new_bytes).hexdigest()
)
def add_json(self, content: list | dict, arcname: str) -> None:
target = (self._target / arcname).resolve()
json_str = _dumps(content)
perform_write = True
if target in self._snapshot:
self._snapshot.discard(target)
if self._compare_json and self._content_unchanged(
target,
json_str.encode("utf-8"),
):
perform_write = False
if perform_write:
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text(json_str, encoding="utf-8")
@contextmanager
def stream(self, arcname: str) -> Iterator[TextIO]:
if self._stream_open:
raise RuntimeError("A stream is already open on this sink")
target = (self._target / arcname).resolve()
tmp = target.with_suffix(target.suffix + ".tmp")
target.parent.mkdir(parents=True, exist_ok=True)
handle = tmp.open("w", encoding="utf-8")
self._stream_open = True
try:
yield handle
except BaseException:
handle.close()
tmp.unlink(missing_ok=True)
raise
else:
handle.close()
self._commit_streamed_file(target, tmp)
finally:
self._stream_open = False
def _commit_streamed_file(self, target: Path, tmp: Path) -> None:
if target in self._snapshot:
self._snapshot.discard(target)
if self._compare_json and self._content_unchanged(
target,
tmp.read_bytes(),
):
tmp.unlink()
return
tmp.rename(target)
def _finalize(self) -> None:
if self._delete:
for f in self._snapshot:
f.unlink()
delete_empty_directories(f.parent, self._target)
def _abort(self) -> None:
# Folder mode is in-place/incremental: streamed .tmp files are already
# cleaned in stream(); leave everything else intact and skip the prune.
return None
class ZipExportSink(ExportSink):
"""Writes a single zip archive, produced atomically only on success.
Builds into ``<target>/<zip_name>.zip.tmp`` and renames to ``.zip`` on clean
finalize. The manifest stream is spooled to a temp file in SCRATCH_DIR and
added as an entry at finalize (a zip entry cannot be interleaved with others).
"""
def __init__(
self,
target: Path,
zip_name: str,
*,
delete: bool = False,
compression: int = zipfile.ZIP_DEFLATED,
compresslevel: int | None = None,
) -> None:
self._target = target.resolve()
self._zip_path = (self._target / zip_name).with_suffix(".zip")
self._tmp_path = self._zip_path.with_name(self._zip_path.name + ".tmp")
self._delete = delete
self._compression = compression
self._compresslevel = compresslevel
self._zip: zipfile.ZipFile | None = None
self._dirs: set[str] = set()
self._pending_manifest: tuple[Path, str] | None = None
self._stream_open = False
def _open(self) -> None:
settings.SCRATCH_DIR.mkdir(parents=True, exist_ok=True)
self._zip = zipfile.ZipFile(
self._tmp_path,
"w",
compression=self._compression,
compresslevel=self._compresslevel,
allowZip64=True,
)
def _ensure_dirs(self, arcname: str) -> None:
assert self._zip is not None
dir_arc = ""
for part in PurePosixPath(arcname).parts[:-1]:
dir_arc += f"{part}/"
if dir_arc not in self._dirs:
self._dirs.add(dir_arc)
self._zip.mkdir(dir_arc)
def add_file(
self,
source: Path,
arcname: str,
*,
checksum: str | None = None,
) -> None:
assert self._zip is not None
self._ensure_dirs(arcname)
self._zip.write(source, arcname=arcname)
def add_json(self, content: list | dict, arcname: str) -> None:
assert self._zip is not None
self._ensure_dirs(arcname)
self._zip.writestr(arcname, _dumps(content))
@contextmanager
def stream(self, arcname: str) -> Iterator[TextIO]:
if self._stream_open:
raise RuntimeError("A stream is already open on this sink")
settings.SCRATCH_DIR.mkdir(parents=True, exist_ok=True)
fd, tmp_name = tempfile.mkstemp(
dir=settings.SCRATCH_DIR,
prefix="export-manifest-",
suffix=".json",
)
tmp = Path(tmp_name)
handle = os.fdopen(fd, "w", encoding="utf-8")
self._stream_open = True
try:
yield handle
except BaseException:
handle.close()
tmp.unlink(missing_ok=True)
raise
else:
handle.close()
self._pending_manifest = (tmp, arcname)
finally:
self._stream_open = False
def _finalize(self) -> None:
assert self._zip is not None
if self._pending_manifest is not None:
tmp, arcname = self._pending_manifest
self._ensure_dirs(arcname)
self._zip.write(tmp, arcname=arcname)
tmp.unlink(missing_ok=True)
self._pending_manifest = None
self._zip.close()
self._zip = None
if self._delete:
self._wipe_destination()
self._tmp_path.replace(self._zip_path)
def _wipe_destination(self) -> None:
skip = {self._zip_path.resolve(), self._tmp_path.resolve()}
for item in self._target.glob("*"):
if item.resolve() in skip:
continue
if item.is_dir():
shutil.rmtree(item)
else:
item.unlink()
def _abort(self) -> None:
if self._zip is not None:
self._zip.close()
self._zip = None
self._tmp_path.unlink(missing_ok=True)
if self._pending_manifest is not None:
self._pending_manifest[0].unlink(missing_ok=True)
self._pending_manifest = None
+8 -2
View File
@@ -161,7 +161,9 @@ class ObjectFilter(Filter):
class InboxFilter(Filter): class InboxFilter(Filter):
def filter(self, qs, value): def filter(self, qs, value):
if value == "true": if value == "true":
return qs.filter(tags__is_inbox_tag=True) # A document can have more than one tag flagged as an inbox tag
# (nothing enforces uniqueness), so this join can multiply rows.
return qs.filter(tags__is_inbox_tag=True).distinct()
elif value == "false": elif value == "false":
return qs.exclude(tags__is_inbox_tag=True) return qs.exclude(tags__is_inbox_tag=True)
else: else:
@@ -268,6 +270,10 @@ class CustomFieldsFilter(Filter):
for _, option in enumerate(options): for _, option in enumerate(options):
if option.get("label").lower().find(value.lower()) != -1: if option.get("label").lower().find(value.lower()) != -1:
option_ids.extend([option.get("id")]) option_ids.extend([option.get("id")])
# A document with multiple custom field instances can match more
# than one of these OR-ed branches (or the same branch via
# different fields), each via its own join to custom_fields --
# dedupe explicitly rather than relying on the caller to.
return ( return (
qs.filter(custom_fields__field__name__icontains=value) qs.filter(custom_fields__field__name__icontains=value)
| qs.filter(custom_fields__value_text__icontains=value) | qs.filter(custom_fields__value_text__icontains=value)
@@ -280,7 +286,7 @@ class CustomFieldsFilter(Filter):
| qs.filter(custom_fields__value_document_ids__icontains=value) | qs.filter(custom_fields__value_document_ids__icontains=value)
| qs.filter(custom_fields__value_select__in=option_ids) | qs.filter(custom_fields__value_select__in=option_ids)
| qs.filter(custom_fields__value_long_text__icontains=value) | qs.filter(custom_fields__value_long_text__icontains=value)
) ).distinct()
else: else:
return qs return qs
@@ -1,4 +1,8 @@
import hashlib
import json
import os import os
import shutil
import tempfile
from itertools import islice from itertools import islice
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
@@ -15,6 +19,7 @@ from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core import serializers from django.core import serializers
from django.core.management.base import CommandError from django.core.management.base import CommandError
from django.core.serializers.json import DjangoJSONEncoder
from django.db import transaction from django.db import transaction
from django.utils import timezone from django.utils import timezone
from filelock import FileLock from filelock import FileLock
@@ -29,15 +34,7 @@ if TYPE_CHECKING:
if settings.AUDIT_LOG_ENABLED: if settings.AUDIT_LOG_ENABLED:
from auditlog.models import LogEntry from auditlog.models import LogEntry
from documents.export.compression import COMPRESSION_CHOICES from documents.file_handling import delete_empty_directories
from documents.export.compression import COMPRESSION_METHODS
from documents.export.compression import ZSTD
from documents.export.compression import compression_available
from documents.export.compression import level_error
from documents.export.sinks import DirectoryExportSink
from documents.export.sinks import ExportSink
from documents.export.sinks import StreamingManifestWriter
from documents.export.sinks import ZipExportSink
from documents.file_handling import generate_filename from documents.file_handling import generate_filename
from documents.management.commands.base import PaperlessCommand from documents.management.commands.base import PaperlessCommand
from documents.management.commands.mixins import CryptMixin from documents.management.commands.mixins import CryptMixin
@@ -63,6 +60,8 @@ from documents.settings import EXPORTER_ARCHIVE_NAME
from documents.settings import EXPORTER_FILE_NAME from documents.settings import EXPORTER_FILE_NAME
from documents.settings import EXPORTER_SHARE_LINK_BUNDLE_NAME from documents.settings import EXPORTER_SHARE_LINK_BUNDLE_NAME
from documents.settings import EXPORTER_THUMBNAIL_NAME from documents.settings import EXPORTER_THUMBNAIL_NAME
from documents.utils import compute_checksum
from documents.utils import copy_file_with_basic_stats
from paperless import version from paperless import version
from paperless.models import ApplicationConfiguration from paperless.models import ApplicationConfiguration
from paperless_mail.models import MailAccount from paperless_mail.models import MailAccount
@@ -85,6 +84,87 @@ def serialize_queryset_batched(
yield serializers.serialize("python", chunk) yield serializers.serialize("python", chunk)
class StreamingManifestWriter:
"""Incrementally writes a JSON array to a file, one record at a time.
Writes to <target>.tmp first; on close(), optionally BLAKE2b-compares
with the existing file (--compare-json) and renames or discards accordingly.
On exception, discard() deletes the tmp file and leaves the original intact.
"""
def __init__(
self,
path: Path,
*,
compare_json: bool = False,
files_in_export_dir: "set[Path] | None" = None,
) -> None:
self._path = path.resolve()
self._tmp_path = self._path.with_suffix(self._path.suffix + ".tmp")
self._compare_json = compare_json
self._files_in_export_dir: set[Path] = (
files_in_export_dir if files_in_export_dir is not None else set()
)
self._file = None
self._first = True
def open(self) -> None:
self._path.parent.mkdir(parents=True, exist_ok=True)
self._file = self._tmp_path.open("w", encoding="utf-8")
self._file.write("[")
self._first = True
def write_record(self, record: dict) -> None:
if not self._first:
self._file.write(",\n")
else:
self._first = False
self._file.write(
json.dumps(record, cls=DjangoJSONEncoder, indent=2, ensure_ascii=False),
)
def write_batch(self, records: list[dict]) -> None:
for record in records:
self.write_record(record)
def close(self) -> None:
if self._file is None:
return
self._file.write("\n]")
self._file.close()
self._file = None
self._finalize()
def discard(self) -> None:
if self._file is not None:
self._file.close()
self._file = None
if self._tmp_path.exists():
self._tmp_path.unlink()
def _finalize(self) -> None:
"""Compare with existing file (if --compare-json) then rename or discard tmp."""
if self._path in self._files_in_export_dir:
self._files_in_export_dir.remove(self._path)
if self._compare_json:
existing_hash = hashlib.blake2b(self._path.read_bytes()).hexdigest()
new_hash = hashlib.blake2b(self._tmp_path.read_bytes()).hexdigest()
if existing_hash == new_hash:
self._tmp_path.unlink()
return
self._tmp_path.rename(self._path)
def __enter__(self) -> "StreamingManifestWriter":
self.open()
return self
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
if exc_type is not None:
self.discard()
else:
self.close()
class Command(CryptMixin, PaperlessCommand): class Command(CryptMixin, PaperlessCommand):
help = ( help = (
"Decrypt and rename all files in our collection into a given target " "Decrypt and rename all files in our collection into a given target "
@@ -196,28 +276,6 @@ class Command(CryptMixin, PaperlessCommand):
help="Sets the export zip file name", help="Sets the export zip file name",
) )
parser.add_argument(
"--zip-compression",
choices=COMPRESSION_CHOICES,
default=None,
help=(
"Compression method for the export zip (requires --zip). "
"Default: deflated. 'zstd' requires Python 3.14+ on both the "
"exporting and importing machine."
),
)
parser.add_argument(
"--zip-compression-level",
type=int,
default=None,
help=(
"Compression level for the export zip (requires --zip). "
"deflated: 0-9, bzip2: 1-9, zstd: -22..22; ignored for "
"stored/lzma."
),
)
parser.add_argument( parser.add_argument(
"--data-only", "--data-only",
default=False, default=False,
@@ -256,13 +314,20 @@ class Command(CryptMixin, PaperlessCommand):
self.passphrase: str | None = options.get("passphrase") self.passphrase: str | None = options.get("passphrase")
self.batch_size: int = options["batch_size"] self.batch_size: int = options["batch_size"]
self.files_in_export_dir: set[Path] = set()
self.exported_files: set[str] = set() self.exported_files: set[str] = set()
if self.zip_export and (self.compare_checksums or self.compare_json): # If zipping, save the original target for later and
raise CommandError( # get a temporary directory for the target instead
"--compare-checksums and --compare-json have no effect when " temp_dir = None
"used with --zip", self.original_target = self.target
if self.zip_export:
settings.SCRATCH_DIR.mkdir(parents=True, exist_ok=True)
temp_dir = tempfile.TemporaryDirectory(
dir=settings.SCRATCH_DIR,
prefix="paperless-export",
) )
self.target = Path(temp_dir.name).resolve()
if not self.target.exists(): if not self.target.exists():
raise CommandError("That path doesn't exist") raise CommandError("That path doesn't exist")
@@ -273,55 +338,33 @@ class Command(CryptMixin, PaperlessCommand):
if not os.access(self.target, os.W_OK): if not os.access(self.target, os.W_OK):
raise CommandError("That path doesn't appear to be writable") raise CommandError("That path doesn't appear to be writable")
zip_compression: str | None = options["zip_compression"] try:
zip_compression_level: int | None = options["zip_compression_level"] # Prevent any ongoing changes in the documents
with FileLock(settings.MEDIA_LOCK):
self.dump()
if not self.zip_export and ( # We've written everything to the temporary directory in this case,
zip_compression is not None or zip_compression_level is not None # now make an archive in the original target, with all files stored
): if self.zip_export and temp_dir is not None:
raise CommandError( shutil.make_archive(
"--zip-compression and --zip-compression-level require --zip", self.original_target / options["zip_name"],
) format="zip",
root_dir=temp_dir.name,
compression_method = zip_compression or "deflated"
if self.zip_export:
if not compression_available(compression_method):
if compression_method == "zstd" and ZSTD is None:
raise CommandError(
"zstd compression requires Python 3.14 or newer",
) )
raise CommandError(
f"Compression method '{compression_method}' is not "
f"available on this Python runtime",
)
level_msg = level_error(compression_method, zip_compression_level)
if level_msg is not None:
raise CommandError(level_msg)
sink: ExportSink finally:
if self.zip_export: # Always cleanup the temporary directory, if one was created
sink = ZipExportSink( if self.zip_export and temp_dir is not None:
self.target, temp_dir.cleanup()
options["zip_name"],
delete=self.delete,
compression=COMPRESSION_METHODS[compression_method],
compresslevel=zip_compression_level,
)
else:
sink = DirectoryExportSink(
self.target,
compare_checksums=self.compare_checksums,
compare_json=self.compare_json,
delete=self.delete,
)
# Prevent any ongoing changes in the documents while exporting def dump(self) -> None:
with FileLock(settings.MEDIA_LOCK), sink: # 1. Take a snapshot of what files exist in the current export folder
self.dump(sink) for x in self.target.glob("**/*"):
if x.is_file():
self.files_in_export_dir.add(x.resolve())
def dump(self, sink: ExportSink) -> None: # 2. Create manifest, containing all correspondents, types, tags, storage paths
# 1. Create manifest, containing all correspondents, types, tags, storage # note, documents and ui_settings
# paths, note, documents and ui_settings
_excluded_usernames = ["consumer", "AnonymousUser"] _excluded_usernames = ["consumer", "AnonymousUser"]
manifest_key_to_object_query: dict[str, QuerySet[Any]] = { manifest_key_to_object_query: dict[str, QuerySet[Any]] = {
"correspondents": Correspondent.objects.all(), "correspondents": Correspondent.objects.all(),
@@ -384,9 +427,13 @@ class Command(CryptMixin, PaperlessCommand):
document_manifest: list[dict] = [] document_manifest: list[dict] = []
share_link_bundle_manifest: list[dict] = [] share_link_bundle_manifest: list[dict] = []
manifest_path = (self.target / "manifest.json").resolve()
with sink.stream("manifest.json") as handle: with StreamingManifestWriter(
writer = StreamingManifestWriter(handle) manifest_path,
compare_json=self.compare_json,
files_in_export_dir=self.files_in_export_dir,
) as writer:
with transaction.atomic(): with transaction.atomic():
for key, qs in manifest_key_to_object_query.items(): for key, qs in manifest_key_to_object_query.items():
if key == "documents": if key == "documents":
@@ -432,55 +479,84 @@ class Command(CryptMixin, PaperlessCommand):
) )
} }
# 2. Export files from each document # 3. Export files from each document
for document_dict in self.track( for index, document_dict in enumerate(
document_manifest, self.track(
description="Exporting documents...", document_manifest,
total=len(document_manifest), description="Exporting documents...",
total=len(document_manifest),
),
): ):
document = document_map[document_dict["pk"]] document = document_map[document_dict["pk"]]
# generate a unique filename, then the arcnames for its files # 3.1. generate a unique filename
base_name = self.generate_base_name(document) base_name = self.generate_base_name(document)
original_arc, thumbnail_arc, archive_arc = (
# 3.2. write filenames into manifest
original_target, thumbnail_target, archive_target = (
self.generate_document_targets(document, base_name, document_dict) self.generate_document_targets(document, base_name, document_dict)
) )
# 3.3. write files to target folder
if not self.data_only: if not self.data_only:
self.copy_document_files( self.copy_document_files(
document, document,
sink, original_target,
original_arc, thumbnail_target,
thumbnail_arc, archive_target,
archive_arc,
) )
if self.split_manifest: if self.split_manifest:
self._write_split_manifest(sink, document_dict, document, base_name) self._write_split_manifest(document_dict, document, base_name)
else: else:
writer.write_record(document_dict) writer.write_record(document_dict)
for bundle_dict in share_link_bundle_manifest: for bundle_dict in share_link_bundle_manifest:
bundle = share_link_bundle_map[bundle_dict["pk"]] bundle = share_link_bundle_map[bundle_dict["pk"]]
bundle_arc = self.generate_share_link_bundle_target(
bundle_target = self.generate_share_link_bundle_target(
bundle, bundle,
bundle_dict, bundle_dict,
) )
if not self.data_only and bundle_arc is not None:
self.copy_share_link_bundle_file(bundle, sink, bundle_arc) if not self.data_only and bundle_target is not None:
self.copy_share_link_bundle_file(bundle, bundle_target)
writer.write_record(bundle_dict) writer.write_record(bundle_dict)
writer.close() # 4.2 write version information to target folder
extra_metadata_path = (self.target / "metadata.json").resolve()
# 3. Write version (and crypto params) to metadata.json
# Django stores most crypto values in the field itself; we store
# them once here for the whole export
metadata: dict[str, str | int | dict[str, str | int]] = { metadata: dict[str, str | int | dict[str, str | int]] = {
"version": version.__full_version_str__, "version": version.__full_version_str__,
} }
# 4.2.1 If needed, write the crypto values into the metadata
# Django stores most of these in the field itself, we store them once here
if self.passphrase: if self.passphrase:
metadata.update(self.get_crypt_params()) metadata.update(self.get_crypt_params())
sink.add_json(metadata, "metadata.json")
self.check_and_write_json(
metadata,
extra_metadata_path,
)
if self.delete:
# 5. Remove files which we did not explicitly export in this run
if not self.zip_export:
for f in self.files_in_export_dir:
f.unlink()
delete_empty_directories(
f.parent,
self.target,
)
else:
# 5. Remove anything in the original location (before moving the zip)
for item in self.original_target.glob("*"):
if item.is_dir():
shutil.rmtree(item)
else:
item.unlink()
def generate_base_name(self, document: Document) -> Path: def generate_base_name(self, document: Document) -> Path:
""" """
@@ -508,69 +584,73 @@ class Command(CryptMixin, PaperlessCommand):
document: Document, document: Document,
base_name: Path, base_name: Path,
document_dict: dict, document_dict: dict,
) -> tuple[str, str | None, str | None]: ) -> tuple[Path, Path | None, Path | None]:
""" """
Generates the relative POSIX arcnames for a document's original, thumbnail Generates the targets for a given document, including the original file, archive file and thumbnail (depending on settings).
and archive files (depending on settings), and records them in the manifest.
""" """
original_name = base_name original_name = base_name
if self.use_folder_prefix: if self.use_folder_prefix:
original_name = Path("originals") / original_name original_name = Path("originals") / original_name
original_arc = original_name.as_posix() original_target = (self.target / original_name).resolve()
document_dict[EXPORTER_FILE_NAME] = original_arc document_dict[EXPORTER_FILE_NAME] = str(original_name)
if not self.no_thumbnail: if not self.no_thumbnail:
thumbnail_name = base_name.parent / (base_name.stem + "-thumbnail.webp") thumbnail_name = base_name.parent / (base_name.stem + "-thumbnail.webp")
if self.use_folder_prefix: if self.use_folder_prefix:
thumbnail_name = Path("thumbnails") / thumbnail_name thumbnail_name = Path("thumbnails") / thumbnail_name
thumbnail_arc = thumbnail_name.as_posix() thumbnail_target = (self.target / thumbnail_name).resolve()
document_dict[EXPORTER_THUMBNAIL_NAME] = thumbnail_arc document_dict[EXPORTER_THUMBNAIL_NAME] = str(thumbnail_name)
else: else:
thumbnail_arc = None thumbnail_target = None
if not self.no_archive and document.has_archive_version: if not self.no_archive and document.has_archive_version:
archive_name = base_name.parent / (base_name.stem + "-archive.pdf") archive_name = base_name.parent / (base_name.stem + "-archive.pdf")
if self.use_folder_prefix: if self.use_folder_prefix:
archive_name = Path("archive") / archive_name archive_name = Path("archive") / archive_name
archive_arc = archive_name.as_posix() archive_target = (self.target / archive_name).resolve()
document_dict[EXPORTER_ARCHIVE_NAME] = archive_arc document_dict[EXPORTER_ARCHIVE_NAME] = str(archive_name)
else: else:
archive_arc = None archive_target = None
return original_arc, thumbnail_arc, archive_arc return original_target, thumbnail_target, archive_target
def copy_document_files( def copy_document_files(
self, self,
document: Document, document: Document,
sink: ExportSink, original_target: Path,
original_arc: str, thumbnail_target: Path | None,
thumbnail_arc: str | None, archive_target: Path | None,
archive_arc: str | None,
) -> None: ) -> None:
""" """
Hands the document's files to the sink (original, thumbnail, archive). Copies files from the document storage location to the specified target location.
If the document is encrypted, the files are decrypted before copying them to the target location.
""" """
sink.add_file(document.source_path, original_arc, checksum=document.checksum) self.check_and_copy(
document.source_path,
document.checksum,
original_target,
)
if thumbnail_arc: if thumbnail_target:
sink.add_file(document.thumbnail_path, thumbnail_arc) self.check_and_copy(document.thumbnail_path, None, thumbnail_target)
if archive_arc: if archive_target:
if TYPE_CHECKING: if TYPE_CHECKING:
assert isinstance(document.archive_path, Path) assert isinstance(document.archive_path, Path)
sink.add_file( self.check_and_copy(
document.archive_path, document.archive_path,
archive_arc, document.archive_checksum,
checksum=document.archive_checksum, archive_target,
) )
def generate_share_link_bundle_target( def generate_share_link_bundle_target(
self, self,
bundle: ShareLinkBundle, bundle: ShareLinkBundle,
bundle_dict: dict, bundle_dict: dict,
) -> str | None: ) -> Path | None:
""" """
Generates the relative POSIX arcname for a share link bundle file, if any. Generates the export target for a share link bundle file, when present.
""" """
if not bundle.file_path: if not bundle.file_path:
return None return None
@@ -586,22 +666,25 @@ class Command(CryptMixin, PaperlessCommand):
bundle_dict["fields"]["file_path"] = portable_bundle_path.as_posix() bundle_dict["fields"]["file_path"] = portable_bundle_path.as_posix()
bundle_dict[EXPORTER_SHARE_LINK_BUNDLE_NAME] = export_bundle_path.as_posix() bundle_dict[EXPORTER_SHARE_LINK_BUNDLE_NAME] = export_bundle_path.as_posix()
return export_bundle_path.as_posix() return (self.target / export_bundle_path).resolve()
def copy_share_link_bundle_file( def copy_share_link_bundle_file(
self, self,
bundle: ShareLinkBundle, bundle: ShareLinkBundle,
sink: ExportSink, bundle_target: Path,
bundle_arc: str,
) -> None: ) -> None:
""" """
Hands a share link bundle ZIP to the sink. Copies a share link bundle ZIP into the export directory.
""" """
bundle_source_path = bundle.absolute_file_path bundle_source_path = bundle.absolute_file_path
if bundle_source_path is None: if bundle_source_path is None:
raise FileNotFoundError(f"Share link bundle {bundle.pk} has no file path") raise FileNotFoundError(f"Share link bundle {bundle.pk} has no file path")
sink.add_file(bundle_source_path, bundle_arc) self.check_and_copy(
bundle_source_path,
None,
bundle_target,
)
def _encrypt_record_inline(self, record: dict) -> None: def _encrypt_record_inline(self, record: dict) -> None:
"""Encrypt sensitive fields in a single record, if passphrase is set.""" """Encrypt sensitive fields in a single record, if passphrase is set."""
@@ -617,7 +700,6 @@ class Command(CryptMixin, PaperlessCommand):
def _write_split_manifest( def _write_split_manifest(
self, self,
sink: ExportSink,
document_dict: dict, document_dict: dict,
document: Document, document: Document,
base_name: Path, base_name: Path,
@@ -639,4 +721,81 @@ class Command(CryptMixin, PaperlessCommand):
manifest_name = base_name.with_name(f"{base_name.stem}-manifest.json") manifest_name = base_name.with_name(f"{base_name.stem}-manifest.json")
if self.use_folder_prefix: if self.use_folder_prefix:
manifest_name = Path("json") / manifest_name manifest_name = Path("json") / manifest_name
sink.add_json(content, manifest_name.as_posix()) manifest_name = (self.target / manifest_name).resolve()
manifest_name.parent.mkdir(parents=True, exist_ok=True)
self.check_and_write_json(content, manifest_name)
def check_and_write_json(
self,
content: list[dict] | dict,
target: Path,
) -> None:
"""
Writes the source content to the target json file.
If --compare-json arg was used, don't write to target file if
the file exists and checksum is identical to content checksum.
This preserves the file timestamps when no changes are made.
"""
target = target.resolve()
perform_write = True
if target in self.files_in_export_dir:
self.files_in_export_dir.remove(target)
if self.compare_json:
target_checksum = hashlib.blake2b(target.read_bytes()).hexdigest()
src_str = json.dumps(
content,
cls=DjangoJSONEncoder,
indent=2,
ensure_ascii=False,
)
src_checksum = hashlib.blake2b(src_str.encode("utf-8")).hexdigest()
if src_checksum == target_checksum:
perform_write = False
if perform_write:
target.write_text(
json.dumps(
content,
cls=DjangoJSONEncoder,
indent=2,
ensure_ascii=False,
),
encoding="utf-8",
)
def check_and_copy(
self,
source: Path,
source_checksum: str | None,
target: Path,
) -> None:
"""
Copies the source to the target, if target doesn't exist or the target doesn't seem to match
the source attributes
"""
target = target.resolve()
if target in self.files_in_export_dir:
self.files_in_export_dir.remove(target)
perform_copy = False
if target.exists():
source_stat = source.stat()
target_stat = target.stat()
if self.compare_checksums and source_checksum:
target_checksum = compute_checksum(target)
perform_copy = target_checksum != source_checksum
elif (
source_stat.st_mtime != target_stat.st_mtime
or source_stat.st_size != target_stat.st_size
):
perform_copy = True
else:
# Copy if it does not exist
perform_copy = True
if perform_copy:
target.parent.mkdir(parents=True, exist_ok=True)
copy_file_with_basic_stats(source, target)
@@ -32,8 +32,6 @@ from django.db.models.signals import post_save
from filelock import FileLock from filelock import FileLock
from guardian.shortcuts import clear_ct_cache from guardian.shortcuts import clear_ct_cache
from documents.export.compression import compress_type_readable
from documents.export.compression import unreadable_method_names
from documents.file_handling import create_source_path_directory from documents.file_handling import create_source_path_directory
from documents.management.commands.base import PaperlessCommand from documents.management.commands.base import PaperlessCommand
from documents.management.commands.mixins import CryptMixin from documents.management.commands.mixins import CryptMixin
@@ -453,20 +451,6 @@ class Command(CryptMixin, PaperlessCommand):
with tempfile.TemporaryDirectory() as tmp_dir: with tempfile.TemporaryDirectory() as tmp_dir:
if is_zipfile(self.source): if is_zipfile(self.source):
with ZipFile(self.source) as zf: with ZipFile(self.source) as zf:
unsupported = {
info.compress_type
for info in zf.infolist()
if not compress_type_readable(info.compress_type)
}
if unsupported:
names = sorted(unreadable_method_names(unsupported))
message = (
f"This archive uses compression this Python cannot "
f"read ({', '.join(names)})."
)
if "zstd" in names:
message += " zstd archives require Python 3.14+."
raise CommandError(message)
zf.extractall(tmp_dir) zf.extractall(tmp_dir)
self.source = Path(tmp_dir) self.source = Path(tmp_dir)
self._run_import() self._run_import()
+89 -28
View File
@@ -4,14 +4,14 @@ from django.contrib.auth.models import Group
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.db.models import Case
from django.db.models import Count from django.db.models import Count
from django.db.models import IntegerField from django.db.models import IntegerField
from django.db.models import OuterRef
from django.db.models import Q from django.db.models import Q
from django.db.models import QuerySet from django.db.models import QuerySet
from django.db.models import Subquery from django.db.models import Value
from django.db.models import When
from django.db.models.functions import Cast from django.db.models.functions import Cast
from django.db.models.functions import Coalesce
from guardian.core import ObjectPermissionChecker from guardian.core import ObjectPermissionChecker
from guardian.models import GroupObjectPermission from guardian.models import GroupObjectPermission
from guardian.models import UserObjectPermission from guardian.models import UserObjectPermission
@@ -204,20 +204,95 @@ def _permitted_document_ids(user):
).values_list("id", flat=True) ).values_list("id", flat=True)
def get_document_count_filter_for_user(user): def get_document_count_filter_for_user(user, related_name: str = "documents"):
""" """
Return the Q object used to filter document counts for the given user. Return the Q object used to filter document counts for the given user.
The filter is expressed as an ``id__in`` against a small subquery of permitted The filter is expressed as an ``id__in`` against a small subquery of permitted
document IDs to keep the generated SQL simple and avoid large OR clauses. document IDs to keep the generated SQL simple and avoid large OR clauses.
``related_name`` is the ORM path from the annotated model to Document (e.g.
``"documents"`` for Tag's direct M2M, or ``"fields__document"`` for CustomField,
which only reaches Document via the CustomFieldInstance through-model).
""" """
if getattr(user, "is_superuser", False): if getattr(user, "is_superuser", False):
# Superuser: no permission filtering needed # Superuser: no permission filtering needed
return Q(documents__deleted_at__isnull=True) return Q(**{f"{related_name}__deleted_at__isnull": True})
permitted_ids = _permitted_document_ids(user) permitted_ids = _permitted_document_ids(user)
return Q(documents__id__in=permitted_ids) return Q(**{f"{related_name}__id__in": permitted_ids})
def annotate_document_count_by_ids(
queryset: QuerySet[Any],
through_model: Any,
related_object_field: str,
document_ids: Any,
target_field: str = "document_id",
) -> QuerySet[Any]:
"""
Annotate a queryset with a document count for a relation to Document that
goes through an M2M/through-model table (e.g. Tag via
``Document.tags.through``, or CustomField via ``CustomFieldInstance``),
for an explicit, already-resolved set of document ids.
Counts are computed via a single, independent GROUP BY over the relation
table -- with the id filter expressed as a plain ``WHERE`` rather than an
aggregate ``FILTER`` -- then injected via ``Case``/``When``. This
deliberately avoids two slower alternatives found while building this:
- A per-outer-row correlated subquery (one execution per row of the
annotated queryset): fine at a handful of rows, catastrophic once the
queryset has hundreds/thousands of rows.
- ``Count(..., filter=Q(id__in=document_ids), distinct=True)`` applied
directly to the M2M relation: Postgres can fail to plan the ``id__in``
check as a semi-join and instead re-checks subquery membership once per
row of the (much larger) M2M join -- worse than the correlated subquery.
Aggregation is restricted to rows whose ``related_object_field`` is one of
``queryset``'s pks, so passing a subset (e.g. a handful of tag descendants)
doesn't pay the cost of counting for every row matching ``document_ids``.
Args:
queryset: base queryset to annotate (must contain pk)
through_model: model representing the relation (e.g., Document.tags.through
or CustomFieldInstance)
related_object_field: field on the relation pointing back to queryset pk
document_ids: the document ids to count against -- a concrete list/set,
or a simple (already resolved) queryset of ids. Callers
that need this filtered by a complex condition (e.g. a
permission check) should resolve it to a concrete list
first if the same ids will be reused across multiple
calls, rather than passing the complex queryset itself
into each -- see ``_get_selection_data_for_queryset``.
target_field: field on the relation pointing to Document id
"""
counts = (
through_model.objects.filter(
**{
f"{related_object_field}__in": queryset.values("pk"),
f"{target_field}__in": document_ids,
},
)
.values(related_object_field)
.annotate(c=Count(target_field, distinct=True))
)
counts_by_pk = {row[related_object_field]: row["c"] for row in counts}
if not counts_by_pk:
return queryset.annotate(
document_count=Value(0, output_field=IntegerField()),
)
return queryset.annotate(
document_count=Case(
*(When(pk=pk, then=Value(count)) for pk, count in counts_by_pk.items()),
default=Value(0),
output_field=IntegerField(),
),
)
def annotate_document_count_for_related_queryset( def annotate_document_count_for_related_queryset(
@@ -228,31 +303,17 @@ def annotate_document_count_for_related_queryset(
user: User | None = None, user: User | None = None,
) -> QuerySet[Any]: ) -> QuerySet[Any]:
""" """
Annotate a queryset with permissions-aware document counts using a subquery Same as ``annotate_document_count_by_ids``, but resolves the document ids
against a relation table. from the given user's view permissions rather than taking them directly.
Args:
queryset: base queryset to annotate (must contain pk)
through_model: model representing the relation (e.g., Document.tags.through
or CustomFieldInstance)
source_field: field on the relation pointing back to queryset pk
target_field: field on the relation pointing to Document id
user: the user for whom to filter permitted document ids
""" """
permitted_ids = _permitted_document_ids(user) return annotate_document_count_by_ids(
counts = ( queryset,
through_model.objects.filter( through_model=through_model,
**{ related_object_field=related_object_field,
related_object_field: OuterRef("pk"), document_ids=_permitted_document_ids(user),
f"{target_field}__in": permitted_ids, target_field=target_field,
},
)
.values(related_object_field)
.annotate(c=Count(target_field))
.values("c")
) )
return queryset.annotate(document_count=Coalesce(Subquery(counts[:1]), 0))
def get_objects_for_user_owner_aware( def get_objects_for_user_owner_aware(
+7 -1
View File
@@ -475,7 +475,13 @@ class TantivyBackend:
note_texts: list[str] = [] note_texts: list[str] = []
for note in document.notes.all(): for note in document.notes.all():
num_notes += 1 num_notes += 1
doc.add_json("notes", {"note": note.note, "user": note.user.username}) doc.add_json(
"notes",
{
"note": note.note,
"user": note.user.username if note.user else None,
},
)
note_texts.append(note.note) note_texts.append(note.note)
if note_texts: if note_texts:
doc.add_text("notes_text", " ".join(note_texts)) doc.add_text("notes_text", " ".join(note_texts))
+27 -8
View File
@@ -392,15 +392,34 @@ class OwnedObjectSerializer(
} }
def get_user_can_change(self, obj) -> bool: def get_user_can_change(self, obj) -> bool:
checker = ObjectPermissionChecker(self.user) if self.user is not None else None if obj.owner is None or obj.owner == self.user:
return ( return True
obj.owner is None if self.user is None:
or obj.owner == self.user return False
or ( if self.user.is_active and self.user.is_superuser:
self.user is not None # Mirrors guardian's own ObjectPermissionChecker.has_perm() shortcut --
and checker.has_perm(f"change_{obj.__class__.__name__.lower()}", obj) # superusers aren't necessarily granted explicit object permissions,
# so the batched context below would otherwise incorrectly say no.
return True
# Prefer the page-level batch computed by BulkPermissionMixin
# (get_serializer_context) over a fresh per-object guardian check,
# which would otherwise query the permission tables once per row.
users_change_perms = self.context.get("users_change_perms")
groups_change_perms = self.context.get("groups_change_perms")
if users_change_perms is not None and groups_change_perms is not None:
if self.user.pk in users_change_perms.get(obj.pk, []):
return True
user_group_ids = getattr(self, "_user_group_ids", None)
if user_group_ids is None:
user_group_ids = set(self.user.groups.values_list("id", flat=True))
self._user_group_ids = user_group_ids
return bool(
user_group_ids.intersection(groups_change_perms.get(obj.pk, [])),
) )
)
checker = ObjectPermissionChecker(self.user)
return checker.has_perm(f"change_{obj.__class__.__name__.lower()}", obj)
@staticmethod @staticmethod
def get_shared_object_pks(objects: Iterable): def get_shared_object_pks(objects: Iterable):
+11 -1
View File
@@ -1264,7 +1264,17 @@ def task_failure_handler(
"error_message": str(exception) if exception else "Unknown error", "error_message": str(exception) if exception else "Unknown error",
} }
if traceback: if traceback:
tb_str = "".join(_tb.format_tb(traceback)) # billiard/celery pass a pre-formatted string instead of a real
# traceback object when the worker process itself died (e.g.
# WorkerLostError from a SIGILL) since there's no live traceback
# to walk in that case.
tb_str = (
traceback
if isinstance(traceback, str)
else "".join(
_tb.format_tb(traceback),
)
)
result_data["traceback"] = tb_str[:5000] result_data["traceback"] = tb_str[:5000]
now = timezone.now() now = timezone.now()
@@ -1,190 +0,0 @@
import sys
import zipfile
import pytest
from documents.export import compression
class TestCompressionMethods:
def test_choices_always_include_zstd(self) -> None:
"""
GIVEN:
- The compression policy module's CLI choices list
WHEN:
- Read on any runtime
THEN:
- zstd is always present; availability is checked separately so
argparse never hides it based on the current Python version
"""
assert compression.COMPRESSION_CHOICES == (
"stored",
"deflated",
"bzip2",
"lzma",
"zstd",
)
@pytest.mark.parametrize(
("name", "constant"),
[
("stored", zipfile.ZIP_STORED),
("deflated", zipfile.ZIP_DEFLATED),
("bzip2", zipfile.ZIP_BZIP2),
("lzma", zipfile.ZIP_LZMA),
],
)
def test_method_maps_to_zipfile_constant(self, name: str, constant: int) -> None:
"""
GIVEN:
- A compression method name
WHEN:
- Looked up in COMPRESSION_METHODS
THEN:
- It maps to the matching zipfile compression constant
"""
assert compression.COMPRESSION_METHODS[name] == constant
def test_stored_and_deflated_always_available(self) -> None:
"""
GIVEN:
- The stored and deflated compression methods
WHEN:
- Checked with compression_available()
THEN:
- Both are always available (zlib is a hard CPython dependency)
"""
assert compression.compression_available("stored")
assert compression.compression_available("deflated")
def test_zstd_availability_tracks_runtime(self) -> None:
"""
GIVEN:
- The zstd compression method
WHEN:
- Checked with compression_available() on this runtime
THEN:
- Availability matches whether Python is 3.14+
"""
expected: bool = sys.version_info >= (3, 14)
assert compression.compression_available("zstd") == expected
class TestLevelError:
@pytest.mark.parametrize(
("method", "level"),
[
("deflated", 0),
("deflated", 9),
("bzip2", 1),
("bzip2", 9),
("zstd", -22),
("zstd", 22),
("deflated", None),
("stored", None),
],
)
def test_valid_levels_return_none(self, method: str, level: int | None) -> None:
"""
GIVEN:
- A method and a level within its valid bounds (or no level)
WHEN:
- Checked with level_error()
THEN:
- No error message is returned
"""
assert compression.level_error(method, level) is None
@pytest.mark.parametrize(
("method", "level"),
[
("deflated", 10),
("deflated", -1),
("bzip2", 0),
("bzip2", 10),
("zstd", -23),
("zstd", 23),
],
)
def test_out_of_range_levels_return_message(
self,
method: str,
level: int,
) -> None:
"""
GIVEN:
- A method and a level outside its valid bounds
WHEN:
- Checked with level_error()
THEN:
- An error message naming the valid range is returned
"""
msg: str | None = compression.level_error(method, level)
assert msg is not None
assert "between" in msg
@pytest.mark.parametrize("method", ["stored", "lzma"])
def test_level_on_levelless_method_is_rejected(self, method: str) -> None:
"""
GIVEN:
- A method that ignores compression level (stored, lzma)
WHEN:
- A level is passed to level_error() anyway
THEN:
- An error message noting the level has no effect is returned
"""
msg: str | None = compression.level_error(method, 5)
assert msg is not None
assert "no effect" in msg
class TestCompressTypeReadable:
@pytest.mark.parametrize("ct", [zipfile.ZIP_STORED, zipfile.ZIP_DEFLATED])
def test_stored_and_deflated_always_readable(self, ct: int) -> None:
"""
GIVEN:
- A stored or deflated compress_type id
WHEN:
- Checked with compress_type_readable()
THEN:
- It is always readable
"""
assert compression.compress_type_readable(ct)
def test_zstd_compress_type_readability_tracks_runtime(self) -> None:
"""
GIVEN:
- The current (93) and legacy (20) zstd compress_type ids
WHEN:
- Checked with compress_type_readable() on this runtime
THEN:
- Readability matches whether Python is 3.14+
"""
# 93 = ZIP_ZSTANDARD; 20 = legacy zstd method id (read-only)
expected: bool = sys.version_info >= (3, 14)
assert compression.compress_type_readable(93) == expected
assert compression.compress_type_readable(20) == expected
def test_unknown_compress_type_is_unreadable(self) -> None:
"""
GIVEN:
- An unrecognized compress_type id
WHEN:
- Checked with compress_type_readable()
THEN:
- It is reported as unreadable
"""
assert not compression.compress_type_readable(9999)
def test_unreadable_method_names_lists_methods(self) -> None:
"""
GIVEN:
- A set containing an unknown compress_type id
WHEN:
- Passed to unreadable_method_names()
THEN:
- It is reported generically as "method <id>"
"""
# An unknown method id maps to no name and is reported generically.
names: set[str] = compression.unreadable_method_names({9999})
assert names == {"method 9999"}
-332
View File
@@ -1,332 +0,0 @@
import io
import json
import os
import zipfile
from pathlib import Path
import pytest
import pytest_mock
from documents.export.sinks import DirectoryExportSink
from documents.export.sinks import ExportSink
from documents.export.sinks import StreamingManifestWriter
from documents.export.sinks import ZipExportSink
from documents.export.sinks import _dumps
@pytest.fixture()
def source_file(tmp_path: Path) -> Path:
src: Path = tmp_path / "src" / "doc.pdf"
src.parent.mkdir(parents=True)
src.write_bytes(b"PDF-CONTENT")
return src
class TestDumps:
def test_dumps_is_indented_unicode_json(self) -> None:
result: str = _dumps({"a": "é", "b": 1})
assert '"é"' in result # ensure_ascii=False keeps unicode literal
assert "\n" in result # indent=2 produces newlines
assert json.loads(result) == {"a": "é", "b": 1}
class TestStreamingManifestWriter:
def test_writes_json_array_of_records(self) -> None:
handle: io.StringIO = io.StringIO()
writer: StreamingManifestWriter = StreamingManifestWriter(handle)
writer.write_batch([{"pk": 1}, {"pk": 2}])
writer.write_record({"pk": 3})
writer.close()
assert json.loads(handle.getvalue()) == [{"pk": 1}, {"pk": 2}, {"pk": 3}]
def test_empty_manifest_is_valid_empty_array(self) -> None:
handle: io.StringIO = io.StringIO()
writer: StreamingManifestWriter = StreamingManifestWriter(handle)
writer.close()
assert json.loads(handle.getvalue()) == []
class TestDirectoryExportSink:
def test_add_file_copies_to_relative_arcname(
self,
tmp_path: Path,
source_file: Path,
) -> None:
target: Path = tmp_path / "out"
target.mkdir()
with DirectoryExportSink(
target,
compare_checksums=False,
compare_json=False,
delete=False,
) as sink:
sink.add_file(source_file, "originals/doc.pdf")
assert (target / "originals" / "doc.pdf").read_bytes() == b"PDF-CONTENT"
def test_add_json_writes_file(self, tmp_path: Path) -> None:
target: Path = tmp_path / "out"
target.mkdir()
with DirectoryExportSink(
target,
compare_checksums=False,
compare_json=False,
delete=False,
) as sink:
sink.add_json({"version": "x"}, "metadata.json")
assert json.loads((target / "metadata.json").read_text()) == {"version": "x"}
def test_stream_writes_manifest(self, tmp_path: Path) -> None:
target: Path = tmp_path / "out"
target.mkdir()
with DirectoryExportSink(
target,
compare_checksums=False,
compare_json=False,
delete=False,
) as sink:
with sink.stream("manifest.json") as handle:
writer: StreamingManifestWriter = StreamingManifestWriter(handle)
writer.write_record({"pk": 1})
writer.close()
assert json.loads((target / "manifest.json").read_text()) == [{"pk": 1}]
def test_add_file_skips_when_size_and_mtime_match(
self,
tmp_path: Path,
source_file: Path,
) -> None:
# Pre-existing target with identical size+mtime but DIFFERENT content:
# if add_file skips (no compare-checksums), the old content survives.
target: Path = tmp_path / "out"
target.mkdir()
existing: Path = target / "originals" / "doc.pdf"
existing.parent.mkdir(parents=True)
# Same byte length as the source but different content + matching mtime,
# so a size/mtime comparison treats it as unchanged and skips the copy.
existing.write_bytes(b"X" * len(b"PDF-CONTENT"))
stat = source_file.stat()
os.utime(existing, (stat.st_atime, stat.st_mtime))
with DirectoryExportSink(
target,
compare_checksums=False,
compare_json=False,
delete=False,
) as sink:
sink.add_file(source_file, "originals/doc.pdf", checksum="abc")
assert existing.read_bytes() == b"X" * len(b"PDF-CONTENT") # skipped
def test_add_file_recopies_when_compare_checksums_differ(
self,
tmp_path: Path,
source_file: Path,
) -> None:
target: Path = tmp_path / "out"
target.mkdir()
existing: Path = target / "originals" / "doc.pdf"
existing.parent.mkdir(parents=True)
existing.write_bytes(b"X" * len(b"PDF-CONTENT"))
stat = source_file.stat()
os.utime(existing, (stat.st_atime, stat.st_mtime))
with DirectoryExportSink(
target,
compare_checksums=True,
compare_json=False,
delete=False,
) as sink:
# wrong checksum forces recopy despite matching size/mtime
sink.add_file(source_file, "originals/doc.pdf", checksum="not-the-real-sum")
assert existing.read_bytes() == b"PDF-CONTENT" # recopied
def test_delete_prunes_unwritten_snapshot_files(
self,
tmp_path: Path,
source_file: Path,
) -> None:
target: Path = tmp_path / "out"
target.mkdir()
stale: Path = target / "stale.pdf"
stale.write_bytes(b"STALE")
with DirectoryExportSink(
target,
compare_checksums=False,
compare_json=False,
delete=True,
) as sink:
sink.add_file(source_file, "originals/doc.pdf")
assert not stale.exists()
assert (target / "originals" / "doc.pdf").exists()
def test_no_delete_keeps_unwritten_files(
self,
tmp_path: Path,
source_file: Path,
) -> None:
target: Path = tmp_path / "out"
target.mkdir()
stale: Path = target / "stale.pdf"
stale.write_bytes(b"STALE")
with DirectoryExportSink(
target,
compare_checksums=False,
compare_json=False,
delete=False,
) as sink:
sink.add_file(source_file, "originals/doc.pdf")
assert stale.exists()
class TestZipExportSink:
def test_round_trip_files_json_and_stream(
self,
tmp_path: Path,
source_file: Path,
) -> None:
target: Path = tmp_path / "out"
target.mkdir()
with ZipExportSink(target, "export", delete=False) as sink:
sink.add_file(source_file, "originals/doc.pdf")
sink.add_json({"version": "x"}, "metadata.json")
with sink.stream("manifest.json") as handle:
writer = StreamingManifestWriter(handle)
writer.write_record({"pk": 1})
writer.close()
zip_path: Path = target / "export.zip"
assert zip_path.exists()
assert not (target / "export.zip.tmp").exists()
with zipfile.ZipFile(zip_path) as zf:
names = set(zf.namelist())
assert {"originals/doc.pdf", "metadata.json", "manifest.json"} <= names
assert zf.read("originals/doc.pdf") == b"PDF-CONTENT"
assert json.loads(zf.read("manifest.json")) == [{"pk": 1}]
def test_nested_arcname_emits_directory_marker(
self,
tmp_path: Path,
source_file: Path,
) -> None:
target: Path = tmp_path / "out"
target.mkdir()
with ZipExportSink(target, "export", delete=False) as sink:
sink.add_file(source_file, "originals/doc.pdf")
with zipfile.ZipFile(target / "export.zip") as zf:
assert "originals/" in zf.namelist()
def test_flat_arcname_has_no_directory_markers(
self,
tmp_path: Path,
source_file: Path,
) -> None:
target: Path = tmp_path / "out"
target.mkdir()
with ZipExportSink(target, "export", delete=False) as sink:
sink.add_file(source_file, "doc.pdf")
with zipfile.ZipFile(target / "export.zip") as zf:
assert all(not n.endswith("/") for n in zf.namelist())
def test_exception_leaves_no_zip_and_no_tmp(
self,
tmp_path: Path,
source_file: Path,
) -> None:
target: Path = tmp_path / "out"
target.mkdir()
with pytest.raises(RuntimeError):
with ZipExportSink(target, "export", delete=False) as sink:
sink.add_file(source_file, "doc.pdf")
raise RuntimeError("boom")
assert not (target / "export.zip").exists()
assert not (target / "export.zip.tmp").exists()
def test_delete_wipes_destination_on_success(
self,
tmp_path: Path,
source_file: Path,
) -> None:
target: Path = tmp_path / "out"
target.mkdir()
(target / "preexisting.txt").write_text("old")
(target / "olddir").mkdir()
with ZipExportSink(target, "export", delete=True) as sink:
sink.add_file(source_file, "doc.pdf")
assert (target / "export.zip").exists()
assert not (target / "preexisting.txt").exists()
assert not (target / "olddir").exists()
def test_abort_with_delete_does_not_wipe_destination(
self,
tmp_path: Path,
source_file: Path,
) -> None:
target: Path = tmp_path / "out"
target.mkdir()
(target / "preexisting.txt").write_text("old")
with pytest.raises(RuntimeError):
with ZipExportSink(target, "export", delete=True) as sink:
sink.add_file(source_file, "doc.pdf")
raise RuntimeError("boom")
assert (target / "preexisting.txt").exists()
assert not (target / "export.zip").exists()
class TestZipExportSinkCompression:
@pytest.mark.parametrize(
("method", "constant"),
[
("stored", zipfile.ZIP_STORED),
("deflated", zipfile.ZIP_DEFLATED),
("bzip2", zipfile.ZIP_BZIP2),
("lzma", zipfile.ZIP_LZMA),
],
)
def test_compression_and_level_forwarded_to_zipfile(
self,
mocker: pytest_mock.MockerFixture,
tmp_path: Path,
method: str,
constant: int,
) -> None:
"""
GIVEN:
- A ZipExportSink constructed with a compression method and level
WHEN:
- The sink is opened
THEN:
- zipfile.ZipFile is constructed with those values forwarded
unchanged (whether ZipFile actually compresses is Python's own
contract, not ours, so this checks the call args, not a real
archive)
"""
target: Path = tmp_path / "out"
target.mkdir()
zip_cls = mocker.patch("documents.export.sinks.zipfile.ZipFile")
sink = ZipExportSink(target, "export", compression=constant, compresslevel=5)
sink._open()
zip_cls.assert_called_once_with(
mocker.ANY,
"w",
compression=constant,
compresslevel=5,
allowZip64=True,
)
class TestStreamContract:
@pytest.fixture(params=["dir", "zip"])
def sink(self, request: pytest.FixtureRequest, tmp_path: Path) -> ExportSink:
target: Path = tmp_path / "out"
target.mkdir()
if request.param == "dir":
return DirectoryExportSink(
target,
compare_checksums=False,
compare_json=False,
delete=False,
)
return ZipExportSink(target, "export", delete=False)
def test_second_concurrent_stream_is_rejected(self, sink: ExportSink) -> None:
with sink:
with sink.stream("manifest.json"):
with pytest.raises(RuntimeError, match="already open"):
with sink.stream("other.json"):
pass
@@ -844,6 +844,23 @@ class TestFieldHandling:
f"Expected 1, got {len(ids)}. Note content should be searchable via notes.note: prefix." f"Expected 1, got {len(ids)}. Note content should be searchable via notes.note: prefix."
) )
def test_notes_without_user_are_indexed(self, backend: TantivyBackend) -> None:
"""Notes whose user was deleted (SET_NULL) must not break indexing."""
doc = Document.objects.create(
title="Doc with orphaned note",
content="test",
checksum="NT2",
pk=81,
)
Note.objects.create(document=doc, note="Orphaned note", user=None)
backend.add_or_update(doc)
ids = backend.search_ids("notes.note:orphaned", user=None)
assert len(ids) == 1, (
f"Expected 1, got {len(ids)}. Notes without a user should still be indexed."
)
class TestHighlightHits: class TestHighlightHits:
"""Test highlight_hits returns proper HTML strings, not raw Snippet objects.""" """Test highlight_hits returns proper HTML strings, not raw Snippet objects."""
+113
View File
@@ -883,6 +883,62 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
results = response.data["results"] results = response.data["results"]
self.assertEqual(len(results), 3) self.assertEqual(len(results), 3)
def test_is_in_inbox_filter_no_duplicates_with_multiple_inbox_tags(self) -> None:
"""
GIVEN:
- A document tagged with two different inbox tags
WHEN:
- The document list is filtered by is_in_inbox=true
THEN:
- The document appears exactly once, not once per matching tag
"""
doc = Document.objects.create(title="doc", checksum="c1")
inbox_1 = Tag.objects.create(name="inbox1", is_inbox_tag=True)
inbox_2 = Tag.objects.create(name="inbox2", is_inbox_tag=True)
doc.tags.add(inbox_1, inbox_2)
response = self.client.get("/api/documents/?is_in_inbox=true")
self.assertEqual(response.status_code, status.HTTP_200_OK)
results = response.data["results"]
self.assertEqual(len(results), 1)
self.assertEqual(results[0]["id"], doc.id)
def test_custom_fields_icontains_filter_no_duplicates(self) -> None:
"""
GIVEN:
- A document with two custom field instances that both match the
same custom_fields__icontains search term
WHEN:
- The document list is filtered by custom_fields__icontains
THEN:
- The document appears exactly once, not once per matching field
"""
doc = Document.objects.create(title="doc", checksum="c1")
field_1 = CustomField.objects.create(
name="apple",
data_type=CustomField.FieldDataType.STRING,
)
field_2 = CustomField.objects.create(
name="apricot",
data_type=CustomField.FieldDataType.STRING,
)
CustomFieldInstance.objects.create(
document=doc,
field=field_1,
value_text="something",
)
CustomFieldInstance.objects.create(
document=doc,
field=field_2,
value_text="something else",
)
response = self.client.get("/api/documents/?custom_fields__icontains=ap")
self.assertEqual(response.status_code, status.HTTP_200_OK)
results = response.data["results"]
self.assertEqual(len(results), 1)
self.assertEqual(results[0]["id"], doc.id)
def test_custom_field_select_filter(self) -> None: def test_custom_field_select_filter(self) -> None:
""" """
GIVEN: GIVEN:
@@ -1291,6 +1347,63 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
self.assertEqual(selected_type["document_count"], 1) self.assertEqual(selected_type["document_count"], 1)
self.assertEqual(selected_storage_path["document_count"], 1) self.assertEqual(selected_storage_path["document_count"], 1)
def test_selection_data_document_counts_per_tag(self) -> None:
"""
GIVEN:
- Multiple tags with different numbers of matching documents
within the filtered set, including one with no matches
WHEN:
- Requesting the document list with include_selection_data=true
THEN:
- Each tag's document_count reflects only documents in the
filtered set, not the instance-wide count
"""
tag_a = Tag.objects.create(name="a")
tag_b = Tag.objects.create(name="b")
tag_unused = Tag.objects.create(name="unused")
custom_field = CustomField.objects.create(
name="cf1",
data_type=CustomField.FieldDataType.STRING,
)
doc1 = Document.objects.create(checksum="1", correspondent=None)
doc1.tags.add(tag_a)
doc2 = Document.objects.create(checksum="2")
doc2.tags.add(tag_a, tag_b)
doc3 = Document.objects.create(checksum="3")
doc3.tags.add(tag_b)
CustomFieldInstance.objects.create(
document=doc1,
field=custom_field,
value_text="x",
)
# Excluded from the filtered set entirely.
excluded = Document.objects.create(checksum="4")
excluded.tags.add(tag_a, tag_b, tag_unused)
response = self.client.get(
f"/api/documents/?id__in={doc1.id},{doc2.id},{doc3.id}"
"&include_selection_data=true",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
selection_data = response.data["selection_data"]
counts_by_tag = {
item["id"]: item["document_count"]
for item in selection_data["selected_tags"]
}
self.assertEqual(counts_by_tag[tag_a.id], 2)
self.assertEqual(counts_by_tag[tag_b.id], 2)
self.assertEqual(counts_by_tag[tag_unused.id], 0)
counts_by_field = {
item["id"]: item["document_count"]
for item in selection_data["selected_custom_fields"]
}
self.assertEqual(counts_by_field[custom_field.id], 1)
def test_statistics(self) -> None: def test_statistics(self) -> None:
doc1 = Document.objects.create( doc1 = Document.objects.create(
title="none1", title="none1",
@@ -568,6 +568,30 @@ class TestApiAuth(DirectoriesMixin, APITestCase):
self.assertNotIn("user_can_change", results[0]) self.assertNotIn("user_can_change", results[0])
self.assertNotIn("is_shared_by_requester", results[0]) self.assertNotIn("is_shared_by_requester", results[0])
def test_superuser_user_can_change_without_explicit_grant(self) -> None:
"""
A superuser has implicit change access to every document, even one
owned by someone else with no explicit guardian grant -- mirrors
guardian's own ObjectPermissionChecker.has_perm() superuser shortcut.
"""
superuser = User.objects.create_superuser(username="admin")
other_user = User.objects.create_user(username="user2")
Document.objects.create(
title="Test",
content="content",
checksum="1",
owner=other_user,
)
self.client.force_authenticate(superuser)
response = self.client.get("/api/documents/", format="json")
self.assertEqual(response.status_code, status.HTTP_200_OK)
results = response.json()["results"]
self.assertEqual(len(results), 1)
self.assertTrue(results[0]["user_can_change"])
@mock.patch("allauth.mfa.adapter.DefaultMFAAdapter.is_mfa_enabled") @mock.patch("allauth.mfa.adapter.DefaultMFAAdapter.is_mfa_enabled")
def test_basic_auth_mfa_enabled(self, mock_is_mfa_enabled) -> None: def test_basic_auth_mfa_enabled(self, mock_is_mfa_enabled) -> None:
""" """
+4 -190
View File
@@ -6,8 +6,6 @@ from datetime import timedelta
from io import StringIO from io import StringIO
from pathlib import Path from pathlib import Path
from unittest import mock from unittest import mock
from zipfile import ZIP_DEFLATED
from zipfile import ZIP_LZMA
from zipfile import ZipFile from zipfile import ZipFile
import pytest import pytest
@@ -428,7 +426,7 @@ class TestExportImport(
st_mtime_1 = (self.target / "manifest.json").stat().st_mtime st_mtime_1 = (self.target / "manifest.json").stat().st_mtime
with mock.patch( with mock.patch(
"documents.export.sinks.copy_file_with_basic_stats", "documents.management.commands.document_exporter.copy_file_with_basic_stats",
) as m: ) as m:
self._do_export() self._do_export()
m.assert_not_called() m.assert_not_called()
@@ -439,7 +437,7 @@ class TestExportImport(
Path(self.d1.source_path).touch() Path(self.d1.source_path).touch()
with mock.patch( with mock.patch(
"documents.export.sinks.copy_file_with_basic_stats", "documents.management.commands.document_exporter.copy_file_with_basic_stats",
) as m: ) as m:
self._do_export() self._do_export()
self.assertEqual(m.call_count, 1) self.assertEqual(m.call_count, 1)
@@ -466,7 +464,7 @@ class TestExportImport(
self.assertIsFile(self.target / "manifest.json") self.assertIsFile(self.target / "manifest.json")
with mock.patch( with mock.patch(
"documents.export.sinks.copy_file_with_basic_stats", "documents.management.commands.document_exporter.copy_file_with_basic_stats",
) as m: ) as m:
self._do_export() self._do_export()
m.assert_not_called() m.assert_not_called()
@@ -477,7 +475,7 @@ class TestExportImport(
self.d2.save() self.d2.save()
with mock.patch( with mock.patch(
"documents.export.sinks.copy_file_with_basic_stats", "documents.management.commands.document_exporter.copy_file_with_basic_stats",
) as m: ) as m:
self._do_export(compare_checksums=True) self._do_export(compare_checksums=True)
self.assertEqual(m.call_count, 1) self.assertEqual(m.call_count, 1)
@@ -1060,190 +1058,6 @@ class TestExportImport(
self.assertEqual(Document.objects.all().count(), 4) self.assertEqual(Document.objects.all().count(), 4)
def test_zip_with_compare_flags_raises(self) -> None:
"""
GIVEN:
- A request to export to a zip file
WHEN:
- --compare-checksums or --compare-json is also passed
THEN:
- A CommandError is raised (the flags are no-ops in zip mode)
"""
for flag in ("--compare-checksums", "--compare-json"):
with self.subTest(flag=flag):
with self.assertRaises(CommandError):
call_command(
"document_exporter",
self.target,
"--zip",
flag,
skip_checks=True,
)
def test_compression_flags_require_zip(self) -> None:
"""
GIVEN:
- A request to export without --zip
WHEN:
- --zip-compression or --zip-compression-level is passed anyway
THEN:
- A CommandError is raised (the flags are meaningless without --zip)
"""
for args in (
["--zip-compression", "lzma"],
["--zip-compression-level", "5"],
):
with self.assertRaises(CommandError):
call_command(
"document_exporter",
self.target,
*args,
skip_checks=True,
)
def test_zip_compression_level_out_of_range_raises(self) -> None:
"""
GIVEN:
- A request to export to a zip file
WHEN:
- --zip-compression-level is outside the chosen method's valid range
THEN:
- A CommandError is raised
"""
with self.assertRaises(CommandError):
call_command(
"document_exporter",
self.target,
"--zip",
"--zip-compression",
"deflated",
"--zip-compression-level",
"99",
skip_checks=True,
)
def test_zip_compression_level_rejected_for_stored(self) -> None:
"""
GIVEN:
- A request to export to a zip file with --zip-compression stored
WHEN:
- --zip-compression-level is also passed
THEN:
- A CommandError is raised (stored ignores level entirely)
"""
with self.assertRaises(CommandError):
call_command(
"document_exporter",
self.target,
"--zip",
"--zip-compression",
"stored",
"--zip-compression-level",
"5",
skip_checks=True,
)
def test_zip_compression_level_rejected_for_lzma(self) -> None:
"""
GIVEN:
- A request to export to a zip file with --zip-compression lzma
WHEN:
- --zip-compression-level is also passed
THEN:
- A CommandError is raised (lzma ignores level entirely)
"""
with self.assertRaises(CommandError):
call_command(
"document_exporter",
self.target,
"--zip",
"--zip-compression",
"lzma",
"--zip-compression-level",
"5",
skip_checks=True,
)
def test_zstd_unavailable_raises_friendly_error(self) -> None:
"""
GIVEN:
- A Python runtime without zstd support (< 3.14)
WHEN:
- --zip-compression zstd is requested
THEN:
- A CommandError naming the Python version requirement is raised
"""
with self.assertRaises(CommandError) as e:
call_command(
"document_exporter",
self.target,
"--zip",
"--zip-compression",
"zstd",
skip_checks=True,
)
self.assertIn("3.14", str(e.exception))
def test_zip_compression_flag_resolves_to_sink_constant(self) -> None:
"""
GIVEN:
- A request to export to a zip file with --zip-compression lzma
WHEN:
- The export runs
THEN:
- ZipExportSink is constructed with the resolved ZIP_LZMA constant
(whether zipfile actually compresses with the chosen method is
Python's own contract, and ZipExportSink's own tests already
cover the forwarding; what this command owns is resolving the
CLI string to the right constant, so assert that resolution
directly)
"""
with mock.patch(
"documents.management.commands.document_exporter.ZipExportSink",
) as sink_cls:
call_command(
"document_exporter",
self.target,
"--zip",
"--zip-compression",
"lzma",
skip_checks=True,
)
sink_cls.assert_called_once_with(
mock.ANY,
mock.ANY,
delete=False,
compression=ZIP_LZMA,
compresslevel=None,
)
def test_default_zip_compression_resolves_to_deflate(self) -> None:
"""
GIVEN:
- A request to export to a zip file with no --zip-compression flag
WHEN:
- The export runs
THEN:
- ZipExportSink is constructed with the default ZIP_DEFLATED
constant and compresslevel=None, matching pre-existing behavior
"""
with mock.patch(
"documents.management.commands.document_exporter.ZipExportSink",
) as sink_cls:
call_command(
"document_exporter",
self.target,
"--zip",
skip_checks=True,
)
sink_cls.assert_called_once_with(
mock.ANY,
mock.ANY,
delete=False,
compression=ZIP_DEFLATED,
compresslevel=None,
)
@pytest.mark.management @pytest.mark.management
class TestCryptExportImport( class TestCryptExportImport(
@@ -525,35 +525,6 @@ class TestCommandImport(
self.assertEqual(doc.tags.count(), 1) self.assertEqual(doc.tags.count(), 1)
self.assertEqual(doc.tags.first().name, "batch-flush-tag") self.assertEqual(doc.tags.first().name, "batch-flush-tag")
def test_import_rejects_unreadable_compression(self) -> None:
"""
GIVEN:
- A zip archive with an entry whose compression this Python can't read
WHEN:
- Import is attempted
THEN:
- A CommandError naming the issue is raised, before extraction
"""
import zipfile
from unittest import mock
archive = Path(self.dirs.scratch_dir) / "export.zip"
with zipfile.ZipFile(archive, "w") as zf:
zf.writestr("manifest.json", "[]")
with mock.patch(
"documents.management.commands.document_importer.compress_type_readable",
return_value=False,
):
with self.assertRaises(CommandError) as e:
call_command(
"document_importer",
str(archive),
"--no-progress-bar",
skip_checks=True,
)
self.assertIn("compression", str(e.exception))
@pytest.mark.management @pytest.mark.management
@pytest.mark.django_db @pytest.mark.django_db
+71 -30
View File
@@ -169,6 +169,7 @@ from documents.permissions import PaperlessAdminPermissions
from documents.permissions import PaperlessNotePermissions from documents.permissions import PaperlessNotePermissions
from documents.permissions import PaperlessObjectPermissions from documents.permissions import PaperlessObjectPermissions
from documents.permissions import ViewDocumentsPermissions from documents.permissions import ViewDocumentsPermissions
from documents.permissions import annotate_document_count_by_ids
from documents.permissions import annotate_document_count_for_related_queryset from documents.permissions import annotate_document_count_for_related_queryset
from documents.permissions import get_document_count_filter_for_user from documents.permissions import get_document_count_filter_for_user
from documents.permissions import get_objects_for_user_owner_aware from documents.permissions import get_objects_for_user_owner_aware
@@ -431,14 +432,12 @@ class BulkPermissionMixin:
This avoid fetching permissions object by object in database. This avoid fetching permissions object by object in database.
""" """
context = super().get_serializer_context() context = super().get_serializer_context()
try:
full_perms = get_boolean(
str(self.request.query_params.get("full_perms", "false")),
)
except ValueError:
full_perms = False
if not full_perms: if getattr(self, "action", None) != "list":
# Batching only pays off across a page of objects; for single-object
# actions (retrieve, update, ...) the per-object fallback in
# get_user_can_change()/_get_perms() is cheap and avoids scanning
# the whole queryset here.
return context return context
# Check which objects are being paginated # Check which objects are being paginated
@@ -484,7 +483,15 @@ class BulkPermissionMixin:
class PermissionsAwareDocumentCountMixin(BulkPermissionMixin, PassUserMixin): class PermissionsAwareDocumentCountMixin(BulkPermissionMixin, PassUserMixin):
"""Mixin to add document count to queryset, permissions-aware if needed""" """Mixin to add document count to queryset, permissions-aware if needed"""
# Default is simple relation path, override for through-table/count specialization. # Direct FK/M2M relation name from this model to Document, used for the
# cheap Count(filter=...) path (Correspondent, DocumentType, StoragePath).
document_count_related_name: str = "documents"
# Set both of these instead, for models that only reach Document through
# an M2M/through-model table (Tag, CustomField). A plain Count(filter=...)
# over such a relation is fine for a direct FK, but forces a much more
# expensive plan once an M2M bridge table is involved -- see
# annotate_document_count_for_related_queryset() for why.
document_count_through: type[Model] | None = None document_count_through: type[Model] | None = None
document_count_source_field: str | None = None document_count_source_field: str | None = None
@@ -500,12 +507,14 @@ class PermissionsAwareDocumentCountMixin(BulkPermissionMixin, PassUserMixin):
def get_document_count_filter(self): def get_document_count_filter(self):
request = getattr(self, "request", None) request = getattr(self, "request", None)
user = getattr(request, "user", None) if request else None user = getattr(request, "user", None) if request else None
return get_document_count_filter_for_user(user) return get_document_count_filter_for_user(
user,
related_name=self.document_count_related_name,
)
def get_queryset(self): def get_queryset(self):
base_qs = super().get_queryset() base_qs = super().get_queryset()
# Use optimized through-table counting when configured.
if self.document_count_through: if self.document_count_through:
user = getattr(getattr(self, "request", None), "user", None) user = getattr(getattr(self, "request", None), "user", None)
return annotate_document_count_for_related_queryset( return annotate_document_count_for_related_queryset(
@@ -515,10 +524,13 @@ class PermissionsAwareDocumentCountMixin(BulkPermissionMixin, PassUserMixin):
user=user, user=user,
) )
# Fallback: simple Count on relation with permission filter.
filter = self.get_document_count_filter() filter = self.get_document_count_filter()
return base_qs.annotate( return base_qs.annotate(
document_count=Count("documents", filter=filter), document_count=Count(
self.document_count_related_name,
filter=filter,
distinct=True,
),
) )
@@ -943,6 +955,7 @@ class EmailDocumentDetailSchema(EmailSerializer):
), ),
) )
class DocumentViewSet( class DocumentViewSet(
BulkPermissionMixin,
PassUserMixin, PassUserMixin,
RetrieveModelMixin, RetrieveModelMixin,
UpdateModelMixin, UpdateModelMixin,
@@ -980,42 +993,54 @@ class DocumentViewSet(
) )
def _get_selection_data_for_queryset(self, queryset): def _get_selection_data_for_queryset(self, queryset):
# Resolve once instead of once per model below. `queryset` can carry an
# arbitrarily expensive WHERE clause (user filters plus the permission
# filter); re-embedding it as a subquery inside 5 separate Count(...)
# calls forces the database to re-evaluate that whole thing 5 times, and
# -- for FK relations especially -- can defeat semi-join planning
# entirely at scale. A concrete id list is cheap to reuse.
# order_by() drops the default/user ordering -- irrelevant for a plain
# id list, but left in place it forces a sort over the full filtered
# set before the ids can even be collected.
document_ids = list(queryset.order_by().values_list("pk", flat=True))
correspondents = Correspondent.objects.annotate( correspondents = Correspondent.objects.annotate(
document_count=Count( document_count=Count(
"documents", "documents",
filter=Q(documents__in=queryset), filter=Q(documents__id__in=document_ids),
distinct=True,
),
)
tags = Tag.objects.annotate(
document_count=Count(
"documents",
filter=Q(documents__in=queryset),
distinct=True, distinct=True,
), ),
) )
document_types = DocumentType.objects.annotate( document_types = DocumentType.objects.annotate(
document_count=Count( document_count=Count(
"documents", "documents",
filter=Q(documents__in=queryset), filter=Q(documents__id__in=document_ids),
distinct=True, distinct=True,
), ),
) )
storage_paths = StoragePath.objects.annotate( storage_paths = StoragePath.objects.annotate(
document_count=Count( document_count=Count(
"documents", "documents",
filter=Q(documents__in=queryset), filter=Q(documents__id__in=document_ids),
distinct=True, distinct=True,
), ),
) )
custom_fields = CustomField.objects.annotate( # Tag and CustomField reach Document through an M2M/through-model table;
document_count=Count( # a plain Count(filter=...) there is a much more expensive plan than the
"fields__document", # FK relations above once the bridge table is large -- see
filter=Q(fields__document__in=queryset), # annotate_document_count_by_ids() for why.
distinct=True, tags = annotate_document_count_by_ids(
), Tag.objects.all(),
through_model=Document.tags.through,
related_object_field="tag_id",
document_ids=document_ids,
)
custom_fields = annotate_document_count_by_ids(
CustomField.objects.all(),
through_model=CustomFieldInstance,
related_object_field="field_id",
document_ids=document_ids,
) )
return { return {
"selected_correspondents": [ "selected_correspondents": [
{"id": t.id, "document_count": t.document_count} for t in correspondents {"id": t.id, "document_count": t.document_count} for t in correspondents
@@ -1051,9 +1076,16 @@ class DocumentViewSet(
.values("count"), .values("count"),
output_field=IntegerField(), output_field=IntegerField(),
) )
# No .distinct() here: nothing in this base queryset can produce
# duplicate document rows (select_related below is all FK-to-PK;
# permission filtering is a boolean id__in predicate, not a join).
# M2M-based filters that *do* introduce a join (e.g. tags__id__in)
# already call .distinct() themselves where they need it -- see
# ObjectFilter.filter(). A blanket .distinct() here forces the
# database to fully sort and dedupe every visible document before
# it can apply LIMIT, which is disastrous at scale.
return ( return (
Document.objects.filter(root_document__isnull=True) Document.objects.filter(root_document__isnull=True)
.distinct()
.order_by("-created", "-id") .order_by("-created", "-id")
.annotate(effective_content=Coalesce(latest_version_content, F("content"))) .annotate(effective_content=Coalesce(latest_version_content, F("content")))
.annotate(num_notes=Coalesce(note_count, 0)) .annotate(num_notes=Coalesce(note_count, 0))
@@ -2291,6 +2323,15 @@ class UnifiedSearchViewSet(DocumentViewSet):
return SearchResultSerializer return SearchResultSerializer
return DocumentSerializer return DocumentSerializer
def get_serializer_context(self):
if self._is_search_request():
# BulkPermissionMixin.get_serializer_context() (inherited via
# DocumentViewSet) assumes it's batching permissions for a page of
# real Document instances. Tantivy search results are SearchHit/
# dict-like objects instead, so skip straight past it here.
return super(BulkPermissionMixin, self).get_serializer_context()
return super().get_serializer_context()
def _get_active_search_params(self, request: Request | None = None) -> list[str]: def _get_active_search_params(self, request: Request | None = None) -> list[str]:
request = request or self.request request = request or self.request
return [ return [
+30 -30
View File
@@ -2,8 +2,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-22 15:44+0000\n" "POT-Creation-Date: 2026-07-23 19:21+0000\n"
"PO-Revision-Date: 2026-07-22 15:47\n" "PO-Revision-Date: 2026-07-23 19:23\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Afrikaans\n" "Language-Team: Afrikaans\n"
"Language: af_ZA\n" "Language: af_ZA\n"
@@ -21,39 +21,39 @@ msgstr ""
msgid "Documents" msgid "Documents"
msgstr "Dokumente" msgstr "Dokumente"
#: documents/filters.py:464 #: documents/filters.py:470
msgid "Value must be valid JSON." msgid "Value must be valid JSON."
msgstr "Waarde moet geldige JSON wees." msgstr "Waarde moet geldige JSON wees."
#: documents/filters.py:483 #: documents/filters.py:489
msgid "Invalid custom field query expression" msgid "Invalid custom field query expression"
msgstr "Ongeldige gepasmaakte veldnavraaguitdrukking" msgstr "Ongeldige gepasmaakte veldnavraaguitdrukking"
#: documents/filters.py:493 #: documents/filters.py:499
msgid "Invalid expression list. Must be nonempty." msgid "Invalid expression list. Must be nonempty."
msgstr "Ongeldige uitdrukking lys. Moet nie leeg wees nie." msgstr "Ongeldige uitdrukking lys. Moet nie leeg wees nie."
#: documents/filters.py:514 #: documents/filters.py:520
msgid "Invalid logical operator {op!r}" msgid "Invalid logical operator {op!r}"
msgstr "Ongeldige logiese uitdrukking {op!r}" msgstr "Ongeldige logiese uitdrukking {op!r}"
#: documents/filters.py:528 #: documents/filters.py:534
msgid "Maximum number of query conditions exceeded." msgid "Maximum number of query conditions exceeded."
msgstr "" msgstr ""
#: documents/filters.py:592 #: documents/filters.py:598
msgid "{name!r} is not a valid custom field." msgid "{name!r} is not a valid custom field."
msgstr "" msgstr ""
#: documents/filters.py:629 #: documents/filters.py:635
msgid "{data_type} does not support query expr {expr!r}." msgid "{data_type} does not support query expr {expr!r}."
msgstr "" msgstr ""
#: documents/filters.py:744 documents/models.py:136 #: documents/filters.py:750 documents/models.py:136
msgid "Maximum nesting depth exceeded." msgid "Maximum nesting depth exceeded."
msgstr "" msgstr ""
#: documents/filters.py:1061 #: documents/filters.py:1067
msgid "Custom field not found" msgid "Custom field not found"
msgstr "" msgstr ""
@@ -1338,48 +1338,48 @@ msgstr ""
msgid "workflow runs" msgid "workflow runs"
msgstr "" msgstr ""
#: documents/serialisers.py:503 documents/serialisers.py:855 #: documents/serialisers.py:522 documents/serialisers.py:874
#: documents/serialisers.py:2744 documents/views.py:297 documents/views.py:2500 #: documents/serialisers.py:2763 documents/views.py:298 documents/views.py:2541
#: paperless_mail/serialisers.py:155 #: paperless_mail/serialisers.py:155
msgid "Insufficient permissions." msgid "Insufficient permissions."
msgstr "" msgstr ""
#: documents/serialisers.py:691 #: documents/serialisers.py:710
msgid "Invalid color." msgid "Invalid color."
msgstr "Ongeldige kleur." msgstr "Ongeldige kleur."
#: documents/serialisers.py:2216 #: documents/serialisers.py:2235
#, python-format #, python-format
msgid "File type %(type)s not supported" msgid "File type %(type)s not supported"
msgstr "Lêertipe %(type)s word nie ondersteun nie" msgstr "Lêertipe %(type)s word nie ondersteun nie"
#: documents/serialisers.py:2260 #: documents/serialisers.py:2279
#, python-format #, python-format
msgid "Custom field id must be an integer: %(id)s" msgid "Custom field id must be an integer: %(id)s"
msgstr "" msgstr ""
#: documents/serialisers.py:2267 #: documents/serialisers.py:2286
#, python-format #, python-format
msgid "Custom field with id %(id)s does not exist" msgid "Custom field with id %(id)s does not exist"
msgstr "" msgstr ""
#: documents/serialisers.py:2284 documents/serialisers.py:2294 #: documents/serialisers.py:2303 documents/serialisers.py:2313
msgid "Custom fields must be a list of integers or an object mapping ids to values." msgid "Custom fields must be a list of integers or an object mapping ids to values."
msgstr "" msgstr ""
#: documents/serialisers.py:2289 #: documents/serialisers.py:2308
msgid "Some custom fields don't exist or were specified twice." msgid "Some custom fields don't exist or were specified twice."
msgstr "" msgstr ""
#: documents/serialisers.py:2436 #: documents/serialisers.py:2455
msgid "Invalid variable detected." msgid "Invalid variable detected."
msgstr "Ongeldige veranderlike bespeur." msgstr "Ongeldige veranderlike bespeur."
#: documents/serialisers.py:2800 #: documents/serialisers.py:2819
msgid "Duplicate document identifiers are not allowed." msgid "Duplicate document identifiers are not allowed."
msgstr "" msgstr ""
#: documents/serialisers.py:2830 documents/views.py:4459 #: documents/serialisers.py:2849 documents/views.py:4500
#, python-format #, python-format
msgid "Documents not found: %(ids)s" msgid "Documents not found: %(ids)s"
msgstr "" msgstr ""
@@ -1634,36 +1634,36 @@ msgstr ""
msgid "Unable to parse URI {value}" msgid "Unable to parse URI {value}"
msgstr "" msgstr ""
#: documents/views.py:290 documents/views.py:2497 #: documents/views.py:291 documents/views.py:2538
msgid "Invalid more_like_id" msgid "Invalid more_like_id"
msgstr "" msgstr ""
#: documents/views.py:1524 #: documents/views.py:1556
msgid "Invalid AI configuration." msgid "Invalid AI configuration."
msgstr "" msgstr ""
#: documents/views.py:1533 #: documents/views.py:1565
msgid "AI backend request timed out." msgid "AI backend request timed out."
msgstr "" msgstr ""
#: documents/views.py:2322 documents/views.py:2643 #: documents/views.py:2363 documents/views.py:2684
msgid "Specify only one of text, title_search, query, or more_like_id." msgid "Specify only one of text, title_search, query, or more_like_id."
msgstr "" msgstr ""
#: documents/views.py:4471 #: documents/views.py:4512
#, python-format #, python-format
msgid "Insufficient permissions to share document %(id)s." msgid "Insufficient permissions to share document %(id)s."
msgstr "" msgstr ""
#: documents/views.py:4517 #: documents/views.py:4558
msgid "Bundle is already being processed." msgid "Bundle is already being processed."
msgstr "" msgstr ""
#: documents/views.py:4578 #: documents/views.py:4619
msgid "The share link bundle is still being prepared. Please try again later." msgid "The share link bundle is still being prepared. Please try again later."
msgstr "" msgstr ""
#: documents/views.py:4588 #: documents/views.py:4629
msgid "The share link bundle is unavailable." msgid "The share link bundle is unavailable."
msgstr "" msgstr ""
+30 -30
View File
@@ -2,8 +2,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-22 15:44+0000\n" "POT-Creation-Date: 2026-07-23 19:21+0000\n"
"PO-Revision-Date: 2026-07-22 15:48\n" "PO-Revision-Date: 2026-07-23 19:23\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Amharic\n" "Language-Team: Amharic\n"
"Language: am_ET\n" "Language: am_ET\n"
@@ -21,39 +21,39 @@ msgstr ""
msgid "Documents" msgid "Documents"
msgstr "መዝገባት" msgstr "መዝገባት"
#: documents/filters.py:464 #: documents/filters.py:470
msgid "Value must be valid JSON." msgid "Value must be valid JSON."
msgstr "የሚሰራው እሴት \"JSON\" መሆን አለበት" msgstr "የሚሰራው እሴት \"JSON\" መሆን አለበት"
#: documents/filters.py:483 #: documents/filters.py:489
msgid "Invalid custom field query expression" msgid "Invalid custom field query expression"
msgstr "ልክ ያልሆነ የተወሰነ የቦታ መጠይቅ አገላለጽ" msgstr "ልክ ያልሆነ የተወሰነ የቦታ መጠይቅ አገላለጽ"
#: documents/filters.py:493 #: documents/filters.py:499
msgid "Invalid expression list. Must be nonempty." msgid "Invalid expression list. Must be nonempty."
msgstr "ልክ ያልሆነ የመግለጫ ዝርዝር። ባዶ መሆን የለበትም።" msgstr "ልክ ያልሆነ የመግለጫ ዝርዝር። ባዶ መሆን የለበትም።"
#: documents/filters.py:514 #: documents/filters.py:520
msgid "Invalid logical operator {op!r}" msgid "Invalid logical operator {op!r}"
msgstr "ልክ ያልሆነ የሎጂክ ኦፕሬተር {op!r}" msgstr "ልክ ያልሆነ የሎጂክ ኦፕሬተር {op!r}"
#: documents/filters.py:528 #: documents/filters.py:534
msgid "Maximum number of query conditions exceeded." msgid "Maximum number of query conditions exceeded."
msgstr "ከፍተኛው የጥያቄ ሁኔታዎች/መጠን ብዛት አልፏል።" msgstr "ከፍተኛው የጥያቄ ሁኔታዎች/መጠን ብዛት አልፏል።"
#: documents/filters.py:592 #: documents/filters.py:598
msgid "{name!r} is not a valid custom field." msgid "{name!r} is not a valid custom field."
msgstr "{name!r} ይሄ ታዐማኒነት ያለው ልማድ አይደለም።" msgstr "{name!r} ይሄ ታዐማኒነት ያለው ልማድ አይደለም።"
#: documents/filters.py:629 #: documents/filters.py:635
msgid "{data_type} does not support query expr {expr!r}." msgid "{data_type} does not support query expr {expr!r}."
msgstr "ጥያቄን አይደግፍም expr {expr!r}." msgstr "ጥያቄን አይደግፍም expr {expr!r}."
#: documents/filters.py:744 documents/models.py:136 #: documents/filters.py:750 documents/models.py:136
msgid "Maximum nesting depth exceeded." msgid "Maximum nesting depth exceeded."
msgstr "ከፍተኛው የጥገኝነት ጥልቀት አልፏል።" msgstr "ከፍተኛው የጥገኝነት ጥልቀት አልፏል።"
#: documents/filters.py:1061 #: documents/filters.py:1067
msgid "Custom field not found" msgid "Custom field not found"
msgstr "ይህ ልማድ አልተገኘም" msgstr "ይህ ልማድ አልተገኘም"
@@ -1338,48 +1338,48 @@ msgstr ""
msgid "workflow runs" msgid "workflow runs"
msgstr "" msgstr ""
#: documents/serialisers.py:503 documents/serialisers.py:855 #: documents/serialisers.py:522 documents/serialisers.py:874
#: documents/serialisers.py:2744 documents/views.py:297 documents/views.py:2500 #: documents/serialisers.py:2763 documents/views.py:298 documents/views.py:2541
#: paperless_mail/serialisers.py:155 #: paperless_mail/serialisers.py:155
msgid "Insufficient permissions." msgid "Insufficient permissions."
msgstr "" msgstr ""
#: documents/serialisers.py:691 #: documents/serialisers.py:710
msgid "Invalid color." msgid "Invalid color."
msgstr "" msgstr ""
#: documents/serialisers.py:2216 #: documents/serialisers.py:2235
#, python-format #, python-format
msgid "File type %(type)s not supported" msgid "File type %(type)s not supported"
msgstr "" msgstr ""
#: documents/serialisers.py:2260 #: documents/serialisers.py:2279
#, python-format #, python-format
msgid "Custom field id must be an integer: %(id)s" msgid "Custom field id must be an integer: %(id)s"
msgstr "" msgstr ""
#: documents/serialisers.py:2267 #: documents/serialisers.py:2286
#, python-format #, python-format
msgid "Custom field with id %(id)s does not exist" msgid "Custom field with id %(id)s does not exist"
msgstr "" msgstr ""
#: documents/serialisers.py:2284 documents/serialisers.py:2294 #: documents/serialisers.py:2303 documents/serialisers.py:2313
msgid "Custom fields must be a list of integers or an object mapping ids to values." msgid "Custom fields must be a list of integers or an object mapping ids to values."
msgstr "" msgstr ""
#: documents/serialisers.py:2289 #: documents/serialisers.py:2308
msgid "Some custom fields don't exist or were specified twice." msgid "Some custom fields don't exist or were specified twice."
msgstr "" msgstr ""
#: documents/serialisers.py:2436 #: documents/serialisers.py:2455
msgid "Invalid variable detected." msgid "Invalid variable detected."
msgstr "" msgstr ""
#: documents/serialisers.py:2800 #: documents/serialisers.py:2819
msgid "Duplicate document identifiers are not allowed." msgid "Duplicate document identifiers are not allowed."
msgstr "" msgstr ""
#: documents/serialisers.py:2830 documents/views.py:4459 #: documents/serialisers.py:2849 documents/views.py:4500
#, python-format #, python-format
msgid "Documents not found: %(ids)s" msgid "Documents not found: %(ids)s"
msgstr "" msgstr ""
@@ -1634,36 +1634,36 @@ msgstr ""
msgid "Unable to parse URI {value}" msgid "Unable to parse URI {value}"
msgstr "" msgstr ""
#: documents/views.py:290 documents/views.py:2497 #: documents/views.py:291 documents/views.py:2538
msgid "Invalid more_like_id" msgid "Invalid more_like_id"
msgstr "" msgstr ""
#: documents/views.py:1524 #: documents/views.py:1556
msgid "Invalid AI configuration." msgid "Invalid AI configuration."
msgstr "" msgstr ""
#: documents/views.py:1533 #: documents/views.py:1565
msgid "AI backend request timed out." msgid "AI backend request timed out."
msgstr "" msgstr ""
#: documents/views.py:2322 documents/views.py:2643 #: documents/views.py:2363 documents/views.py:2684
msgid "Specify only one of text, title_search, query, or more_like_id." msgid "Specify only one of text, title_search, query, or more_like_id."
msgstr "" msgstr ""
#: documents/views.py:4471 #: documents/views.py:4512
#, python-format #, python-format
msgid "Insufficient permissions to share document %(id)s." msgid "Insufficient permissions to share document %(id)s."
msgstr "" msgstr ""
#: documents/views.py:4517 #: documents/views.py:4558
msgid "Bundle is already being processed." msgid "Bundle is already being processed."
msgstr "" msgstr ""
#: documents/views.py:4578 #: documents/views.py:4619
msgid "The share link bundle is still being prepared. Please try again later." msgid "The share link bundle is still being prepared. Please try again later."
msgstr "" msgstr ""
#: documents/views.py:4588 #: documents/views.py:4629
msgid "The share link bundle is unavailable." msgid "The share link bundle is unavailable."
msgstr "" msgstr ""
+30 -30
View File
@@ -2,8 +2,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-22 15:44+0000\n" "POT-Creation-Date: 2026-07-23 19:21+0000\n"
"PO-Revision-Date: 2026-07-22 15:48\n" "PO-Revision-Date: 2026-07-23 19:23\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Arabic\n" "Language-Team: Arabic\n"
"Language: ar_SA\n" "Language: ar_SA\n"
@@ -21,39 +21,39 @@ msgstr ""
msgid "Documents" msgid "Documents"
msgstr "المستندات" msgstr "المستندات"
#: documents/filters.py:464 #: documents/filters.py:470
msgid "Value must be valid JSON." msgid "Value must be valid JSON."
msgstr "يجب أن تكون القيمة JSON." msgstr "يجب أن تكون القيمة JSON."
#: documents/filters.py:483 #: documents/filters.py:489
msgid "Invalid custom field query expression" msgid "Invalid custom field query expression"
msgstr "تعبير استعلام غير صالح للحقول المخصصة" msgstr "تعبير استعلام غير صالح للحقول المخصصة"
#: documents/filters.py:493 #: documents/filters.py:499
msgid "Invalid expression list. Must be nonempty." msgid "Invalid expression list. Must be nonempty."
msgstr "قائمة عبارة خاطئة." msgstr "قائمة عبارة خاطئة."
#: documents/filters.py:514 #: documents/filters.py:520
msgid "Invalid logical operator {op!r}" msgid "Invalid logical operator {op!r}"
msgstr "" msgstr ""
#: documents/filters.py:528 #: documents/filters.py:534
msgid "Maximum number of query conditions exceeded." msgid "Maximum number of query conditions exceeded."
msgstr "تجاوز الحد الأقصى لعدد شروط الاستعلام." msgstr "تجاوز الحد الأقصى لعدد شروط الاستعلام."
#: documents/filters.py:592 #: documents/filters.py:598
msgid "{name!r} is not a valid custom field." msgid "{name!r} is not a valid custom field."
msgstr "{name!r} حقل مخصص غير صالح." msgstr "{name!r} حقل مخصص غير صالح."
#: documents/filters.py:629 #: documents/filters.py:635
msgid "{data_type} does not support query expr {expr!r}." msgid "{data_type} does not support query expr {expr!r}."
msgstr "{data_type} لا يدعم تعبير الاستعلام {expr!r}." msgstr "{data_type} لا يدعم تعبير الاستعلام {expr!r}."
#: documents/filters.py:744 documents/models.py:136 #: documents/filters.py:750 documents/models.py:136
msgid "Maximum nesting depth exceeded." msgid "Maximum nesting depth exceeded."
msgstr "" msgstr ""
#: documents/filters.py:1061 #: documents/filters.py:1067
msgid "Custom field not found" msgid "Custom field not found"
msgstr "لم يتم العثور على حقل مخصص" msgstr "لم يتم العثور على حقل مخصص"
@@ -1338,48 +1338,48 @@ msgstr ""
msgid "workflow runs" msgid "workflow runs"
msgstr "" msgstr ""
#: documents/serialisers.py:503 documents/serialisers.py:855 #: documents/serialisers.py:522 documents/serialisers.py:874
#: documents/serialisers.py:2744 documents/views.py:297 documents/views.py:2500 #: documents/serialisers.py:2763 documents/views.py:298 documents/views.py:2541
#: paperless_mail/serialisers.py:155 #: paperless_mail/serialisers.py:155
msgid "Insufficient permissions." msgid "Insufficient permissions."
msgstr "" msgstr ""
#: documents/serialisers.py:691 #: documents/serialisers.py:710
msgid "Invalid color." msgid "Invalid color."
msgstr "لون خاطئ." msgstr "لون خاطئ."
#: documents/serialisers.py:2216 #: documents/serialisers.py:2235
#, python-format #, python-format
msgid "File type %(type)s not supported" msgid "File type %(type)s not supported"
msgstr "نوع الملف %(type)s غير مدعوم" msgstr "نوع الملف %(type)s غير مدعوم"
#: documents/serialisers.py:2260 #: documents/serialisers.py:2279
#, python-format #, python-format
msgid "Custom field id must be an integer: %(id)s" msgid "Custom field id must be an integer: %(id)s"
msgstr "" msgstr ""
#: documents/serialisers.py:2267 #: documents/serialisers.py:2286
#, python-format #, python-format
msgid "Custom field with id %(id)s does not exist" msgid "Custom field with id %(id)s does not exist"
msgstr "" msgstr ""
#: documents/serialisers.py:2284 documents/serialisers.py:2294 #: documents/serialisers.py:2303 documents/serialisers.py:2313
msgid "Custom fields must be a list of integers or an object mapping ids to values." msgid "Custom fields must be a list of integers or an object mapping ids to values."
msgstr "" msgstr ""
#: documents/serialisers.py:2289 #: documents/serialisers.py:2308
msgid "Some custom fields don't exist or were specified twice." msgid "Some custom fields don't exist or were specified twice."
msgstr "" msgstr ""
#: documents/serialisers.py:2436 #: documents/serialisers.py:2455
msgid "Invalid variable detected." msgid "Invalid variable detected."
msgstr "اكتشاف متغير خاطئ." msgstr "اكتشاف متغير خاطئ."
#: documents/serialisers.py:2800 #: documents/serialisers.py:2819
msgid "Duplicate document identifiers are not allowed." msgid "Duplicate document identifiers are not allowed."
msgstr "" msgstr ""
#: documents/serialisers.py:2830 documents/views.py:4459 #: documents/serialisers.py:2849 documents/views.py:4500
#, python-format #, python-format
msgid "Documents not found: %(ids)s" msgid "Documents not found: %(ids)s"
msgstr "" msgstr ""
@@ -1635,36 +1635,36 @@ msgstr ""
msgid "Unable to parse URI {value}" msgid "Unable to parse URI {value}"
msgstr "" msgstr ""
#: documents/views.py:290 documents/views.py:2497 #: documents/views.py:291 documents/views.py:2538
msgid "Invalid more_like_id" msgid "Invalid more_like_id"
msgstr "" msgstr ""
#: documents/views.py:1524 #: documents/views.py:1556
msgid "Invalid AI configuration." msgid "Invalid AI configuration."
msgstr "" msgstr ""
#: documents/views.py:1533 #: documents/views.py:1565
msgid "AI backend request timed out." msgid "AI backend request timed out."
msgstr "" msgstr ""
#: documents/views.py:2322 documents/views.py:2643 #: documents/views.py:2363 documents/views.py:2684
msgid "Specify only one of text, title_search, query, or more_like_id." msgid "Specify only one of text, title_search, query, or more_like_id."
msgstr "" msgstr ""
#: documents/views.py:4471 #: documents/views.py:4512
#, python-format #, python-format
msgid "Insufficient permissions to share document %(id)s." msgid "Insufficient permissions to share document %(id)s."
msgstr "" msgstr ""
#: documents/views.py:4517 #: documents/views.py:4558
msgid "Bundle is already being processed." msgid "Bundle is already being processed."
msgstr "" msgstr ""
#: documents/views.py:4578 #: documents/views.py:4619
msgid "The share link bundle is still being prepared. Please try again later." msgid "The share link bundle is still being prepared. Please try again later."
msgstr "" msgstr ""
#: documents/views.py:4588 #: documents/views.py:4629
msgid "The share link bundle is unavailable." msgid "The share link bundle is unavailable."
msgstr "" msgstr ""
+30 -30
View File
@@ -2,8 +2,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-22 15:44+0000\n" "POT-Creation-Date: 2026-07-23 19:21+0000\n"
"PO-Revision-Date: 2026-07-22 15:48\n" "PO-Revision-Date: 2026-07-23 19:23\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Belarusian\n" "Language-Team: Belarusian\n"
"Language: be_BY\n" "Language: be_BY\n"
@@ -21,39 +21,39 @@ msgstr ""
msgid "Documents" msgid "Documents"
msgstr "Дакументы" msgstr "Дакументы"
#: documents/filters.py:464 #: documents/filters.py:470
msgid "Value must be valid JSON." msgid "Value must be valid JSON."
msgstr "" msgstr ""
#: documents/filters.py:483 #: documents/filters.py:489
msgid "Invalid custom field query expression" msgid "Invalid custom field query expression"
msgstr "" msgstr ""
#: documents/filters.py:493 #: documents/filters.py:499
msgid "Invalid expression list. Must be nonempty." msgid "Invalid expression list. Must be nonempty."
msgstr "" msgstr ""
#: documents/filters.py:514 #: documents/filters.py:520
msgid "Invalid logical operator {op!r}" msgid "Invalid logical operator {op!r}"
msgstr "" msgstr ""
#: documents/filters.py:528 #: documents/filters.py:534
msgid "Maximum number of query conditions exceeded." msgid "Maximum number of query conditions exceeded."
msgstr "" msgstr ""
#: documents/filters.py:592 #: documents/filters.py:598
msgid "{name!r} is not a valid custom field." msgid "{name!r} is not a valid custom field."
msgstr "" msgstr ""
#: documents/filters.py:629 #: documents/filters.py:635
msgid "{data_type} does not support query expr {expr!r}." msgid "{data_type} does not support query expr {expr!r}."
msgstr "" msgstr ""
#: documents/filters.py:744 documents/models.py:136 #: documents/filters.py:750 documents/models.py:136
msgid "Maximum nesting depth exceeded." msgid "Maximum nesting depth exceeded."
msgstr "" msgstr ""
#: documents/filters.py:1061 #: documents/filters.py:1067
msgid "Custom field not found" msgid "Custom field not found"
msgstr "" msgstr ""
@@ -1338,48 +1338,48 @@ msgstr ""
msgid "workflow runs" msgid "workflow runs"
msgstr "" msgstr ""
#: documents/serialisers.py:503 documents/serialisers.py:855 #: documents/serialisers.py:522 documents/serialisers.py:874
#: documents/serialisers.py:2744 documents/views.py:297 documents/views.py:2500 #: documents/serialisers.py:2763 documents/views.py:298 documents/views.py:2541
#: paperless_mail/serialisers.py:155 #: paperless_mail/serialisers.py:155
msgid "Insufficient permissions." msgid "Insufficient permissions."
msgstr "" msgstr ""
#: documents/serialisers.py:691 #: documents/serialisers.py:710
msgid "Invalid color." msgid "Invalid color."
msgstr "Няправільны колер." msgstr "Няправільны колер."
#: documents/serialisers.py:2216 #: documents/serialisers.py:2235
#, python-format #, python-format
msgid "File type %(type)s not supported" msgid "File type %(type)s not supported"
msgstr "Тып файла %(type)s не падтрымліваецца" msgstr "Тып файла %(type)s не падтрымліваецца"
#: documents/serialisers.py:2260 #: documents/serialisers.py:2279
#, python-format #, python-format
msgid "Custom field id must be an integer: %(id)s" msgid "Custom field id must be an integer: %(id)s"
msgstr "" msgstr ""
#: documents/serialisers.py:2267 #: documents/serialisers.py:2286
#, python-format #, python-format
msgid "Custom field with id %(id)s does not exist" msgid "Custom field with id %(id)s does not exist"
msgstr "" msgstr ""
#: documents/serialisers.py:2284 documents/serialisers.py:2294 #: documents/serialisers.py:2303 documents/serialisers.py:2313
msgid "Custom fields must be a list of integers or an object mapping ids to values." msgid "Custom fields must be a list of integers or an object mapping ids to values."
msgstr "" msgstr ""
#: documents/serialisers.py:2289 #: documents/serialisers.py:2308
msgid "Some custom fields don't exist or were specified twice." msgid "Some custom fields don't exist or were specified twice."
msgstr "" msgstr ""
#: documents/serialisers.py:2436 #: documents/serialisers.py:2455
msgid "Invalid variable detected." msgid "Invalid variable detected."
msgstr "Выяўлена няправільная зменная." msgstr "Выяўлена няправільная зменная."
#: documents/serialisers.py:2800 #: documents/serialisers.py:2819
msgid "Duplicate document identifiers are not allowed." msgid "Duplicate document identifiers are not allowed."
msgstr "" msgstr ""
#: documents/serialisers.py:2830 documents/views.py:4459 #: documents/serialisers.py:2849 documents/views.py:4500
#, python-format #, python-format
msgid "Documents not found: %(ids)s" msgid "Documents not found: %(ids)s"
msgstr "" msgstr ""
@@ -1634,36 +1634,36 @@ msgstr ""
msgid "Unable to parse URI {value}" msgid "Unable to parse URI {value}"
msgstr "" msgstr ""
#: documents/views.py:290 documents/views.py:2497 #: documents/views.py:291 documents/views.py:2538
msgid "Invalid more_like_id" msgid "Invalid more_like_id"
msgstr "" msgstr ""
#: documents/views.py:1524 #: documents/views.py:1556
msgid "Invalid AI configuration." msgid "Invalid AI configuration."
msgstr "" msgstr ""
#: documents/views.py:1533 #: documents/views.py:1565
msgid "AI backend request timed out." msgid "AI backend request timed out."
msgstr "" msgstr ""
#: documents/views.py:2322 documents/views.py:2643 #: documents/views.py:2363 documents/views.py:2684
msgid "Specify only one of text, title_search, query, or more_like_id." msgid "Specify only one of text, title_search, query, or more_like_id."
msgstr "" msgstr ""
#: documents/views.py:4471 #: documents/views.py:4512
#, python-format #, python-format
msgid "Insufficient permissions to share document %(id)s." msgid "Insufficient permissions to share document %(id)s."
msgstr "" msgstr ""
#: documents/views.py:4517 #: documents/views.py:4558
msgid "Bundle is already being processed." msgid "Bundle is already being processed."
msgstr "" msgstr ""
#: documents/views.py:4578 #: documents/views.py:4619
msgid "The share link bundle is still being prepared. Please try again later." msgid "The share link bundle is still being prepared. Please try again later."
msgstr "" msgstr ""
#: documents/views.py:4588 #: documents/views.py:4629
msgid "The share link bundle is unavailable." msgid "The share link bundle is unavailable."
msgstr "" msgstr ""
+30 -30
View File
@@ -2,8 +2,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-22 15:44+0000\n" "POT-Creation-Date: 2026-07-23 19:21+0000\n"
"PO-Revision-Date: 2026-07-22 15:48\n" "PO-Revision-Date: 2026-07-23 19:23\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Bulgarian\n" "Language-Team: Bulgarian\n"
"Language: bg_BG\n" "Language: bg_BG\n"
@@ -21,39 +21,39 @@ msgstr ""
msgid "Documents" msgid "Documents"
msgstr "Документи" msgstr "Документи"
#: documents/filters.py:464 #: documents/filters.py:470
msgid "Value must be valid JSON." msgid "Value must be valid JSON."
msgstr "Стойността трябва да е валидна JSON." msgstr "Стойността трябва да е валидна JSON."
#: documents/filters.py:483 #: documents/filters.py:489
msgid "Invalid custom field query expression" msgid "Invalid custom field query expression"
msgstr "Невалидна заявка на персонализираното полето" msgstr "Невалидна заявка на персонализираното полето"
#: documents/filters.py:493 #: documents/filters.py:499
msgid "Invalid expression list. Must be nonempty." msgid "Invalid expression list. Must be nonempty."
msgstr "Списък с невалиден израз. Не може да е празно." msgstr "Списък с невалиден израз. Не може да е празно."
#: documents/filters.py:514 #: documents/filters.py:520
msgid "Invalid logical operator {op!r}" msgid "Invalid logical operator {op!r}"
msgstr "Невалиден логически оператор {op!r}" msgstr "Невалиден логически оператор {op!r}"
#: documents/filters.py:528 #: documents/filters.py:534
msgid "Maximum number of query conditions exceeded." msgid "Maximum number of query conditions exceeded."
msgstr "Надвишен е максимален брой за заявки." msgstr "Надвишен е максимален брой за заявки."
#: documents/filters.py:592 #: documents/filters.py:598
msgid "{name!r} is not a valid custom field." msgid "{name!r} is not a valid custom field."
msgstr "{name!r} не е валидно персонализирано поле." msgstr "{name!r} не е валидно персонализирано поле."
#: documents/filters.py:629 #: documents/filters.py:635
msgid "{data_type} does not support query expr {expr!r}." msgid "{data_type} does not support query expr {expr!r}."
msgstr "{data_type} не поддържа заявка expr {expr!r}." msgstr "{data_type} не поддържа заявка expr {expr!r}."
#: documents/filters.py:744 documents/models.py:136 #: documents/filters.py:750 documents/models.py:136
msgid "Maximum nesting depth exceeded." msgid "Maximum nesting depth exceeded."
msgstr "Надвишена е максималната дълбочина на вмъкване." msgstr "Надвишена е максималната дълбочина на вмъкване."
#: documents/filters.py:1061 #: documents/filters.py:1067
msgid "Custom field not found" msgid "Custom field not found"
msgstr "Персонализирано поле не е намерено" msgstr "Персонализирано поле не е намерено"
@@ -1338,48 +1338,48 @@ msgstr "стартиране на работния процес"
msgid "workflow runs" msgid "workflow runs"
msgstr "стартиране на работните процеси" msgstr "стартиране на работните процеси"
#: documents/serialisers.py:503 documents/serialisers.py:855 #: documents/serialisers.py:522 documents/serialisers.py:874
#: documents/serialisers.py:2744 documents/views.py:297 documents/views.py:2500 #: documents/serialisers.py:2763 documents/views.py:298 documents/views.py:2541
#: paperless_mail/serialisers.py:155 #: paperless_mail/serialisers.py:155
msgid "Insufficient permissions." msgid "Insufficient permissions."
msgstr "" msgstr ""
#: documents/serialisers.py:691 #: documents/serialisers.py:710
msgid "Invalid color." msgid "Invalid color."
msgstr "Невалиден цвят." msgstr "Невалиден цвят."
#: documents/serialisers.py:2216 #: documents/serialisers.py:2235
#, python-format #, python-format
msgid "File type %(type)s not supported" msgid "File type %(type)s not supported"
msgstr "Файловия тип %(type)s не се поддържа" msgstr "Файловия тип %(type)s не се поддържа"
#: documents/serialisers.py:2260 #: documents/serialisers.py:2279
#, python-format #, python-format
msgid "Custom field id must be an integer: %(id)s" msgid "Custom field id must be an integer: %(id)s"
msgstr "" msgstr ""
#: documents/serialisers.py:2267 #: documents/serialisers.py:2286
#, python-format #, python-format
msgid "Custom field with id %(id)s does not exist" msgid "Custom field with id %(id)s does not exist"
msgstr "" msgstr ""
#: documents/serialisers.py:2284 documents/serialisers.py:2294 #: documents/serialisers.py:2303 documents/serialisers.py:2313
msgid "Custom fields must be a list of integers or an object mapping ids to values." msgid "Custom fields must be a list of integers or an object mapping ids to values."
msgstr "" msgstr ""
#: documents/serialisers.py:2289 #: documents/serialisers.py:2308
msgid "Some custom fields don't exist or were specified twice." msgid "Some custom fields don't exist or were specified twice."
msgstr "" msgstr ""
#: documents/serialisers.py:2436 #: documents/serialisers.py:2455
msgid "Invalid variable detected." msgid "Invalid variable detected."
msgstr "Засечена е невалидна променлива." msgstr "Засечена е невалидна променлива."
#: documents/serialisers.py:2800 #: documents/serialisers.py:2819
msgid "Duplicate document identifiers are not allowed." msgid "Duplicate document identifiers are not allowed."
msgstr "" msgstr ""
#: documents/serialisers.py:2830 documents/views.py:4459 #: documents/serialisers.py:2849 documents/views.py:4500
#, python-format #, python-format
msgid "Documents not found: %(ids)s" msgid "Documents not found: %(ids)s"
msgstr "" msgstr ""
@@ -1635,36 +1635,36 @@ msgstr ""
msgid "Unable to parse URI {value}" msgid "Unable to parse URI {value}"
msgstr "" msgstr ""
#: documents/views.py:290 documents/views.py:2497 #: documents/views.py:291 documents/views.py:2538
msgid "Invalid more_like_id" msgid "Invalid more_like_id"
msgstr "" msgstr ""
#: documents/views.py:1524 #: documents/views.py:1556
msgid "Invalid AI configuration." msgid "Invalid AI configuration."
msgstr "" msgstr ""
#: documents/views.py:1533 #: documents/views.py:1565
msgid "AI backend request timed out." msgid "AI backend request timed out."
msgstr "" msgstr ""
#: documents/views.py:2322 documents/views.py:2643 #: documents/views.py:2363 documents/views.py:2684
msgid "Specify only one of text, title_search, query, or more_like_id." msgid "Specify only one of text, title_search, query, or more_like_id."
msgstr "" msgstr ""
#: documents/views.py:4471 #: documents/views.py:4512
#, python-format #, python-format
msgid "Insufficient permissions to share document %(id)s." msgid "Insufficient permissions to share document %(id)s."
msgstr "" msgstr ""
#: documents/views.py:4517 #: documents/views.py:4558
msgid "Bundle is already being processed." msgid "Bundle is already being processed."
msgstr "" msgstr ""
#: documents/views.py:4578 #: documents/views.py:4619
msgid "The share link bundle is still being prepared. Please try again later." msgid "The share link bundle is still being prepared. Please try again later."
msgstr "" msgstr ""
#: documents/views.py:4588 #: documents/views.py:4629
msgid "The share link bundle is unavailable." msgid "The share link bundle is unavailable."
msgstr "" msgstr ""
+30 -30
View File
@@ -2,8 +2,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-22 15:44+0000\n" "POT-Creation-Date: 2026-07-23 19:21+0000\n"
"PO-Revision-Date: 2026-07-22 15:48\n" "PO-Revision-Date: 2026-07-23 19:23\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Catalan\n" "Language-Team: Catalan\n"
"Language: ca_ES\n" "Language: ca_ES\n"
@@ -21,39 +21,39 @@ msgstr ""
msgid "Documents" msgid "Documents"
msgstr "Documents " msgstr "Documents "
#: documents/filters.py:464 #: documents/filters.py:470
msgid "Value must be valid JSON." msgid "Value must be valid JSON."
msgstr "Valor ha de ser un JSON valid." msgstr "Valor ha de ser un JSON valid."
#: documents/filters.py:483 #: documents/filters.py:489
msgid "Invalid custom field query expression" msgid "Invalid custom field query expression"
msgstr "Expressió de camp de consulta invàlid" msgstr "Expressió de camp de consulta invàlid"
#: documents/filters.py:493 #: documents/filters.py:499
msgid "Invalid expression list. Must be nonempty." msgid "Invalid expression list. Must be nonempty."
msgstr "Expressió de llista invàlida. No ha d'estar buida." msgstr "Expressió de llista invàlida. No ha d'estar buida."
#: documents/filters.py:514 #: documents/filters.py:520
msgid "Invalid logical operator {op!r}" msgid "Invalid logical operator {op!r}"
msgstr "Invàlid operand lògic {op!r}" msgstr "Invàlid operand lògic {op!r}"
#: documents/filters.py:528 #: documents/filters.py:534
msgid "Maximum number of query conditions exceeded." msgid "Maximum number of query conditions exceeded."
msgstr "Condicions de consulta excedits." msgstr "Condicions de consulta excedits."
#: documents/filters.py:592 #: documents/filters.py:598
msgid "{name!r} is not a valid custom field." msgid "{name!r} is not a valid custom field."
msgstr "{name!r} no és un camp personalitzat vàlid." msgstr "{name!r} no és un camp personalitzat vàlid."
#: documents/filters.py:629 #: documents/filters.py:635
msgid "{data_type} does not support query expr {expr!r}." msgid "{data_type} does not support query expr {expr!r}."
msgstr "{data_type} no suporta expressió de consulta {expr!r}." msgstr "{data_type} no suporta expressió de consulta {expr!r}."
#: documents/filters.py:744 documents/models.py:136 #: documents/filters.py:750 documents/models.py:136
msgid "Maximum nesting depth exceeded." msgid "Maximum nesting depth exceeded."
msgstr "Màxima profunditat anidada excedida." msgstr "Màxima profunditat anidada excedida."
#: documents/filters.py:1061 #: documents/filters.py:1067
msgid "Custom field not found" msgid "Custom field not found"
msgstr "Camp personalitzat no trobat" msgstr "Camp personalitzat no trobat"
@@ -1338,48 +1338,48 @@ msgstr "data del flux"
msgid "workflow runs" msgid "workflow runs"
msgstr "flux corrents" msgstr "flux corrents"
#: documents/serialisers.py:503 documents/serialisers.py:855 #: documents/serialisers.py:522 documents/serialisers.py:874
#: documents/serialisers.py:2744 documents/views.py:297 documents/views.py:2500 #: documents/serialisers.py:2763 documents/views.py:298 documents/views.py:2541
#: paperless_mail/serialisers.py:155 #: paperless_mail/serialisers.py:155
msgid "Insufficient permissions." msgid "Insufficient permissions."
msgstr "Permisos insuficients." msgstr "Permisos insuficients."
#: documents/serialisers.py:691 #: documents/serialisers.py:710
msgid "Invalid color." msgid "Invalid color."
msgstr "Color Invàlid." msgstr "Color Invàlid."
#: documents/serialisers.py:2216 #: documents/serialisers.py:2235
#, python-format #, python-format
msgid "File type %(type)s not supported" msgid "File type %(type)s not supported"
msgstr "Tipus arxiu %(type)s no suportat" msgstr "Tipus arxiu %(type)s no suportat"
#: documents/serialisers.py:2260 #: documents/serialisers.py:2279
#, python-format #, python-format
msgid "Custom field id must be an integer: %(id)s" msgid "Custom field id must be an integer: %(id)s"
msgstr "ID de camp personalizat ha de ser enter: %(id)s" msgstr "ID de camp personalizat ha de ser enter: %(id)s"
#: documents/serialisers.py:2267 #: documents/serialisers.py:2286
#, python-format #, python-format
msgid "Custom field with id %(id)s does not exist" msgid "Custom field with id %(id)s does not exist"
msgstr "Camp personalitzat amb ID %(id)s no existeix" msgstr "Camp personalitzat amb ID %(id)s no existeix"
#: documents/serialisers.py:2284 documents/serialisers.py:2294 #: documents/serialisers.py:2303 documents/serialisers.py:2313
msgid "Custom fields must be a list of integers or an object mapping ids to values." msgid "Custom fields must be a list of integers or an object mapping ids to values."
msgstr "Camps personalitzats han de ser una llista d'enters o un objecte que mapegi els identificadors amb els valors." msgstr "Camps personalitzats han de ser una llista d'enters o un objecte que mapegi els identificadors amb els valors."
#: documents/serialisers.py:2289 #: documents/serialisers.py:2308
msgid "Some custom fields don't exist or were specified twice." msgid "Some custom fields don't exist or were specified twice."
msgstr "Alguns camps personalitzats no existeixen o s'han especificat dues vegades." msgstr "Alguns camps personalitzats no existeixen o s'han especificat dues vegades."
#: documents/serialisers.py:2436 #: documents/serialisers.py:2455
msgid "Invalid variable detected." msgid "Invalid variable detected."
msgstr "Variable detectada invàlida." msgstr "Variable detectada invàlida."
#: documents/serialisers.py:2800 #: documents/serialisers.py:2819
msgid "Duplicate document identifiers are not allowed." msgid "Duplicate document identifiers are not allowed."
msgstr "Duplicat d'identificadors de documents no permès." msgstr "Duplicat d'identificadors de documents no permès."
#: documents/serialisers.py:2830 documents/views.py:4459 #: documents/serialisers.py:2849 documents/views.py:4500
#, python-format #, python-format
msgid "Documents not found: %(ids)s" msgid "Documents not found: %(ids)s"
msgstr "Documents no trobats: %(ids)s" msgstr "Documents no trobats: %(ids)s"
@@ -1635,36 +1635,36 @@ msgstr "L'esquema d'URI '{parts.scheme}' no està permès. Esquemes permesos: {'
msgid "Unable to parse URI {value}" msgid "Unable to parse URI {value}"
msgstr "No s'ha pogut analitzar l'URI {value}" msgstr "No s'ha pogut analitzar l'URI {value}"
#: documents/views.py:290 documents/views.py:2497 #: documents/views.py:291 documents/views.py:2538
msgid "Invalid more_like_id" msgid "Invalid more_like_id"
msgstr "Invalid more_like_id" msgstr "Invalid more_like_id"
#: documents/views.py:1524 #: documents/views.py:1556
msgid "Invalid AI configuration." msgid "Invalid AI configuration."
msgstr "Configuració AI invàlida." msgstr "Configuració AI invàlida."
#: documents/views.py:1533 #: documents/views.py:1565
msgid "AI backend request timed out." msgid "AI backend request timed out."
msgstr "" msgstr ""
#: documents/views.py:2322 documents/views.py:2643 #: documents/views.py:2363 documents/views.py:2684
msgid "Specify only one of text, title_search, query, or more_like_id." msgid "Specify only one of text, title_search, query, or more_like_id."
msgstr "Especifica només un dels següents valors: text, title_search, query o more_like_id." msgstr "Especifica només un dels següents valors: text, title_search, query o more_like_id."
#: documents/views.py:4471 #: documents/views.py:4512
#, python-format #, python-format
msgid "Insufficient permissions to share document %(id)s." msgid "Insufficient permissions to share document %(id)s."
msgstr "Permisos insuficients per compartir document %(id)s." msgstr "Permisos insuficients per compartir document %(id)s."
#: documents/views.py:4517 #: documents/views.py:4558
msgid "Bundle is already being processed." msgid "Bundle is already being processed."
msgstr "Paquet ja s'està processant." msgstr "Paquet ja s'està processant."
#: documents/views.py:4578 #: documents/views.py:4619
msgid "The share link bundle is still being prepared. Please try again later." msgid "The share link bundle is still being prepared. Please try again later."
msgstr "El paquet de link encarà s'està preparant. Prova de nou més tard." msgstr "El paquet de link encarà s'està preparant. Prova de nou més tard."
#: documents/views.py:4588 #: documents/views.py:4629
msgid "The share link bundle is unavailable." msgid "The share link bundle is unavailable."
msgstr "El paquet d'enllaç no està disponible." msgstr "El paquet d'enllaç no està disponible."
+30 -30
View File
@@ -2,8 +2,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-22 15:44+0000\n" "POT-Creation-Date: 2026-07-23 19:21+0000\n"
"PO-Revision-Date: 2026-07-22 15:48\n" "PO-Revision-Date: 2026-07-23 19:23\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Czech\n" "Language-Team: Czech\n"
"Language: cs_CZ\n" "Language: cs_CZ\n"
@@ -21,39 +21,39 @@ msgstr ""
msgid "Documents" msgid "Documents"
msgstr "Dokumenty" msgstr "Dokumenty"
#: documents/filters.py:464 #: documents/filters.py:470
msgid "Value must be valid JSON." msgid "Value must be valid JSON."
msgstr "Hodnota musí být platný JSON." msgstr "Hodnota musí být platný JSON."
#: documents/filters.py:483 #: documents/filters.py:489
msgid "Invalid custom field query expression" msgid "Invalid custom field query expression"
msgstr "Neplatný výraz dotazu na vlastní pole" msgstr "Neplatný výraz dotazu na vlastní pole"
#: documents/filters.py:493 #: documents/filters.py:499
msgid "Invalid expression list. Must be nonempty." msgid "Invalid expression list. Must be nonempty."
msgstr "Neplatný seznam výrazů. Nesmí být prázdný." msgstr "Neplatný seznam výrazů. Nesmí být prázdný."
#: documents/filters.py:514 #: documents/filters.py:520
msgid "Invalid logical operator {op!r}" msgid "Invalid logical operator {op!r}"
msgstr "Neplatný logický operátor {op!r}" msgstr "Neplatný logický operátor {op!r}"
#: documents/filters.py:528 #: documents/filters.py:534
msgid "Maximum number of query conditions exceeded." msgid "Maximum number of query conditions exceeded."
msgstr "Překročen maximální počet podmínek dotazu." msgstr "Překročen maximální počet podmínek dotazu."
#: documents/filters.py:592 #: documents/filters.py:598
msgid "{name!r} is not a valid custom field." msgid "{name!r} is not a valid custom field."
msgstr "{name!r} není platné vlastní pole." msgstr "{name!r} není platné vlastní pole."
#: documents/filters.py:629 #: documents/filters.py:635
msgid "{data_type} does not support query expr {expr!r}." msgid "{data_type} does not support query expr {expr!r}."
msgstr "{data_type} nepodporuje výraz dotazu {expr!r}." msgstr "{data_type} nepodporuje výraz dotazu {expr!r}."
#: documents/filters.py:744 documents/models.py:136 #: documents/filters.py:750 documents/models.py:136
msgid "Maximum nesting depth exceeded." msgid "Maximum nesting depth exceeded."
msgstr "Překročena maximální hloubka větvení." msgstr "Překročena maximální hloubka větvení."
#: documents/filters.py:1061 #: documents/filters.py:1067
msgid "Custom field not found" msgid "Custom field not found"
msgstr "Vlastní pole nebylo nalezeno" msgstr "Vlastní pole nebylo nalezeno"
@@ -1338,48 +1338,48 @@ msgstr "spuštění pracovního postupu"
msgid "workflow runs" msgid "workflow runs"
msgstr "spuštění pracovních postupů" msgstr "spuštění pracovních postupů"
#: documents/serialisers.py:503 documents/serialisers.py:855 #: documents/serialisers.py:522 documents/serialisers.py:874
#: documents/serialisers.py:2744 documents/views.py:297 documents/views.py:2500 #: documents/serialisers.py:2763 documents/views.py:298 documents/views.py:2541
#: paperless_mail/serialisers.py:155 #: paperless_mail/serialisers.py:155
msgid "Insufficient permissions." msgid "Insufficient permissions."
msgstr "" msgstr ""
#: documents/serialisers.py:691 #: documents/serialisers.py:710
msgid "Invalid color." msgid "Invalid color."
msgstr "Neplatná barva." msgstr "Neplatná barva."
#: documents/serialisers.py:2216 #: documents/serialisers.py:2235
#, python-format #, python-format
msgid "File type %(type)s not supported" msgid "File type %(type)s not supported"
msgstr "Typ souboru %(type)s není podporován" msgstr "Typ souboru %(type)s není podporován"
#: documents/serialisers.py:2260 #: documents/serialisers.py:2279
#, python-format #, python-format
msgid "Custom field id must be an integer: %(id)s" msgid "Custom field id must be an integer: %(id)s"
msgstr "Vlastní ID pole musí být celé číslo: %(id)s" msgstr "Vlastní ID pole musí být celé číslo: %(id)s"
#: documents/serialisers.py:2267 #: documents/serialisers.py:2286
#, python-format #, python-format
msgid "Custom field with id %(id)s does not exist" msgid "Custom field with id %(id)s does not exist"
msgstr "Vlastní pole s ID %(id)s neexistuje" msgstr "Vlastní pole s ID %(id)s neexistuje"
#: documents/serialisers.py:2284 documents/serialisers.py:2294 #: documents/serialisers.py:2303 documents/serialisers.py:2313
msgid "Custom fields must be a list of integers or an object mapping ids to values." msgid "Custom fields must be a list of integers or an object mapping ids to values."
msgstr "Vlastní pole musí být seznam celých čísel nebo ID pro mapování objektů na hodnoty." msgstr "Vlastní pole musí být seznam celých čísel nebo ID pro mapování objektů na hodnoty."
#: documents/serialisers.py:2289 #: documents/serialisers.py:2308
msgid "Some custom fields don't exist or were specified twice." msgid "Some custom fields don't exist or were specified twice."
msgstr "Některá vlastní pole neexistují nebo byla zadána dvakrát." msgstr "Některá vlastní pole neexistují nebo byla zadána dvakrát."
#: documents/serialisers.py:2436 #: documents/serialisers.py:2455
msgid "Invalid variable detected." msgid "Invalid variable detected."
msgstr "Zjištěna neplatná proměnná." msgstr "Zjištěna neplatná proměnná."
#: documents/serialisers.py:2800 #: documents/serialisers.py:2819
msgid "Duplicate document identifiers are not allowed." msgid "Duplicate document identifiers are not allowed."
msgstr "" msgstr ""
#: documents/serialisers.py:2830 documents/views.py:4459 #: documents/serialisers.py:2849 documents/views.py:4500
#, python-format #, python-format
msgid "Documents not found: %(ids)s" msgid "Documents not found: %(ids)s"
msgstr "" msgstr ""
@@ -1636,36 +1636,36 @@ msgstr "URI schéma '{parts.scheme}' není povoleno. Povolená schémata: {',\n"
msgid "Unable to parse URI {value}" msgid "Unable to parse URI {value}"
msgstr "Nelze zpracovat URI {value}" msgstr "Nelze zpracovat URI {value}"
#: documents/views.py:290 documents/views.py:2497 #: documents/views.py:291 documents/views.py:2538
msgid "Invalid more_like_id" msgid "Invalid more_like_id"
msgstr "" msgstr ""
#: documents/views.py:1524 #: documents/views.py:1556
msgid "Invalid AI configuration." msgid "Invalid AI configuration."
msgstr "" msgstr ""
#: documents/views.py:1533 #: documents/views.py:1565
msgid "AI backend request timed out." msgid "AI backend request timed out."
msgstr "" msgstr ""
#: documents/views.py:2322 documents/views.py:2643 #: documents/views.py:2363 documents/views.py:2684
msgid "Specify only one of text, title_search, query, or more_like_id." msgid "Specify only one of text, title_search, query, or more_like_id."
msgstr "" msgstr ""
#: documents/views.py:4471 #: documents/views.py:4512
#, python-format #, python-format
msgid "Insufficient permissions to share document %(id)s." msgid "Insufficient permissions to share document %(id)s."
msgstr "" msgstr ""
#: documents/views.py:4517 #: documents/views.py:4558
msgid "Bundle is already being processed." msgid "Bundle is already being processed."
msgstr "" msgstr ""
#: documents/views.py:4578 #: documents/views.py:4619
msgid "The share link bundle is still being prepared. Please try again later." msgid "The share link bundle is still being prepared. Please try again later."
msgstr "" msgstr ""
#: documents/views.py:4588 #: documents/views.py:4629
msgid "The share link bundle is unavailable." msgid "The share link bundle is unavailable."
msgstr "" msgstr ""
+30 -30
View File
@@ -2,8 +2,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-22 15:44+0000\n" "POT-Creation-Date: 2026-07-23 19:21+0000\n"
"PO-Revision-Date: 2026-07-22 15:48\n" "PO-Revision-Date: 2026-07-23 19:23\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Danish\n" "Language-Team: Danish\n"
"Language: da_DK\n" "Language: da_DK\n"
@@ -21,39 +21,39 @@ msgstr ""
msgid "Documents" msgid "Documents"
msgstr "Dokumenter" msgstr "Dokumenter"
#: documents/filters.py:464 #: documents/filters.py:470
msgid "Value must be valid JSON." msgid "Value must be valid JSON."
msgstr "Værdien skal være gyldig JSON." msgstr "Værdien skal være gyldig JSON."
#: documents/filters.py:483 #: documents/filters.py:489
msgid "Invalid custom field query expression" msgid "Invalid custom field query expression"
msgstr "Ugyldigt tilpasset feltforespørgselsudtryk" msgstr "Ugyldigt tilpasset feltforespørgselsudtryk"
#: documents/filters.py:493 #: documents/filters.py:499
msgid "Invalid expression list. Must be nonempty." msgid "Invalid expression list. Must be nonempty."
msgstr "Ugyldig udtryksliste. Må ikke være tom." msgstr "Ugyldig udtryksliste. Må ikke være tom."
#: documents/filters.py:514 #: documents/filters.py:520
msgid "Invalid logical operator {op!r}" msgid "Invalid logical operator {op!r}"
msgstr "Ugyldig logisk operatør {op!r}" msgstr "Ugyldig logisk operatør {op!r}"
#: documents/filters.py:528 #: documents/filters.py:534
msgid "Maximum number of query conditions exceeded." msgid "Maximum number of query conditions exceeded."
msgstr "Maksimalt antal forespørgselsbetingelser overskredet." msgstr "Maksimalt antal forespørgselsbetingelser overskredet."
#: documents/filters.py:592 #: documents/filters.py:598
msgid "{name!r} is not a valid custom field." msgid "{name!r} is not a valid custom field."
msgstr "{name!r} er ikke et gyldigt tilpasset felt." msgstr "{name!r} er ikke et gyldigt tilpasset felt."
#: documents/filters.py:629 #: documents/filters.py:635
msgid "{data_type} does not support query expr {expr!r}." msgid "{data_type} does not support query expr {expr!r}."
msgstr "{data_type} understøtter ikke forespørgsel expr {expr!r}." msgstr "{data_type} understøtter ikke forespørgsel expr {expr!r}."
#: documents/filters.py:744 documents/models.py:136 #: documents/filters.py:750 documents/models.py:136
msgid "Maximum nesting depth exceeded." msgid "Maximum nesting depth exceeded."
msgstr "Maksimal indlejringsdybde overskredet." msgstr "Maksimal indlejringsdybde overskredet."
#: documents/filters.py:1061 #: documents/filters.py:1067
msgid "Custom field not found" msgid "Custom field not found"
msgstr "Tilpasset felt ikke fundet" msgstr "Tilpasset felt ikke fundet"
@@ -1338,48 +1338,48 @@ msgstr "workflow-kørsel"
msgid "workflow runs" msgid "workflow runs"
msgstr "workflow-kørsler" msgstr "workflow-kørsler"
#: documents/serialisers.py:503 documents/serialisers.py:855 #: documents/serialisers.py:522 documents/serialisers.py:874
#: documents/serialisers.py:2744 documents/views.py:297 documents/views.py:2500 #: documents/serialisers.py:2763 documents/views.py:298 documents/views.py:2541
#: paperless_mail/serialisers.py:155 #: paperless_mail/serialisers.py:155
msgid "Insufficient permissions." msgid "Insufficient permissions."
msgstr "" msgstr ""
#: documents/serialisers.py:691 #: documents/serialisers.py:710
msgid "Invalid color." msgid "Invalid color."
msgstr "Ugyldig farve." msgstr "Ugyldig farve."
#: documents/serialisers.py:2216 #: documents/serialisers.py:2235
#, python-format #, python-format
msgid "File type %(type)s not supported" msgid "File type %(type)s not supported"
msgstr "Filtype %(type)s understøttes ikke" msgstr "Filtype %(type)s understøttes ikke"
#: documents/serialisers.py:2260 #: documents/serialisers.py:2279
#, python-format #, python-format
msgid "Custom field id must be an integer: %(id)s" msgid "Custom field id must be an integer: %(id)s"
msgstr "" msgstr ""
#: documents/serialisers.py:2267 #: documents/serialisers.py:2286
#, python-format #, python-format
msgid "Custom field with id %(id)s does not exist" msgid "Custom field with id %(id)s does not exist"
msgstr "" msgstr ""
#: documents/serialisers.py:2284 documents/serialisers.py:2294 #: documents/serialisers.py:2303 documents/serialisers.py:2313
msgid "Custom fields must be a list of integers or an object mapping ids to values." msgid "Custom fields must be a list of integers or an object mapping ids to values."
msgstr "" msgstr ""
#: documents/serialisers.py:2289 #: documents/serialisers.py:2308
msgid "Some custom fields don't exist or were specified twice." msgid "Some custom fields don't exist or were specified twice."
msgstr "" msgstr ""
#: documents/serialisers.py:2436 #: documents/serialisers.py:2455
msgid "Invalid variable detected." msgid "Invalid variable detected."
msgstr "Ugyldig variabel fundet." msgstr "Ugyldig variabel fundet."
#: documents/serialisers.py:2800 #: documents/serialisers.py:2819
msgid "Duplicate document identifiers are not allowed." msgid "Duplicate document identifiers are not allowed."
msgstr "" msgstr ""
#: documents/serialisers.py:2830 documents/views.py:4459 #: documents/serialisers.py:2849 documents/views.py:4500
#, python-format #, python-format
msgid "Documents not found: %(ids)s" msgid "Documents not found: %(ids)s"
msgstr "" msgstr ""
@@ -1635,36 +1635,36 @@ msgstr ""
msgid "Unable to parse URI {value}" msgid "Unable to parse URI {value}"
msgstr "" msgstr ""
#: documents/views.py:290 documents/views.py:2497 #: documents/views.py:291 documents/views.py:2538
msgid "Invalid more_like_id" msgid "Invalid more_like_id"
msgstr "" msgstr ""
#: documents/views.py:1524 #: documents/views.py:1556
msgid "Invalid AI configuration." msgid "Invalid AI configuration."
msgstr "" msgstr ""
#: documents/views.py:1533 #: documents/views.py:1565
msgid "AI backend request timed out." msgid "AI backend request timed out."
msgstr "" msgstr ""
#: documents/views.py:2322 documents/views.py:2643 #: documents/views.py:2363 documents/views.py:2684
msgid "Specify only one of text, title_search, query, or more_like_id." msgid "Specify only one of text, title_search, query, or more_like_id."
msgstr "" msgstr ""
#: documents/views.py:4471 #: documents/views.py:4512
#, python-format #, python-format
msgid "Insufficient permissions to share document %(id)s." msgid "Insufficient permissions to share document %(id)s."
msgstr "" msgstr ""
#: documents/views.py:4517 #: documents/views.py:4558
msgid "Bundle is already being processed." msgid "Bundle is already being processed."
msgstr "" msgstr ""
#: documents/views.py:4578 #: documents/views.py:4619
msgid "The share link bundle is still being prepared. Please try again later." msgid "The share link bundle is still being prepared. Please try again later."
msgstr "" msgstr ""
#: documents/views.py:4588 #: documents/views.py:4629
msgid "The share link bundle is unavailable." msgid "The share link bundle is unavailable."
msgstr "" msgstr ""
+30 -30
View File
@@ -2,8 +2,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-22 15:44+0000\n" "POT-Creation-Date: 2026-07-23 19:21+0000\n"
"PO-Revision-Date: 2026-07-22 15:48\n" "PO-Revision-Date: 2026-07-23 19:23\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: German, Switzerland\n" "Language-Team: German, Switzerland\n"
"Language: de_CH\n" "Language: de_CH\n"
@@ -21,39 +21,39 @@ msgstr ""
msgid "Documents" msgid "Documents"
msgstr "Dokumente" msgstr "Dokumente"
#: documents/filters.py:464 #: documents/filters.py:470
msgid "Value must be valid JSON." msgid "Value must be valid JSON."
msgstr "Wert muss gültiges JSON sein." msgstr "Wert muss gültiges JSON sein."
#: documents/filters.py:483 #: documents/filters.py:489
msgid "Invalid custom field query expression" msgid "Invalid custom field query expression"
msgstr "Ungültiger benutzerdefinierter Feldabfrageausdruck" msgstr "Ungültiger benutzerdefinierter Feldabfrageausdruck"
#: documents/filters.py:493 #: documents/filters.py:499
msgid "Invalid expression list. Must be nonempty." msgid "Invalid expression list. Must be nonempty."
msgstr "Ungültige Ausdrucksliste. Darf nicht leer sein." msgstr "Ungültige Ausdrucksliste. Darf nicht leer sein."
#: documents/filters.py:514 #: documents/filters.py:520
msgid "Invalid logical operator {op!r}" msgid "Invalid logical operator {op!r}"
msgstr "Ungültiger logischer Operator {op!r}" msgstr "Ungültiger logischer Operator {op!r}"
#: documents/filters.py:528 #: documents/filters.py:534
msgid "Maximum number of query conditions exceeded." msgid "Maximum number of query conditions exceeded."
msgstr "Maximale Anzahl an Abfragebedingungen überschritten." msgstr "Maximale Anzahl an Abfragebedingungen überschritten."
#: documents/filters.py:592 #: documents/filters.py:598
msgid "{name!r} is not a valid custom field." msgid "{name!r} is not a valid custom field."
msgstr "{name!r} ist kein gültiges Zusatzfeld." msgstr "{name!r} ist kein gültiges Zusatzfeld."
#: documents/filters.py:629 #: documents/filters.py:635
msgid "{data_type} does not support query expr {expr!r}." msgid "{data_type} does not support query expr {expr!r}."
msgstr "{data_type} unterstützt den Abfrageausdruck {expr!r} nicht." msgstr "{data_type} unterstützt den Abfrageausdruck {expr!r} nicht."
#: documents/filters.py:744 documents/models.py:136 #: documents/filters.py:750 documents/models.py:136
msgid "Maximum nesting depth exceeded." msgid "Maximum nesting depth exceeded."
msgstr "Maximale Verschachtelungstiefe überschritten." msgstr "Maximale Verschachtelungstiefe überschritten."
#: documents/filters.py:1061 #: documents/filters.py:1067
msgid "Custom field not found" msgid "Custom field not found"
msgstr "Benutzerdefiniertes Feld nicht gefunden" msgstr "Benutzerdefiniertes Feld nicht gefunden"
@@ -1338,48 +1338,48 @@ msgstr "Arbeitsablauf-Ausführung"
msgid "workflow runs" msgid "workflow runs"
msgstr "Arbeitsablauf wird ausgeführt" msgstr "Arbeitsablauf wird ausgeführt"
#: documents/serialisers.py:503 documents/serialisers.py:855 #: documents/serialisers.py:522 documents/serialisers.py:874
#: documents/serialisers.py:2744 documents/views.py:297 documents/views.py:2500 #: documents/serialisers.py:2763 documents/views.py:298 documents/views.py:2541
#: paperless_mail/serialisers.py:155 #: paperless_mail/serialisers.py:155
msgid "Insufficient permissions." msgid "Insufficient permissions."
msgstr "Unzureichende Berechtigungen." msgstr "Unzureichende Berechtigungen."
#: documents/serialisers.py:691 #: documents/serialisers.py:710
msgid "Invalid color." msgid "Invalid color."
msgstr "Ungültige Farbe." msgstr "Ungültige Farbe."
#: documents/serialisers.py:2216 #: documents/serialisers.py:2235
#, python-format #, python-format
msgid "File type %(type)s not supported" msgid "File type %(type)s not supported"
msgstr "Dateityp %(type)s nicht unterstützt" msgstr "Dateityp %(type)s nicht unterstützt"
#: documents/serialisers.py:2260 #: documents/serialisers.py:2279
#, python-format #, python-format
msgid "Custom field id must be an integer: %(id)s" msgid "Custom field id must be an integer: %(id)s"
msgstr "Feld-ID eines benutzerdefinierten Felds muss eine Ganzzahl sein: %(id)s" msgstr "Feld-ID eines benutzerdefinierten Felds muss eine Ganzzahl sein: %(id)s"
#: documents/serialisers.py:2267 #: documents/serialisers.py:2286
#, python-format #, python-format
msgid "Custom field with id %(id)s does not exist" msgid "Custom field with id %(id)s does not exist"
msgstr "Benutzerdefiniertes Feld mit ID %(id)s existiert nicht" msgstr "Benutzerdefiniertes Feld mit ID %(id)s existiert nicht"
#: documents/serialisers.py:2284 documents/serialisers.py:2294 #: documents/serialisers.py:2303 documents/serialisers.py:2313
msgid "Custom fields must be a list of integers or an object mapping ids to values." msgid "Custom fields must be a list of integers or an object mapping ids to values."
msgstr "Benutzerdefinierte Felder müssen eine Liste von Ganzzahlen oder ein Objekt mit Zuordnung von IDs zu Werten sein." msgstr "Benutzerdefinierte Felder müssen eine Liste von Ganzzahlen oder ein Objekt mit Zuordnung von IDs zu Werten sein."
#: documents/serialisers.py:2289 #: documents/serialisers.py:2308
msgid "Some custom fields don't exist or were specified twice." msgid "Some custom fields don't exist or were specified twice."
msgstr "Einige benutzerdefinierte Felder existieren nicht oder wurden zweimal angegeben." msgstr "Einige benutzerdefinierte Felder existieren nicht oder wurden zweimal angegeben."
#: documents/serialisers.py:2436 #: documents/serialisers.py:2455
msgid "Invalid variable detected." msgid "Invalid variable detected."
msgstr "Ungültige Variable erkannt." msgstr "Ungültige Variable erkannt."
#: documents/serialisers.py:2800 #: documents/serialisers.py:2819
msgid "Duplicate document identifiers are not allowed." msgid "Duplicate document identifiers are not allowed."
msgstr "Doppelte Dokumentbezeichner sind nicht erlaubt." msgstr "Doppelte Dokumentbezeichner sind nicht erlaubt."
#: documents/serialisers.py:2830 documents/views.py:4459 #: documents/serialisers.py:2849 documents/views.py:4500
#, python-format #, python-format
msgid "Documents not found: %(ids)s" msgid "Documents not found: %(ids)s"
msgstr "Dokumente nicht gefunden: %(ids)s" msgstr "Dokumente nicht gefunden: %(ids)s"
@@ -1635,36 +1635,36 @@ msgstr "URI-Schema „{parts.scheme}“ ist nicht erlaubt. Erlaubte Schemata: {'
msgid "Unable to parse URI {value}" msgid "Unable to parse URI {value}"
msgstr "URI {value} kann nicht gelesen werden" msgstr "URI {value} kann nicht gelesen werden"
#: documents/views.py:290 documents/views.py:2497 #: documents/views.py:291 documents/views.py:2538
msgid "Invalid more_like_id" msgid "Invalid more_like_id"
msgstr "Ungültige more_like_id" msgstr "Ungültige more_like_id"
#: documents/views.py:1524 #: documents/views.py:1556
msgid "Invalid AI configuration." msgid "Invalid AI configuration."
msgstr "Ungültige KI-Konfiguration." msgstr "Ungültige KI-Konfiguration."
#: documents/views.py:1533 #: documents/views.py:1565
msgid "AI backend request timed out." msgid "AI backend request timed out."
msgstr "" msgstr ""
#: documents/views.py:2322 documents/views.py:2643 #: documents/views.py:2363 documents/views.py:2684
msgid "Specify only one of text, title_search, query, or more_like_id." msgid "Specify only one of text, title_search, query, or more_like_id."
msgstr "Geben Sie nur einen von text, title_search, query, oder more_like_id an." msgstr "Geben Sie nur einen von text, title_search, query, oder more_like_id an."
#: documents/views.py:4471 #: documents/views.py:4512
#, python-format #, python-format
msgid "Insufficient permissions to share document %(id)s." msgid "Insufficient permissions to share document %(id)s."
msgstr "Unzureichende Berechtigungen, um Dokument %(id)s zu teilen." msgstr "Unzureichende Berechtigungen, um Dokument %(id)s zu teilen."
#: documents/views.py:4517 #: documents/views.py:4558
msgid "Bundle is already being processed." msgid "Bundle is already being processed."
msgstr "Paket wird bereits verarbeitet." msgstr "Paket wird bereits verarbeitet."
#: documents/views.py:4578 #: documents/views.py:4619
msgid "The share link bundle is still being prepared. Please try again later." msgid "The share link bundle is still being prepared. Please try again later."
msgstr "Das Freigabelink-Paket wird noch vorbereitet. Bitte versuchen Sie es später erneut." msgstr "Das Freigabelink-Paket wird noch vorbereitet. Bitte versuchen Sie es später erneut."
#: documents/views.py:4588 #: documents/views.py:4629
msgid "The share link bundle is unavailable." msgid "The share link bundle is unavailable."
msgstr "Das Freigabelink-Paket ist nicht verfügbar." msgstr "Das Freigabelink-Paket ist nicht verfügbar."
+30 -30
View File
@@ -2,8 +2,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-22 15:44+0000\n" "POT-Creation-Date: 2026-07-23 19:21+0000\n"
"PO-Revision-Date: 2026-07-22 15:48\n" "PO-Revision-Date: 2026-07-23 19:23\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: German\n" "Language-Team: German\n"
"Language: de_DE\n" "Language: de_DE\n"
@@ -21,39 +21,39 @@ msgstr ""
msgid "Documents" msgid "Documents"
msgstr "Dokumente" msgstr "Dokumente"
#: documents/filters.py:464 #: documents/filters.py:470
msgid "Value must be valid JSON." msgid "Value must be valid JSON."
msgstr "Wert muss gültiges JSON sein." msgstr "Wert muss gültiges JSON sein."
#: documents/filters.py:483 #: documents/filters.py:489
msgid "Invalid custom field query expression" msgid "Invalid custom field query expression"
msgstr "Ungültiger Zusatzfeld-Abfrageausdruck" msgstr "Ungültiger Zusatzfeld-Abfrageausdruck"
#: documents/filters.py:493 #: documents/filters.py:499
msgid "Invalid expression list. Must be nonempty." msgid "Invalid expression list. Must be nonempty."
msgstr "Ungültige Ausdrucksliste. Darf nicht leer sein." msgstr "Ungültige Ausdrucksliste. Darf nicht leer sein."
#: documents/filters.py:514 #: documents/filters.py:520
msgid "Invalid logical operator {op!r}" msgid "Invalid logical operator {op!r}"
msgstr "Ungültiger logischer Operator {op!r}" msgstr "Ungültiger logischer Operator {op!r}"
#: documents/filters.py:528 #: documents/filters.py:534
msgid "Maximum number of query conditions exceeded." msgid "Maximum number of query conditions exceeded."
msgstr "Maximale Anzahl an Abfragebedingungen überschritten." msgstr "Maximale Anzahl an Abfragebedingungen überschritten."
#: documents/filters.py:592 #: documents/filters.py:598
msgid "{name!r} is not a valid custom field." msgid "{name!r} is not a valid custom field."
msgstr "{name!r} ist kein gültiges Zusatzfeld." msgstr "{name!r} ist kein gültiges Zusatzfeld."
#: documents/filters.py:629 #: documents/filters.py:635
msgid "{data_type} does not support query expr {expr!r}." msgid "{data_type} does not support query expr {expr!r}."
msgstr "{data_type} unterstützt den Abfrageausdruck {expr!r} nicht." msgstr "{data_type} unterstützt den Abfrageausdruck {expr!r} nicht."
#: documents/filters.py:744 documents/models.py:136 #: documents/filters.py:750 documents/models.py:136
msgid "Maximum nesting depth exceeded." msgid "Maximum nesting depth exceeded."
msgstr "Maximale Verschachtelungstiefe überschritten." msgstr "Maximale Verschachtelungstiefe überschritten."
#: documents/filters.py:1061 #: documents/filters.py:1067
msgid "Custom field not found" msgid "Custom field not found"
msgstr "Zusatzfeld nicht gefunden" msgstr "Zusatzfeld nicht gefunden"
@@ -1338,48 +1338,48 @@ msgstr "Arbeitsablauf-Ausführung"
msgid "workflow runs" msgid "workflow runs"
msgstr "Arbeitsablauf wird ausgeführt" msgstr "Arbeitsablauf wird ausgeführt"
#: documents/serialisers.py:503 documents/serialisers.py:855 #: documents/serialisers.py:522 documents/serialisers.py:874
#: documents/serialisers.py:2744 documents/views.py:297 documents/views.py:2500 #: documents/serialisers.py:2763 documents/views.py:298 documents/views.py:2541
#: paperless_mail/serialisers.py:155 #: paperless_mail/serialisers.py:155
msgid "Insufficient permissions." msgid "Insufficient permissions."
msgstr "Unzureichende Berechtigungen." msgstr "Unzureichende Berechtigungen."
#: documents/serialisers.py:691 #: documents/serialisers.py:710
msgid "Invalid color." msgid "Invalid color."
msgstr "Ungültige Farbe." msgstr "Ungültige Farbe."
#: documents/serialisers.py:2216 #: documents/serialisers.py:2235
#, python-format #, python-format
msgid "File type %(type)s not supported" msgid "File type %(type)s not supported"
msgstr "Dateityp %(type)s nicht unterstützt" msgstr "Dateityp %(type)s nicht unterstützt"
#: documents/serialisers.py:2260 #: documents/serialisers.py:2279
#, python-format #, python-format
msgid "Custom field id must be an integer: %(id)s" msgid "Custom field id must be an integer: %(id)s"
msgstr "Zusatzfeld-ID muss eine Ganzzahl sein: %(id)s" msgstr "Zusatzfeld-ID muss eine Ganzzahl sein: %(id)s"
#: documents/serialisers.py:2267 #: documents/serialisers.py:2286
#, python-format #, python-format
msgid "Custom field with id %(id)s does not exist" msgid "Custom field with id %(id)s does not exist"
msgstr "Zusatzfeld mit ID %(id)s existiert nicht" msgstr "Zusatzfeld mit ID %(id)s existiert nicht"
#: documents/serialisers.py:2284 documents/serialisers.py:2294 #: documents/serialisers.py:2303 documents/serialisers.py:2313
msgid "Custom fields must be a list of integers or an object mapping ids to values." msgid "Custom fields must be a list of integers or an object mapping ids to values."
msgstr "Zusatzfelder müssen eine Liste von Ganzzahlen oder ein Objekt mit Zuordnung von IDs zu Werten sein." msgstr "Zusatzfelder müssen eine Liste von Ganzzahlen oder ein Objekt mit Zuordnung von IDs zu Werten sein."
#: documents/serialisers.py:2289 #: documents/serialisers.py:2308
msgid "Some custom fields don't exist or were specified twice." msgid "Some custom fields don't exist or were specified twice."
msgstr "Einige Zusatzfelder existieren nicht oder wurden zweimal angegeben." msgstr "Einige Zusatzfelder existieren nicht oder wurden zweimal angegeben."
#: documents/serialisers.py:2436 #: documents/serialisers.py:2455
msgid "Invalid variable detected." msgid "Invalid variable detected."
msgstr "Ungültige Variable erkannt." msgstr "Ungültige Variable erkannt."
#: documents/serialisers.py:2800 #: documents/serialisers.py:2819
msgid "Duplicate document identifiers are not allowed." msgid "Duplicate document identifiers are not allowed."
msgstr "Doppelte Dokumentbezeichner sind nicht erlaubt." msgstr "Doppelte Dokumentbezeichner sind nicht erlaubt."
#: documents/serialisers.py:2830 documents/views.py:4459 #: documents/serialisers.py:2849 documents/views.py:4500
#, python-format #, python-format
msgid "Documents not found: %(ids)s" msgid "Documents not found: %(ids)s"
msgstr "Dokumente nicht gefunden: %(ids)s" msgstr "Dokumente nicht gefunden: %(ids)s"
@@ -1635,36 +1635,36 @@ msgstr "URI-Schema „{parts.scheme}“ ist nicht erlaubt. Erlaubte Schemata: {'
msgid "Unable to parse URI {value}" msgid "Unable to parse URI {value}"
msgstr "URI {value} kann nicht gelesen werden" msgstr "URI {value} kann nicht gelesen werden"
#: documents/views.py:290 documents/views.py:2497 #: documents/views.py:291 documents/views.py:2538
msgid "Invalid more_like_id" msgid "Invalid more_like_id"
msgstr "Ungültige more_like_id" msgstr "Ungültige more_like_id"
#: documents/views.py:1524 #: documents/views.py:1556
msgid "Invalid AI configuration." msgid "Invalid AI configuration."
msgstr "Ungültige KI-Konfiguration." msgstr "Ungültige KI-Konfiguration."
#: documents/views.py:1533 #: documents/views.py:1565
msgid "AI backend request timed out." msgid "AI backend request timed out."
msgstr "Zeitüberschreitung bei der KI-Backendanfrage." msgstr "Zeitüberschreitung bei der KI-Backendanfrage."
#: documents/views.py:2322 documents/views.py:2643 #: documents/views.py:2363 documents/views.py:2684
msgid "Specify only one of text, title_search, query, or more_like_id." msgid "Specify only one of text, title_search, query, or more_like_id."
msgstr "Geben Sie nur einen von text, title_search, query, oder more_like_id an." msgstr "Geben Sie nur einen von text, title_search, query, oder more_like_id an."
#: documents/views.py:4471 #: documents/views.py:4512
#, python-format #, python-format
msgid "Insufficient permissions to share document %(id)s." msgid "Insufficient permissions to share document %(id)s."
msgstr "Unzureichende Berechtigungen, um Dokument %(id)s zu teilen." msgstr "Unzureichende Berechtigungen, um Dokument %(id)s zu teilen."
#: documents/views.py:4517 #: documents/views.py:4558
msgid "Bundle is already being processed." msgid "Bundle is already being processed."
msgstr "Paket wird bereits verarbeitet." msgstr "Paket wird bereits verarbeitet."
#: documents/views.py:4578 #: documents/views.py:4619
msgid "The share link bundle is still being prepared. Please try again later." msgid "The share link bundle is still being prepared. Please try again later."
msgstr "Das Freigabelink-Paket wird noch vorbereitet. Bitte versuchen Sie es später erneut." msgstr "Das Freigabelink-Paket wird noch vorbereitet. Bitte versuchen Sie es später erneut."
#: documents/views.py:4588 #: documents/views.py:4629
msgid "The share link bundle is unavailable." msgid "The share link bundle is unavailable."
msgstr "Das Freigabelink-Paket ist nicht verfügbar." msgstr "Das Freigabelink-Paket ist nicht verfügbar."
+30 -30
View File
@@ -2,8 +2,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-22 15:44+0000\n" "POT-Creation-Date: 2026-07-23 19:21+0000\n"
"PO-Revision-Date: 2026-07-22 15:48\n" "PO-Revision-Date: 2026-07-23 19:23\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Greek\n" "Language-Team: Greek\n"
"Language: el_GR\n" "Language: el_GR\n"
@@ -21,39 +21,39 @@ msgstr ""
msgid "Documents" msgid "Documents"
msgstr "Έγγραφα" msgstr "Έγγραφα"
#: documents/filters.py:464 #: documents/filters.py:470
msgid "Value must be valid JSON." msgid "Value must be valid JSON."
msgstr "Η τιμή πρέπει να είναι σε έγκυρη μορφή JSON." msgstr "Η τιμή πρέπει να είναι σε έγκυρη μορφή JSON."
#: documents/filters.py:483 #: documents/filters.py:489
msgid "Invalid custom field query expression" msgid "Invalid custom field query expression"
msgstr "Μη έγκυρη έκφραση προσαρμοσμένου ερωτήματος πεδίου" msgstr "Μη έγκυρη έκφραση προσαρμοσμένου ερωτήματος πεδίου"
#: documents/filters.py:493 #: documents/filters.py:499
msgid "Invalid expression list. Must be nonempty." msgid "Invalid expression list. Must be nonempty."
msgstr "Μη έγκυρη λίστα έκφρασης. Πρέπει να είναι μη κενή." msgstr "Μη έγκυρη λίστα έκφρασης. Πρέπει να είναι μη κενή."
#: documents/filters.py:514 #: documents/filters.py:520
msgid "Invalid logical operator {op!r}" msgid "Invalid logical operator {op!r}"
msgstr "Μη έγκυρος λογικός τελεστής {op!r}" msgstr "Μη έγκυρος λογικός τελεστής {op!r}"
#: documents/filters.py:528 #: documents/filters.py:534
msgid "Maximum number of query conditions exceeded." msgid "Maximum number of query conditions exceeded."
msgstr "Υπέρβαση μέγιστου αριθμού συνθηκών ερωτήματος." msgstr "Υπέρβαση μέγιστου αριθμού συνθηκών ερωτήματος."
#: documents/filters.py:592 #: documents/filters.py:598
msgid "{name!r} is not a valid custom field." msgid "{name!r} is not a valid custom field."
msgstr "Το προσαρμοσμένο πεδίο {name!r} δεν είναι ένα έγκυρο." msgstr "Το προσαρμοσμένο πεδίο {name!r} δεν είναι ένα έγκυρο."
#: documents/filters.py:629 #: documents/filters.py:635
msgid "{data_type} does not support query expr {expr!r}." msgid "{data_type} does not support query expr {expr!r}."
msgstr "Το {data_type} δεν υποστηρίζει το ερώτημα expr {expr!r}s." msgstr "Το {data_type} δεν υποστηρίζει το ερώτημα expr {expr!r}s."
#: documents/filters.py:744 documents/models.py:136 #: documents/filters.py:750 documents/models.py:136
msgid "Maximum nesting depth exceeded." msgid "Maximum nesting depth exceeded."
msgstr "Υπέρβαση μέγιστου βάθους εμφώλευσης." msgstr "Υπέρβαση μέγιστου βάθους εμφώλευσης."
#: documents/filters.py:1061 #: documents/filters.py:1067
msgid "Custom field not found" msgid "Custom field not found"
msgstr "Το προσαρμοσμένο πεδίο δε βρέθηκε" msgstr "Το προσαρμοσμένο πεδίο δε βρέθηκε"
@@ -1338,48 +1338,48 @@ msgstr "εκτέλεση ροής εργασίας"
msgid "workflow runs" msgid "workflow runs"
msgstr "εκτελέσεις ροής εργασίας" msgstr "εκτελέσεις ροής εργασίας"
#: documents/serialisers.py:503 documents/serialisers.py:855 #: documents/serialisers.py:522 documents/serialisers.py:874
#: documents/serialisers.py:2744 documents/views.py:297 documents/views.py:2500 #: documents/serialisers.py:2763 documents/views.py:298 documents/views.py:2541
#: paperless_mail/serialisers.py:155 #: paperless_mail/serialisers.py:155
msgid "Insufficient permissions." msgid "Insufficient permissions."
msgstr "" msgstr ""
#: documents/serialisers.py:691 #: documents/serialisers.py:710
msgid "Invalid color." msgid "Invalid color."
msgstr "Άκυρο χρώμα." msgstr "Άκυρο χρώμα."
#: documents/serialisers.py:2216 #: documents/serialisers.py:2235
#, python-format #, python-format
msgid "File type %(type)s not supported" msgid "File type %(type)s not supported"
msgstr "Ο τύπος αρχείου %(type)s δεν υποστηρίζεται" msgstr "Ο τύπος αρχείου %(type)s δεν υποστηρίζεται"
#: documents/serialisers.py:2260 #: documents/serialisers.py:2279
#, python-format #, python-format
msgid "Custom field id must be an integer: %(id)s" msgid "Custom field id must be an integer: %(id)s"
msgstr "" msgstr ""
#: documents/serialisers.py:2267 #: documents/serialisers.py:2286
#, python-format #, python-format
msgid "Custom field with id %(id)s does not exist" msgid "Custom field with id %(id)s does not exist"
msgstr "" msgstr ""
#: documents/serialisers.py:2284 documents/serialisers.py:2294 #: documents/serialisers.py:2303 documents/serialisers.py:2313
msgid "Custom fields must be a list of integers or an object mapping ids to values." msgid "Custom fields must be a list of integers or an object mapping ids to values."
msgstr "" msgstr ""
#: documents/serialisers.py:2289 #: documents/serialisers.py:2308
msgid "Some custom fields don't exist or were specified twice." msgid "Some custom fields don't exist or were specified twice."
msgstr "" msgstr ""
#: documents/serialisers.py:2436 #: documents/serialisers.py:2455
msgid "Invalid variable detected." msgid "Invalid variable detected."
msgstr "Εντοπίστηκε μη έγκυρη μεταβλητή." msgstr "Εντοπίστηκε μη έγκυρη μεταβλητή."
#: documents/serialisers.py:2800 #: documents/serialisers.py:2819
msgid "Duplicate document identifiers are not allowed." msgid "Duplicate document identifiers are not allowed."
msgstr "" msgstr ""
#: documents/serialisers.py:2830 documents/views.py:4459 #: documents/serialisers.py:2849 documents/views.py:4500
#, python-format #, python-format
msgid "Documents not found: %(ids)s" msgid "Documents not found: %(ids)s"
msgstr "" msgstr ""
@@ -1635,36 +1635,36 @@ msgstr ""
msgid "Unable to parse URI {value}" msgid "Unable to parse URI {value}"
msgstr "" msgstr ""
#: documents/views.py:290 documents/views.py:2497 #: documents/views.py:291 documents/views.py:2538
msgid "Invalid more_like_id" msgid "Invalid more_like_id"
msgstr "" msgstr ""
#: documents/views.py:1524 #: documents/views.py:1556
msgid "Invalid AI configuration." msgid "Invalid AI configuration."
msgstr "" msgstr ""
#: documents/views.py:1533 #: documents/views.py:1565
msgid "AI backend request timed out." msgid "AI backend request timed out."
msgstr "" msgstr ""
#: documents/views.py:2322 documents/views.py:2643 #: documents/views.py:2363 documents/views.py:2684
msgid "Specify only one of text, title_search, query, or more_like_id." msgid "Specify only one of text, title_search, query, or more_like_id."
msgstr "" msgstr ""
#: documents/views.py:4471 #: documents/views.py:4512
#, python-format #, python-format
msgid "Insufficient permissions to share document %(id)s." msgid "Insufficient permissions to share document %(id)s."
msgstr "" msgstr ""
#: documents/views.py:4517 #: documents/views.py:4558
msgid "Bundle is already being processed." msgid "Bundle is already being processed."
msgstr "" msgstr ""
#: documents/views.py:4578 #: documents/views.py:4619
msgid "The share link bundle is still being prepared. Please try again later." msgid "The share link bundle is still being prepared. Please try again later."
msgstr "" msgstr ""
#: documents/views.py:4588 #: documents/views.py:4629
msgid "The share link bundle is unavailable." msgid "The share link bundle is unavailable."
msgstr "" msgstr ""
+66 -66
View File
@@ -2,7 +2,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-22 15:44+0000\n" "POT-Creation-Date: 2026-07-25 07:12+0000\n"
"PO-Revision-Date: 2022-02-17 04:17\n" "PO-Revision-Date: 2022-02-17 04:17\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: English\n" "Language-Team: English\n"
@@ -21,39 +21,39 @@ msgstr ""
msgid "Documents" msgid "Documents"
msgstr "" msgstr ""
#: documents/filters.py:464 #: documents/filters.py:470
msgid "Value must be valid JSON." msgid "Value must be valid JSON."
msgstr "" msgstr ""
#: documents/filters.py:483 #: documents/filters.py:489
msgid "Invalid custom field query expression" msgid "Invalid custom field query expression"
msgstr "" msgstr ""
#: documents/filters.py:493 #: documents/filters.py:499
msgid "Invalid expression list. Must be nonempty." msgid "Invalid expression list. Must be nonempty."
msgstr "" msgstr ""
#: documents/filters.py:514 #: documents/filters.py:520
msgid "Invalid logical operator {op!r}" msgid "Invalid logical operator {op!r}"
msgstr "" msgstr ""
#: documents/filters.py:528 #: documents/filters.py:534
msgid "Maximum number of query conditions exceeded." msgid "Maximum number of query conditions exceeded."
msgstr "" msgstr ""
#: documents/filters.py:592 #: documents/filters.py:598
msgid "{name!r} is not a valid custom field." msgid "{name!r} is not a valid custom field."
msgstr "" msgstr ""
#: documents/filters.py:629 #: documents/filters.py:635
msgid "{data_type} does not support query expr {expr!r}." msgid "{data_type} does not support query expr {expr!r}."
msgstr "" msgstr ""
#: documents/filters.py:744 documents/models.py:136 #: documents/filters.py:750 documents/models.py:136
msgid "Maximum nesting depth exceeded." msgid "Maximum nesting depth exceeded."
msgstr "" msgstr ""
#: documents/filters.py:1061 #: documents/filters.py:1067
msgid "Custom field not found" msgid "Custom field not found"
msgstr "" msgstr ""
@@ -1351,49 +1351,49 @@ msgstr ""
msgid "workflow runs" msgid "workflow runs"
msgstr "" msgstr ""
#: documents/serialisers.py:503 documents/serialisers.py:855 #: documents/serialisers.py:522 documents/serialisers.py:874
#: documents/serialisers.py:2744 documents/views.py:297 documents/views.py:2500 #: documents/serialisers.py:2763 documents/views.py:298 documents/views.py:2541
#: paperless_mail/serialisers.py:155 #: paperless_mail/serialisers.py:155
msgid "Insufficient permissions." msgid "Insufficient permissions."
msgstr "" msgstr ""
#: documents/serialisers.py:691 #: documents/serialisers.py:710
msgid "Invalid color." msgid "Invalid color."
msgstr "" msgstr ""
#: documents/serialisers.py:2216 #: documents/serialisers.py:2235
#, python-format #, python-format
msgid "File type %(type)s not supported" msgid "File type %(type)s not supported"
msgstr "" msgstr ""
#: documents/serialisers.py:2260 #: documents/serialisers.py:2279
#, python-format #, python-format
msgid "Custom field id must be an integer: %(id)s" msgid "Custom field id must be an integer: %(id)s"
msgstr "" msgstr ""
#: documents/serialisers.py:2267 #: documents/serialisers.py:2286
#, python-format #, python-format
msgid "Custom field with id %(id)s does not exist" msgid "Custom field with id %(id)s does not exist"
msgstr "" msgstr ""
#: documents/serialisers.py:2284 documents/serialisers.py:2294 #: documents/serialisers.py:2303 documents/serialisers.py:2313
msgid "" msgid ""
"Custom fields must be a list of integers or an object mapping ids to values." "Custom fields must be a list of integers or an object mapping ids to values."
msgstr "" msgstr ""
#: documents/serialisers.py:2289 #: documents/serialisers.py:2308
msgid "Some custom fields don't exist or were specified twice." msgid "Some custom fields don't exist or were specified twice."
msgstr "" msgstr ""
#: documents/serialisers.py:2436 #: documents/serialisers.py:2455
msgid "Invalid variable detected." msgid "Invalid variable detected."
msgstr "" msgstr ""
#: documents/serialisers.py:2800 #: documents/serialisers.py:2819
msgid "Duplicate document identifiers are not allowed." msgid "Duplicate document identifiers are not allowed."
msgstr "" msgstr ""
#: documents/serialisers.py:2830 documents/views.py:4459 #: documents/serialisers.py:2849 documents/views.py:4500
#, python-format #, python-format
msgid "Documents not found: %(ids)s" msgid "Documents not found: %(ids)s"
msgstr "" msgstr ""
@@ -1661,36 +1661,36 @@ msgstr ""
msgid "Unable to parse URI {value}" msgid "Unable to parse URI {value}"
msgstr "" msgstr ""
#: documents/views.py:290 documents/views.py:2497 #: documents/views.py:291 documents/views.py:2538
msgid "Invalid more_like_id" msgid "Invalid more_like_id"
msgstr "" msgstr ""
#: documents/views.py:1524 #: documents/views.py:1556
msgid "Invalid AI configuration." msgid "Invalid AI configuration."
msgstr "" msgstr ""
#: documents/views.py:1533 #: documents/views.py:1565
msgid "AI backend request timed out." msgid "AI backend request timed out."
msgstr "" msgstr ""
#: documents/views.py:2322 documents/views.py:2643 #: documents/views.py:2363 documents/views.py:2684
msgid "Specify only one of text, title_search, query, or more_like_id." msgid "Specify only one of text, title_search, query, or more_like_id."
msgstr "" msgstr ""
#: documents/views.py:4471 #: documents/views.py:4512
#, python-format #, python-format
msgid "Insufficient permissions to share document %(id)s." msgid "Insufficient permissions to share document %(id)s."
msgstr "" msgstr ""
#: documents/views.py:4517 #: documents/views.py:4558
msgid "Bundle is already being processed." msgid "Bundle is already being processed."
msgstr "" msgstr ""
#: documents/views.py:4578 #: documents/views.py:4619
msgid "The share link bundle is still being prepared. Please try again later." msgid "The share link bundle is still being prepared. Please try again later."
msgstr "" msgstr ""
#: documents/views.py:4588 #: documents/views.py:4629
msgid "The share link bundle is unavailable." msgid "The share link bundle is unavailable."
msgstr "" msgstr ""
@@ -1946,151 +1946,151 @@ msgstr ""
msgid "paperless application settings" msgid "paperless application settings"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:545 #: paperless/settings/__init__.py:556
msgid "English (US)" msgid "English (US)"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:546 #: paperless/settings/__init__.py:557
msgid "Arabic" msgid "Arabic"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:547 #: paperless/settings/__init__.py:558
msgid "Afrikaans" msgid "Afrikaans"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:548 #: paperless/settings/__init__.py:559
msgid "Belarusian" msgid "Belarusian"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:549 #: paperless/settings/__init__.py:560
msgid "Bulgarian" msgid "Bulgarian"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:550 #: paperless/settings/__init__.py:561
msgid "Catalan" msgid "Catalan"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:551 #: paperless/settings/__init__.py:562
msgid "Czech" msgid "Czech"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:552 #: paperless/settings/__init__.py:563
msgid "Danish" msgid "Danish"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:553 #: paperless/settings/__init__.py:564
msgid "German" msgid "German"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:554 #: paperless/settings/__init__.py:565
msgid "Greek" msgid "Greek"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:555 #: paperless/settings/__init__.py:566
msgid "English (GB)" msgid "English (GB)"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:556 #: paperless/settings/__init__.py:567
msgid "Spanish" msgid "Spanish"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:557 #: paperless/settings/__init__.py:568
msgid "Persian" msgid "Persian"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:558 #: paperless/settings/__init__.py:569
msgid "Finnish" msgid "Finnish"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:559 #: paperless/settings/__init__.py:570
msgid "French" msgid "French"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:560 #: paperless/settings/__init__.py:571
msgid "Hungarian" msgid "Hungarian"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:561 #: paperless/settings/__init__.py:572
msgid "Indonesian" msgid "Indonesian"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:562 #: paperless/settings/__init__.py:573
msgid "Italian" msgid "Italian"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:563 #: paperless/settings/__init__.py:574
msgid "Japanese" msgid "Japanese"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:564 #: paperless/settings/__init__.py:575
msgid "Korean" msgid "Korean"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:565 #: paperless/settings/__init__.py:576
msgid "Luxembourgish" msgid "Luxembourgish"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:566 #: paperless/settings/__init__.py:577
msgid "Norwegian" msgid "Norwegian"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:567 #: paperless/settings/__init__.py:578
msgid "Dutch" msgid "Dutch"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:568 #: paperless/settings/__init__.py:579
msgid "Polish" msgid "Polish"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:569 #: paperless/settings/__init__.py:580
msgid "Portuguese (Brazil)" msgid "Portuguese (Brazil)"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:570 #: paperless/settings/__init__.py:581
msgid "Portuguese" msgid "Portuguese"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:571 #: paperless/settings/__init__.py:582
msgid "Romanian" msgid "Romanian"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:572 #: paperless/settings/__init__.py:583
msgid "Russian" msgid "Russian"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:573 #: paperless/settings/__init__.py:584
msgid "Slovak" msgid "Slovak"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:574 #: paperless/settings/__init__.py:585
msgid "Slovenian" msgid "Slovenian"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:575 #: paperless/settings/__init__.py:586
msgid "Serbian" msgid "Serbian"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:576 #: paperless/settings/__init__.py:587
msgid "Swedish" msgid "Swedish"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:577 #: paperless/settings/__init__.py:588
msgid "Turkish" msgid "Turkish"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:578 #: paperless/settings/__init__.py:589
msgid "Ukrainian" msgid "Ukrainian"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:579 #: paperless/settings/__init__.py:590
msgid "Vietnamese" msgid "Vietnamese"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:580 #: paperless/settings/__init__.py:591
msgid "Chinese Simplified" msgid "Chinese Simplified"
msgstr "" msgstr ""
#: paperless/settings/__init__.py:581 #: paperless/settings/__init__.py:592
msgid "Chinese Traditional" msgid "Chinese Traditional"
msgstr "" msgstr ""

Some files were not shown because too many files have changed in this diff Show More