Compare commits

..
22 changed files with 413 additions and 345 deletions
+1 -1
View File
@@ -86,7 +86,7 @@ jobs:
# ---- Prepare Release ----
- name: Generate requirements file
run: |
uv export --quiet --no-dev --all-extras --emit-index-url --format requirements-txt --output-file requirements.txt
uv export --quiet --no-dev --all-extras --format requirements-txt --output-file requirements.txt
- name: Compile messages
env:
PAPERLESS_SECRET_KEY: "ci-release-not-a-real-secret"
+5 -4
View File
@@ -934,10 +934,11 @@ for display in the web interface.
!!! note
The **remote OCR parser** (Azure AI) always produces a searchable
PDF and stores it as the archive copy, regardless of this setting.
`ARCHIVE_FILE_GENERATION=never` has no effect when the remote
parser handles a document.
The **remote OCR parser** (Azure AI) also honors this setting: when
no archive is requested (`never`, or `auto` with a born-digital PDF),
the remote engine is skipped entirely and locally-extracted text is
used instead, avoiding an unnecessary API call and a duplicate text
layer.
#### [`PAPERLESS_OCR_CLEAN=<mode>`](#PAPERLESS_OCR_CLEAN) {#PAPERLESS_OCR_CLEAN}
+7 -64
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
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
@@ -166,7 +166,7 @@ Remove any `PAPERLESS_OCR_SKIP_ARCHIVE_FILE` variable from your environment. If
# v2: skip OCR when text present, always archive
PAPERLESS_OCR_MODE=skip
# 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
PAPERLESS_OCR_MODE=skip_noarchive
@@ -187,10 +187,11 @@ PAPERLESS_ARCHIVE_FILE_GENERATION=auto
### Remote OCR parser
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`
has no effect for documents handled by the remote parser - the archive is produced
unconditionally by the remote engine.
If you use the **remote OCR parser** (Azure AI), `ARCHIVE_FILE_GENERATION` is
honored the same way as for the local engine: when no archive is requested
(`never`, or `auto` with a born-digital PDF), the remote engine is skipped
entirely and locally-extracted text is used instead, avoiding an unnecessary
API call and a duplicate text layer.
## Search Index (Whoosh -> Tantivy)
@@ -327,64 +328,6 @@ behind a reverse proxy may need to set
[`PAPERLESS_ALLAUTH_TRUSTED_CLIENT_IP_HEADER`](configuration.md#PAPERLESS_ALLAUTH_TRUSTED_CLIENT_IP_HEADER),
or both, to avoid `403 Forbidden` errors on login.
## 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
Some integer fields have been changed to smaller types to reduce database size. If you have any `MailRule` records with a `maximum_age` greater than 32767, they will be clamped to 32767 during the migration to avoid errors during migration.
+4 -4
View File
@@ -1996,7 +1996,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">15</context>
</context-group>
<target state="translated">Descarta-ho tot</target>
<target state="needs-translation">Dismiss all</target>
</trans-unit>
<trans-unit id="1616102757855967475" datatype="html">
<source>All</source>
@@ -2076,7 +2076,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">96</context>
</context-group>
<target state="translated">Cerca tasques</target>
<target state="needs-translation">Search tasks</target>
</trans-unit>
<trans-unit id="6849725902312323996" datatype="html">
<source>Reset filters</source>
@@ -2696,7 +2696,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">348</context>
</context-group>
<target state="translated">Confirma Descarta Tot</target>
<target state="needs-translation">Confirm Dismiss All</target>
</trans-unit>
<trans-unit id="4157200209636243740" datatype="html">
<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="linenumber">349</context>
</context-group>
<target state="translated"/>
<target state="needs-translation">Dismiss all <x id="PH" equiv-text="this.totalTasks()"/> tasks?</target>
</trans-unit>
<trans-unit id="8149502458056418229" datatype="html">
<source>Success. New document id <x id="PH" equiv-text="documentId"/> created</source>
+87 -87
View File
@@ -828,7 +828,7 @@
<context context-type="sourcefile">src/app/components/admin/logs/logs.component.html</context>
<context context-type="linenumber">18</context>
</context-group>
<target state="translated">řádků</target>
<target state="translated">řádky</target>
</trans-unit>
<trans-unit id="8838884664569764142" datatype="html">
<source>Auto refresh</source>
@@ -1352,7 +1352,7 @@
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">248</context>
</context-group>
<target state="translated">Vestavěná pole k zobrazení:</target>
<target state="needs-translation">Built-in fields to show:</target>
</trans-unit>
<trans-unit id="3467966318201103991" datatype="html">
<source>Uncheck fields to hide them on the document details page.</source>
@@ -1360,7 +1360,7 @@
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">260</context>
</context-group>
<target state="translated">Zrušte zaškrtnutí polí pro jejich skrytí na stránce s podrobnostmi o dokumentu.</target>
<target state="needs-translation">Uncheck fields to hide them on the document details page.</target>
</trans-unit>
<trans-unit id="8508424367627989968" datatype="html" approved="yes">
<source>Bulk editing</source>
@@ -1400,7 +1400,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1787</context>
</context-group>
<target state="translated">Editor PDF</target>
<target state="translated">PDF editor</target>
</trans-unit>
<trans-unit id="1577733187050997705" datatype="html">
<source>Default editing mode</source>
@@ -1964,7 +1964,7 @@
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.html</context>
<context context-type="linenumber">298</context>
</context-group>
<target state="translated">Úlohy</target>
<target state="needs-translation">Tasks</target>
</trans-unit>
<trans-unit id="8492095365580052820" datatype="html">
<source>Tasks shows detailed information about document consumption and system tasks.</source>
@@ -1972,7 +1972,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">4</context>
</context-group>
<target state="translated">Úlohy zobrazují podrobné informace o zpracování dokumentů a systémových úlohách.</target>
<target state="needs-translation">Tasks shows detailed information about document consumption and system tasks.</target>
</trans-unit>
<trans-unit id="103921551219467537" datatype="html">
<source>Clear selection</source>
@@ -1996,7 +1996,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">15</context>
</context-group>
<target state="translated">Zahodit vše</target>
<target state="needs-translation">Dismiss all</target>
</trans-unit>
<trans-unit id="1616102757855967475" datatype="html" approved="yes">
<source>All</source>
@@ -2056,7 +2056,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">215</context>
</context-group>
<target state="translated">Všechny typy</target>
<target state="needs-translation">All types</target>
</trans-unit>
<trans-unit id="131016739441837046" datatype="html">
<source>All sources</source>
@@ -2068,7 +2068,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">227</context>
</context-group>
<target state="translated">Všechny zdroje</target>
<target state="needs-translation">All sources</target>
</trans-unit>
<trans-unit id="3570013039254960445" datatype="html">
<source>Search tasks</source>
@@ -2100,7 +2100,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">126</context>
</context-group>
<target state="translated">{VAR_PLURAL, plural, few {<x id="INTERPOLATION"/> úlohy} many {<x id="INTERPOLATION"/> úloh}=1 {1 úloha} other {<x id="INTERPOLATION"/> úloh}}</target>
<target state="needs-translation">{VAR_PLURAL, plural, =1 {1 task} other {<x id="INTERPOLATION"/> tasks}}</target>
</trans-unit>
<trans-unit id="8953033926734869941" datatype="html" approved="yes">
<source>Name</source>
@@ -2444,7 +2444,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">289</context>
</context-group>
<target state="translated">Zvoleným filtrům neodpovídají žádné úlohy.</target>
<target state="needs-translation">No tasks match the current filters.</target>
</trans-unit>
<trans-unit id="2525230676386818985" datatype="html">
<source>Result</source>
@@ -2460,7 +2460,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">55</context>
</context-group>
<target state="translated">Vyžaduje pozornost</target>
<target state="needs-translation">Needs attention</target>
</trans-unit>
<trans-unit id="3307214558906712688" datatype="html">
<source>In progress</source>
@@ -2468,7 +2468,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">56</context>
</context-group>
<target state="translated">Probíhá</target>
<target state="needs-translation">In progress</target>
</trans-unit>
<trans-unit id="1371178633976505412" datatype="html">
<source>Recently completed</source>
@@ -2476,7 +2476,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">57</context>
</context-group>
<target state="translated">Nedávno dokončené</target>
<target state="needs-translation">Recently completed</target>
</trans-unit>
<trans-unit id="2936452645673957909" datatype="html">
<source>Consume File</source>
@@ -2484,7 +2484,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">66</context>
</context-group>
<target state="translated">Zpracování souboru</target>
<target state="needs-translation">Consume File</target>
</trans-unit>
<trans-unit id="5622386857946132209" datatype="html">
<source>Train Classifier</source>
@@ -2492,7 +2492,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">70</context>
</context-group>
<target state="translated">Trénování klasifikátoru</target>
<target state="needs-translation">Train Classifier</target>
</trans-unit>
<trans-unit id="776309955507105337" datatype="html">
<source>Sanity Check</source>
@@ -2500,7 +2500,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">74</context>
</context-group>
<target state="translated">Kontrola zdraví</target>
<target state="needs-translation">Sanity Check</target>
</trans-unit>
<trans-unit id="7502272564743467653" datatype="html">
<source>Mail Fetch</source>
@@ -2520,7 +2520,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">77</context>
</context-group>
<target state="translated">Index LLM</target>
<target state="needs-translation">LLM Index</target>
</trans-unit>
<trans-unit id="6402092370576716734" datatype="html">
<source>Empty Trash</source>
@@ -2528,7 +2528,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">80</context>
</context-group>
<target state="translated">Vyprázdnění koše</target>
<target state="needs-translation">Empty Trash</target>
</trans-unit>
<trans-unit id="4173754487295857311" datatype="html">
<source>Check Workflows</source>
@@ -2536,7 +2536,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">84</context>
</context-group>
<target state="translated">Kontrola postupů</target>
<target state="needs-translation">Check Workflows</target>
</trans-unit>
<trans-unit id="2065831805515896240" datatype="html">
<source>Bulk Update</source>
@@ -2544,7 +2544,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">88</context>
</context-group>
<target state="translated">Hromadná aktualizace</target>
<target state="needs-translation">Bulk Update</target>
</trans-unit>
<trans-unit id="5062348912423871240" datatype="html">
<source>Reprocess Document</source>
@@ -2552,7 +2552,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">92</context>
</context-group>
<target state="translated">Opětovné zpracování dokumentu</target>
<target state="needs-translation">Reprocess Document</target>
</trans-unit>
<trans-unit id="6903696804811148799" datatype="html">
<source>Build Share Link</source>
@@ -2560,7 +2560,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">96</context>
</context-group>
<target state="translated">Sestavení odkazu ke sdílení</target>
<target state="needs-translation">Build Share Link</target>
</trans-unit>
<trans-unit id="6581973658756561124" datatype="html">
<source>Bulk Delete</source>
@@ -2568,7 +2568,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">100</context>
</context-group>
<target state="translated">Hromadné smazání</target>
<target state="needs-translation">Bulk Delete</target>
</trans-unit>
<trans-unit id="9172233176401579786" datatype="html">
<source>Scheduled</source>
@@ -2612,7 +2612,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">119</context>
</context-group>
<target state="translated">Zpracování složky</target>
<target state="needs-translation">Folder Consume</target>
</trans-unit>
<trans-unit id="1456901843819961615" datatype="html">
<source>Email Consume</source>
@@ -2620,7 +2620,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">123</context>
</context-group>
<target state="translated">Zpracování e-mailu</target>
<target state="needs-translation">Email Consume</target>
</trans-unit>
<trans-unit id="29832309535656200" datatype="html">
<source>System</source>
@@ -2628,7 +2628,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">125</context>
</context-group>
<target state="translated">Systém</target>
<target state="needs-translation">System</target>
</trans-unit>
<trans-unit id="2233560223291461480" datatype="html">
<source>Manual</source>
@@ -2636,7 +2636,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">126</context>
</context-group>
<target state="translated">Ruční</target>
<target state="needs-translation">Manual</target>
</trans-unit>
<trans-unit id="5404910960991552159" datatype="html">
<source>Dismiss selected</source>
@@ -2652,7 +2652,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">240</context>
</context-group>
<target state="translated">Zahodit viditelné</target>
<target state="needs-translation">Dismiss visible</target>
</trans-unit>
<trans-unit id="3169751690815214293" datatype="html">
<source>Confirm Dismiss</source>
@@ -2696,7 +2696,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">348</context>
</context-group>
<target state="translated">Potvrdit zahození všech</target>
<target state="needs-translation">Confirm Dismiss All</target>
</trans-unit>
<trans-unit id="4157200209636243740" datatype="html">
<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="linenumber">349</context>
</context-group>
<target state="translated">Zahodit všech <x id="PH" equiv-text="this.totalTasks()"/> úloh?</target>
<target state="needs-translation">Dismiss all <x id="PH" equiv-text="this.totalTasks()"/> tasks?</target>
</trans-unit>
<trans-unit id="8149502458056418229" datatype="html">
<source>Success. New document id <x id="PH" equiv-text="documentId"/> created</source>
@@ -2712,7 +2712,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">408</context>
</context-group>
<target state="translated">Úspěch. Vytvořen nový dokument s ID <x id="PH" equiv-text="documentId"/></target>
<target state="needs-translation">Success. New document id <x id="PH" equiv-text="documentId"/> created</target>
</trans-unit>
<trans-unit id="8760066891202884337" datatype="html">
<source>Duplicate of document #<x id="PH" equiv-text="duplicateOf"/></source>
@@ -3540,7 +3540,7 @@
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.html</context>
<context context-type="linenumber">183</context>
</context-group>
<target state="translated">Atributy</target>
<target state="needs-translation">Attributes</target>
</trans-unit>
<trans-unit id="7437910965833684826" datatype="html" approved="yes">
<source>Correspondents</source>
@@ -3572,7 +3572,7 @@
<context context-type="sourcefile">src/app/components/manage/document-attributes/document-attributes.component.ts</context>
<context context-type="linenumber">105</context>
</context-group>
<target state="translated">Typy dokumentů</target>
<target state="needs-translation">Document types</target>
</trans-unit>
<trans-unit id="8835528846812581148" datatype="html">
<source>Storage paths</source>
@@ -3584,7 +3584,7 @@
<context context-type="sourcefile">src/app/components/manage/document-attributes/document-attributes.component.ts</context>
<context context-type="linenumber">115</context>
</context-group>
<target state="translated">Cesty úložiště</target>
<target state="needs-translation">Storage paths</target>
</trans-unit>
<trans-unit id="9149498548977462220" datatype="html">
<source>Custom fields</source>
@@ -5540,7 +5540,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html</context>
<context context-type="linenumber">26</context>
</context-group>
<target state="translated">Přístup ke stavu systému, protokolům, backendu Django</target>
<target state="needs-translation">Access system status, logs, Django backend</target>
</trans-unit>
<trans-unit id="1808271538028523977" datatype="html">
<source>Superuser</source>
@@ -5556,7 +5556,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html</context>
<context context-type="linenumber">30</context>
</context-group>
<target state="translated">Uděluje všechna oprávnění a může zobrazovat všechny objekty</target>
<target state="needs-translation">Grants all permissions and can view all objects</target>
</trans-unit>
<trans-unit id="8900662509426586619" datatype="html">
<source>Two-factor Authentication</source>
@@ -6344,7 +6344,7 @@
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
<context context-type="linenumber">271</context>
</context-group>
<target state="translated">Má kterýkoli z následujících typů dokumentů</target>
<target state="needs-translation">Has any of these document types</target>
</trans-unit>
<trans-unit id="1507843981661822403" datatype="html">
<source>Does not have document types</source>
@@ -7546,7 +7546,7 @@
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.html</context>
<context context-type="linenumber">116</context>
</context-group>
<target state="translated">Spravovat balíčky sdílení odkazů</target>
<target state="needs-translation">Manage share link bundles</target>
</trans-unit>
<trans-unit id="1070687661569746428" datatype="html">
<source>Create share link bundle</source>
@@ -7554,7 +7554,7 @@
<context context-type="sourcefile">src/app/components/common/share-link-bundle-dialog/share-link-bundle-dialog.component.ts</context>
<context context-type="linenumber">61</context>
</context-group>
<target state="translated">Vytvořit balíček sdílení odkazů</target>
<target state="needs-translation">Create share link bundle</target>
</trans-unit>
<trans-unit id="2362798555008696742" datatype="html">
<source>Create link</source>
@@ -7590,7 +7590,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="linenumber">21</context>
</context-group>
<target state="translated">Aktualizace stavu každých pár sekund během přípravy balíčků.</target>
<target state="needs-translation">Status updates every few seconds while bundles are being prepared.</target>
</trans-unit>
<trans-unit id="5194711788228004418" datatype="html">
<source>No share link bundles currently exist.</source>
@@ -7598,7 +7598,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="linenumber">25</context>
</context-group>
<target state="translated">V současné době neexistují žádné balíčky.</target>
<target state="needs-translation">No share link bundles currently exist.</target>
</trans-unit>
<trans-unit id="2841249062294860035" datatype="html">
<source>Built:</source>
@@ -7650,7 +7650,7 @@
<context context-type="sourcefile">src/app/components/common/share-link-bundle-manage-dialog/share-link-bundle-manage-dialog.component.ts</context>
<context context-type="linenumber">42</context>
</context-group>
<target state="translated">Balíčky sdílení odkazů</target>
<target state="needs-translation">Share link bundles</target>
</trans-unit>
<trans-unit id="1541995860059283227" datatype="html">
<source>Failed to load share link bundles.</source>
@@ -7658,7 +7658,7 @@
<context context-type="sourcefile">src/app/components/common/share-link-bundle-manage-dialog/share-link-bundle-manage-dialog.component.ts</context>
<context context-type="linenumber">65</context>
</context-group>
<target state="translated">Nepodařilo se načíst balíčky sdílení odkazů.</target>
<target state="needs-translation">Failed to load share link bundles.</target>
</trans-unit>
<trans-unit id="5417797597565486403" datatype="html">
<source>Error retrieving share link bundles.</source>
@@ -7942,7 +7942,7 @@
<context context-type="sourcefile">src/app/components/common/system-status-dialog/system-status-dialog.component.html</context>
<context context-type="linenumber">147</context>
</context-group>
<target state="translated">Nedávná aktivita úloh <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;small text-muted fw-light&quot;&gt;"/>(<x id="INTERPOLATION" equiv-text="{{status().tasks.summary.days}}"/> days)<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target>
<target state="needs-translation">Recent Task Activity <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;small text-muted fw-light&quot;&gt;"/>(<x id="INTERPOLATION" equiv-text="{{status().tasks.summary.days}}"/> days)<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target>
</trans-unit>
<trans-unit id="3448462145758383019" datatype="html">
<source>Total</source>
@@ -7950,7 +7950,7 @@
<context context-type="sourcefile">src/app/components/common/system-status-dialog/system-status-dialog.component.html</context>
<context context-type="linenumber">152</context>
</context-group>
<target state="translated">Celkem</target>
<target state="needs-translation">Total</target>
</trans-unit>
<trans-unit id="3521084103654700903" datatype="html">
<source>Successful</source>
@@ -7958,7 +7958,7 @@
<context context-type="sourcefile">src/app/components/common/system-status-dialog/system-status-dialog.component.html</context>
<context context-type="linenumber">156</context>
</context-group>
<target state="translated">Úspěšných</target>
<target state="needs-translation">Successful</target>
</trans-unit>
<trans-unit id="7256395947475975935" datatype="html">
<source>Failed</source>
@@ -7970,7 +7970,7 @@
<context context-type="sourcefile">src/app/data/share-link-bundle.ts</context>
<context context-type="linenumber">44</context>
</context-group>
<target state="translated">Selhané</target>
<target state="needs-translation">Failed</target>
</trans-unit>
<trans-unit id="4416413576346763682" datatype="html">
<source>Pending</source>
@@ -7982,7 +7982,7 @@
<context context-type="sourcefile">src/app/data/share-link-bundle.ts</context>
<context context-type="linenumber">41</context>
</context-group>
<target state="translated">Čekající</target>
<target state="needs-translation">Pending</target>
</trans-unit>
<trans-unit id="2000433102211963975" datatype="html">
<source>No recent tasks</source>
@@ -7990,7 +7990,7 @@
<context context-type="sourcefile">src/app/components/common/system-status-dialog/system-status-dialog.component.html</context>
<context context-type="linenumber">169</context>
</context-group>
<target state="translated">Žádné nedávné úlohy</target>
<target state="needs-translation">No recent tasks</target>
</trans-unit>
<trans-unit id="2041675390931385838" datatype="html">
<source>Health</source>
@@ -8090,7 +8090,7 @@
<context context-type="sourcefile">src/app/components/common/system-status-dialog/system-status-dialog.component.html</context>
<context context-type="linenumber">283</context>
</context-group>
<target state="translated">Index AI</target>
<target state="needs-translation">AI Index</target>
</trans-unit>
<trans-unit id="6732151329960766506" datatype="html">
<source>Copy Raw Error</source>
@@ -8660,7 +8660,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
<context context-type="linenumber">318</context>
</context-group>
<target state="translated">Původní kontrolní součet SHA256</target>
<target state="needs-translation">Original SHA256 checksum</target>
</trans-unit>
<trans-unit id="5888243105821763422" datatype="html" approved="yes">
<source>Original file size</source>
@@ -8684,7 +8684,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
<context context-type="linenumber">331</context>
</context-group>
<target state="translated">Archivní kontrolní součet SHA256</target>
<target state="needs-translation">Archive SHA256 checksum</target>
</trans-unit>
<trans-unit id="6033581412811562084" datatype="html" approved="yes">
<source>Archive file size</source>
@@ -8716,7 +8716,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
<context context-type="linenumber">368,371</context>
</context-group>
<target state="translated">Poznámky <x id="START_BLOCK_IF" equiv-text="@if (document()?.notes.length) {"/><x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;badge text-bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span"/><x id="CLOSE_BLOCK_IF" equiv-text="}"/></target>
<target state="needs-translation">Notes <x id="START_BLOCK_IF" equiv-text="@if (document()?.notes.length) {"/><x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;badge text-bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span"/><x id="CLOSE_BLOCK_IF" equiv-text="}"/></target>
</trans-unit>
<trans-unit id="186236568870281953" datatype="html">
<source>History</source>
@@ -9116,7 +9116,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-version-dropdown/document-version-dropdown.component.html</context>
<context context-type="linenumber">4</context>
</context-group>
<target state="translated">Verze</target>
<target state="needs-translation">Versions</target>
</trans-unit>
<trans-unit id="4077520913910941990" datatype="html">
<source>Label</source>
@@ -9124,7 +9124,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-version-dropdown/document-version-dropdown.component.html</context>
<context context-type="linenumber">10</context>
</context-group>
<target state="translated">Označení</target>
<target state="needs-translation">Label</target>
</trans-unit>
<trans-unit id="3915966149686975421" datatype="html">
<source>Optional</source>
@@ -9132,7 +9132,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-version-dropdown/document-version-dropdown.component.html</context>
<context context-type="linenumber">17</context>
</context-group>
<target state="translated">Volitelné</target>
<target state="needs-translation">Optional</target>
</trans-unit>
<trans-unit id="787787001194154763" datatype="html">
<source>Add new version</source>
@@ -9140,7 +9140,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-version-dropdown/document-version-dropdown.component.html</context>
<context context-type="linenumber">32</context>
</context-group>
<target state="translated">Přidat novou verzi</target>
<target state="needs-translation">Add new version</target>
</trans-unit>
<trans-unit id="3119565892291077820" datatype="html">
<source>Uploading version...</source>
@@ -9164,7 +9164,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-version-dropdown/document-version-dropdown.component.html</context>
<context context-type="linenumber">50</context>
</context-group>
<target state="translated">Nepodařilo se nahrát verzi.</target>
<target state="needs-translation">Version upload failed.</target>
</trans-unit>
<trans-unit id="6328986243040954523" datatype="html">
<source>Version label</source>
@@ -9176,7 +9176,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-version-dropdown/document-version-dropdown.component.html</context>
<context context-type="linenumber">85</context>
</context-group>
<target state="translated">Označení verze</target>
<target state="needs-translation">Version label</target>
</trans-unit>
<trans-unit id="2724055831234181057" datatype="html">
<source>Version</source>
@@ -9184,7 +9184,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-version-dropdown/document-version-dropdown.component.html</context>
<context context-type="linenumber">96</context>
</context-group>
<target state="translated">Verze</target>
<target state="needs-translation">Version</target>
</trans-unit>
<trans-unit id="2491751767883178298" datatype="html">
<source>Delete this version?</source>
@@ -9216,7 +9216,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-version-dropdown/document-version-dropdown.component.ts</context>
<context context-type="linenumber">189</context>
</context-group>
<target state="translated">Chyba při aktualizaci označení verze</target>
<target state="needs-translation">Error updating version label</target>
</trans-unit>
<trans-unit id="3567158019134759286" datatype="html">
<source>Uploading new version. Processing will happen in the background.</source>
@@ -9244,7 +9244,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-version-dropdown/document-version-dropdown.component.ts</context>
<context context-type="linenumber">271</context>
</context-group>
<target state="translated">Nahrání selhalo.</target>
<target state="needs-translation">Upload failed.</target>
</trans-unit>
<trans-unit id="8350861980330256599" datatype="html">
<source>Error uploading new version</source>
@@ -9348,7 +9348,7 @@
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.html</context>
<context context-type="linenumber">113</context>
</context-group>
<target state="translated">Vytvořit balíček sdílení odkazů</target>
<target state="needs-translation">Create a share link bundle</target>
</trans-unit>
<trans-unit id="1015374532025907183" datatype="html">
<source>Include:</source>
@@ -9755,7 +9755,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
<context context-type="linenumber">95,96</context>
</context-group>
<target state="translated">Vytvořeno: <x id="INTERPOLATION" equiv-text="{{ document().created | customDate }}"/></target>
<target state="needs-translation">Created: <x id="INTERPOLATION" equiv-text="{{ document().created | customDate }}"/></target>
</trans-unit>
<trans-unit id="2030261243264601523" datatype="html">
<source>Added: <x id="INTERPOLATION" equiv-text="{{ document().added | customDate }}"/></source>
@@ -9771,7 +9771,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
<context context-type="linenumber">96,97</context>
</context-group>
<target state="translated">Přidáno: <x id="INTERPOLATION" equiv-text="{{ document().added | customDate }}"/></target>
<target state="needs-translation">Added: <x id="INTERPOLATION" equiv-text="{{ document().added | customDate }}"/></target>
</trans-unit>
<trans-unit id="4235671847487610290" datatype="html">
<source>Modified: <x id="INTERPOLATION" equiv-text="{{ document().modified | customDate }}"/></source>
@@ -10247,7 +10247,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-list.component.ts</context>
<context context-type="linenumber">497</context>
</context-group>
<target state="translated">Pohled „<x id="PH" equiv-text="savedView.name"/>“ úspěšně vytvořen, nepodařilo se ale aktualizovat nastavení viditelnosti.</target>
<target state="needs-translation">View "<x id="PH" equiv-text="savedView.name"/>" created successfully, but could not update visibility settings.</target>
</trans-unit>
<trans-unit id="739880801667335279" datatype="html">
<source>Dates</source>
@@ -11367,7 +11367,7 @@
<context context-type="sourcefile">src/app/components/manage/saved-views/saved-views.component.html</context>
<context context-type="linenumber">35</context>
</context-group>
<target state="translated"><x id="START_TAG_I_BS" ctype="x-i_bs" equiv-text="bs class=&quot;me-1&quot; name=&quot;person-fill-lock&quot;&gt;"/><x id="CLOSE_TAG_I_BS" ctype="x-i_bs" equiv-text="Oprávnění&lt;"/>Oprávnění</target>
<target state="needs-translation"><x id="START_TAG_I_BS" ctype="x-i_bs" equiv-text="bs class=&quot;me-1&quot; name=&quot;person-fill-lock&quot;&gt;"/><x id="CLOSE_TAG_I_BS" ctype="x-i_bs" equiv-text="Permissions&lt;"/>Permissions</target>
</trans-unit>
<trans-unit id="6338800642797811873" datatype="html">
<source>Documents page size</source>
@@ -11415,7 +11415,7 @@
<context context-type="sourcefile">src/app/components/manage/saved-views/saved-views.component.html</context>
<context context-type="linenumber">62</context>
</context-group>
<target state="translated">Upozornění: pořadí nebude zachováno</target>
<target state="needs-translation">Note: ordering is not preserved</target>
</trans-unit>
<trans-unit id="7877440816920439876" datatype="html" approved="yes">
<source>No saved views defined.</source>
@@ -11864,7 +11864,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">54</context>
</context-group>
<target state="translated">Nastavení AI</target>
<target state="needs-translation">AI Settings</target>
</trans-unit>
<trans-unit id="1313137480169642057" datatype="html">
<source>Output Type</source>
@@ -11896,7 +11896,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">120</context>
</context-group>
<target state="translated">Generování archivních souborů</target>
<target state="needs-translation">Archive File Generation</target>
</trans-unit>
<trans-unit id="1115402553541327390" datatype="html">
<source>Image DPI</source>
@@ -12072,7 +12072,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">277</context>
</context-group>
<target state="translated">Rozdělení podle čárových kódů štítků</target>
<target state="needs-translation">Split on Tag Barcodes</target>
</trans-unit>
<trans-unit id="7011909364081812031" datatype="html">
<source>AI Enabled</source>
@@ -12080,7 +12080,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">284</context>
</context-group>
<target state="translated">AI povoleno</target>
<target state="needs-translation">AI Enabled</target>
</trans-unit>
<trans-unit id="8028880048909383956" datatype="html">
<source>Consider privacy implications when enabling AI features, especially if using a remote model.</source>
@@ -12088,7 +12088,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">288</context>
</context-group>
<target state="translated">Při aktivaci funkcí umělé inteligence zvažte dopady na ochranu osobních údajů, zejména pokud používáte vzdálený model.</target>
<target state="needs-translation">Consider privacy implications when enabling AI features, especially if using a remote model.</target>
</trans-unit>
<trans-unit id="8131374115579345652" datatype="html">
<source>LLM Embedding Backend</source>
@@ -12096,7 +12096,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">292</context>
</context-group>
<target state="translated">Backend pro vkládání LLM</target>
<target state="needs-translation">LLM Embedding Backend</target>
</trans-unit>
<trans-unit id="6647708571891295756" datatype="html">
<source>LLM Embedding Model</source>
@@ -12104,7 +12104,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">300</context>
</context-group>
<target state="translated">Model vkládání LLM</target>
<target state="needs-translation">LLM Embedding Model</target>
</trans-unit>
<trans-unit id="3554114880473286122" datatype="html">
<source>LLM Embedding Endpoint</source>
@@ -12112,7 +12112,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">307</context>
</context-group>
<target state="translated">Koncový bod vkládání LLM</target>
<target state="needs-translation">LLM Embedding Endpoint</target>
</trans-unit>
<trans-unit id="1044242175651289991" datatype="html">
<source>LLM Embedding Chunk Size</source>
@@ -12120,7 +12120,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">314</context>
</context-group>
<target state="translated">Velikost bloku vkládání LLM</target>
<target state="needs-translation">LLM Embedding Chunk Size</target>
</trans-unit>
<trans-unit id="7218245223139363113" datatype="html">
<source>LLM Context Size</source>
@@ -12128,7 +12128,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">321</context>
</context-group>
<target state="translated">Velikost kontextu LLM</target>
<target state="needs-translation">LLM Context Size</target>
</trans-unit>
<trans-unit id="4234495692726214397" datatype="html">
<source>LLM Backend</source>
@@ -12136,7 +12136,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">328</context>
</context-group>
<target state="translated">Backend LLM</target>
<target state="needs-translation">LLM Backend</target>
</trans-unit>
<trans-unit id="7935234833834000002" datatype="html">
<source>LLM Model</source>
@@ -12144,7 +12144,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">336</context>
</context-group>
<target state="translated">Model LLM</target>
<target state="needs-translation">LLM Model</target>
</trans-unit>
<trans-unit id="1980550530387803165" datatype="html">
<source>LLM API Key</source>
@@ -12152,7 +12152,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">343</context>
</context-group>
<target state="translated">Klíč API LLM</target>
<target state="needs-translation">LLM API Key</target>
</trans-unit>
<trans-unit id="6126617860376156501" datatype="html">
<source>LLM Endpoint</source>
@@ -12160,7 +12160,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">350</context>
</context-group>
<target state="translated">Koncový bod LLM</target>
<target state="needs-translation">LLM Endpoint</target>
</trans-unit>
<trans-unit id="6572826277249350975" datatype="html">
<source>LLM Output Language</source>
@@ -12168,7 +12168,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">357</context>
</context-group>
<target state="translated">Výstupní jazyk LLM</target>
<target state="needs-translation">LLM Output Language</target>
</trans-unit>
<trans-unit id="3284403507172415792" datatype="html">
<source>Language to use for generated AI suggestions. When unset, AI suggestions use the user&apos;s display language if explicitly set.</source>
@@ -12176,7 +12176,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">361</context>
</context-group>
<target state="translated">Jazyk, který se má použít pro návrhy generované AI. Pokud není nastaveno, návrhy AI použijí jazyk zobrazení uživatele, je-li explicitně nastaven.</target>
<target state="needs-translation">Language to use for generated AI suggestions. When unset, AI suggestions use the user's display language if explicitly set.</target>
</trans-unit>
<trans-unit id="4493921125434706859" datatype="html">
<source>LLM Request Timeout</source>
@@ -12184,7 +12184,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">365</context>
</context-group>
<target state="translated">Čawsový limit žádosti LLM</target>
<target state="needs-translation">LLM Request Timeout</target>
</trans-unit>
<trans-unit id="483994032066441287" datatype="html">
<source>Timeout in seconds for LLM requests.</source>
@@ -12192,7 +12192,7 @@
<context context-type="sourcefile">src/app/data/paperless-config.ts</context>
<context context-type="linenumber">369</context>
</context-group>
<target state="translated">Časový limit v sekundách pro žádosti LLM.</target>
<target state="needs-translation">Timeout in seconds for LLM requests.</target>
</trans-unit>
<trans-unit id="9155387182259025015" datatype="html">
<source>Processing</source>
+1 -1
View File
@@ -1528,7 +1528,7 @@
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context>
</context-group>
<target state="translated"> Die Einstellungen gelten für dieses Benutzerkonto in Bezug auf Objekte (Tags, E-Mail-Regeln usw.), die über die Weboberfläche erstellt wurden. Diese Einstellungen gelten nicht für Dokumente. </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 id="4292903881380648974" datatype="html" approved="yes">
<source>Default Owner</source>
+23 -23
View File
@@ -1528,7 +1528,7 @@
<context context-type="sourcefile">src/app/components/admin/settings/settings.component.html</context>
<context context-type="linenumber">306,308</context>
</context-group>
<target state="translated"> Nastavitve veljajo za ta uporabniški račun za objekte (oznake, pravila za pošto itd.), ustvarjene prek spletnega uporabniškega vmesnika. Te nastavitve ne veljajo za dokumente. </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 id="4292903881380648974" datatype="html">
<source>Default Owner</source>
@@ -2076,7 +2076,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.html</context>
<context context-type="linenumber">96</context>
</context-group>
<target state="translated">Iskanje nalog</target>
<target state="needs-translation">Search tasks</target>
</trans-unit>
<trans-unit id="6849725902312323996" datatype="html">
<source>Reset filters</source>
@@ -2704,7 +2704,7 @@
<context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
<context context-type="linenumber">349</context>
</context-group>
<target state="translated">Opustim vse naloge <x id="PH" equiv-text="this.totalTasks()"/>?</target>
<target state="needs-translation">Dismiss all <x id="PH" equiv-text="this.totalTasks()"/> tasks?</target>
</trans-unit>
<trans-unit id="8149502458056418229" datatype="html">
<source>Success. New document id <x id="PH" equiv-text="documentId"/> created</source>
@@ -7378,7 +7378,7 @@
<context context-type="sourcefile">src/app/components/common/share-link-bundle-dialog/share-link-bundle-dialog.component.html</context>
<context context-type="linenumber">22</context>
</context-group>
<target state="translated">+ <x id="INTERPOLATION" equiv-text="{{ selectionCount() - documentPreview().length }}"/> več…</target>
<target state="needs-translation">+ <x id="INTERPOLATION" equiv-text="{{ selectionCount() - documentPreview().length }}"/> more…</target>
</trans-unit>
<trans-unit id="8037476586059399916" datatype="html">
<source>Expires</source>
@@ -7478,7 +7478,7 @@
<context context-type="sourcefile">src/app/components/common/share-link-bundle-dialog/share-link-bundle-dialog.component.html</context>
<context context-type="linenumber">68</context>
</context-group>
<target state="translated">Deli povezavo</target>
<target state="needs-translation">Share link</target>
</trans-unit>
<trans-unit id="2618101617221155143" datatype="html">
<source>Copy link</source>
@@ -7942,7 +7942,7 @@
<context context-type="sourcefile">src/app/components/common/system-status-dialog/system-status-dialog.component.html</context>
<context context-type="linenumber">147</context>
</context-group>
<target state="translated">Nedavna aktivnost opravila <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;small text-muted fw-light&quot;&gt;"/>(<x id="INTERPOLATION" equiv-text="{{status().tasks.summary.days}}"/> dni)<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target>
<target state="needs-translation">Recent Task Activity <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;small text-muted fw-light&quot;&gt;"/>(<x id="INTERPOLATION" equiv-text="{{status().tasks.summary.days}}"/> days)<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target>
</trans-unit>
<trans-unit id="3448462145758383019" datatype="html">
<source>Total</source>
@@ -8416,7 +8416,7 @@
<context context-type="sourcefile">src/app/components/document-asn/document-asn.component.html</context>
<context context-type="linenumber">1</context>
</context-group>
<target state="translated">Iskanje dokumenta z asn <x id="INTERPOLATION" equiv-text="{{asn()}}"/></target>
<target state="needs-translation">Searching document with asn <x id="INTERPOLATION" equiv-text="{{asn()}}"/></target>
</trans-unit>
<trans-unit id="1407560924967345762" datatype="html">
<source>Page</source>
@@ -8440,7 +8440,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
<context context-type="linenumber">7,8</context>
</context-group>
<target state="translated">od <x id="INTERPOLATION" equiv-text="{{previewNumPages()}}"/></target>
<target state="needs-translation">of <x id="INTERPOLATION" equiv-text="{{previewNumPages()}}"/></target>
</trans-unit>
<trans-unit id="8590109102084543521" datatype="html">
<source>-</source>
@@ -8660,7 +8660,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
<context context-type="linenumber">318</context>
</context-group>
<target state="translated">Izvirna kontrolna vsota SHA256</target>
<target state="needs-translation">Original SHA256 checksum</target>
</trans-unit>
<trans-unit id="5888243105821763422" datatype="html">
<source>Original file size</source>
@@ -8684,7 +8684,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
<context context-type="linenumber">331</context>
</context-group>
<target state="translated">Arhivska kontrolna vsota SHA256</target>
<target state="needs-translation">Archive SHA256 checksum</target>
</trans-unit>
<trans-unit id="6033581412811562084" datatype="html">
<source>Archive file size</source>
@@ -8716,7 +8716,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
<context context-type="linenumber">368,371</context>
</context-group>
<target state="translated">Opombe <x id="START_BLOCK_IF" equiv-text="@if (document()?.notes.length) {"/><x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;badge text-bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span"/><x id="CLOSE_BLOCK_IF" equiv-text="}"/></target>
<target state="needs-translation">Notes <x id="START_BLOCK_IF" equiv-text="@if (document()?.notes.length) {"/><x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;badge text-bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="length}}"/><x id="CLOSE_TAG_SPAN" ctype="x-span"/><x id="CLOSE_BLOCK_IF" equiv-text="}"/></target>
</trans-unit>
<trans-unit id="186236568870281953" datatype="html">
<source>History</source>
@@ -8732,7 +8732,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
<context context-type="linenumber">401,405</context>
</context-group>
<target state="translated"> Dvojniki <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;badge text-bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="cate_documents.length }}"/><x id="CLOSE_TAG_SPAN" ctype="x-span"/></target>
<target state="needs-translation"> Duplicates <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;badge text-bg-secondary ms-1&quot;&gt;"/><x id="INTERPOLATION" equiv-text="cate_documents.length }}"/><x id="CLOSE_TAG_SPAN" ctype="x-span"/></target>
</trans-unit>
<trans-unit id="6449374629822973702" datatype="html">
<source>Duplicate documents detected:</source>
@@ -8936,7 +8936,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1271</context>
</context-group>
<target state="translated">Napaka pri shranjevanju dokumenta "<x id="PH" equiv-text="this.document().title"/>"</target>
<target state="needs-translation">Error saving document "<x id="PH" equiv-text="this.document().title"/>"</target>
</trans-unit>
<trans-unit id="448882439049417053" datatype="html">
<source>Error saving document</source>
@@ -8952,7 +8952,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1359</context>
</context-group>
<target state="translated">Ali res želite premakniti dokument "<x id="PH" equiv-text="this.document().title"/>" v koš?</target>
<target state="needs-translation">Do you really want to move the document "<x id="PH" equiv-text="this.document().title"/>" to the trash?</target>
</trans-unit>
<trans-unit id="282586936710748252" datatype="html">
<source>Documents can be restored prior to permanent deletion.</source>
@@ -9008,7 +9008,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1413</context>
</context-group>
<target state="translated">V ozadju se bo začel postopek ponovne obdelave za "<x id="PH" equiv-text="this.document().title"/>".</target>
<target state="needs-translation">Reprocess operation for "<x id="PH" equiv-text="this.document().title"/>" will begin in the background.</target>
</trans-unit>
<trans-unit id="4409560272830824468" datatype="html">
<source>Error executing operation</source>
@@ -9040,7 +9040,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1808</context>
</context-group>
<target state="translated">Urejanje PDF-ja za "<x id="PH" equiv-text="this.document().title"/>" se bo začelo v ozadju.</target>
<target state="needs-translation">PDF edit operation for "<x id="PH" equiv-text="this.document().title"/>" will begin in the background.</target>
</trans-unit>
<trans-unit id="9043972994040261999" datatype="html">
<source>Error executing PDF edit operation</source>
@@ -9064,7 +9064,7 @@
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1865</context>
</context-group>
<target state="translated">Operacija odstranitve gesla za "<x id="PH" equiv-text="this.document().title"/>" se bo začela v ozadju.</target>
<target state="needs-translation">Password removal operation for "<x id="PH" equiv-text="this.document().title"/>" will begin in the background.</target>
</trans-unit>
<trans-unit id="2282118435712883014" datatype="html">
<source>Error executing password removal operation</source>
@@ -9720,7 +9720,7 @@
<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-group>
<target state="translated"><x id="INTERPOLATION" equiv-text="document().title | documentTitle }}"/> sličica</target>
<target state="needs-translation"><x id="INTERPOLATION" equiv-text="document().title | documentTitle }}"/> thumbnail</target>
</trans-unit>
<trans-unit id="2784168796433474565" datatype="html">
<source>Filter by tag</source>
@@ -9756,7 +9756,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
<context context-type="linenumber">95,96</context>
</context-group>
<target state="translated">Ustvarjeno: <x id="INTERPOLATION" equiv-text="{{ document().created | customDate }}"/></target>
<target state="needs-translation">Created: <x id="INTERPOLATION" equiv-text="{{ document().created | customDate }}"/></target>
</trans-unit>
<trans-unit id="2030261243264601523" datatype="html">
<source>Added: <x id="INTERPOLATION" equiv-text="{{ document().added | customDate }}"/></source>
@@ -9772,7 +9772,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
<context context-type="linenumber">96,97</context>
</context-group>
<target state="translated">Dodano: <x id="INTERPOLATION" equiv-text="{{ document().added | customDate }}"/></target>
<target state="needs-translation">Added: <x id="INTERPOLATION" equiv-text="{{ document().added | customDate }}"/></target>
</trans-unit>
<trans-unit id="4235671847487610290" datatype="html">
<source>Modified: <x id="INTERPOLATION" equiv-text="{{ document().modified | customDate }}"/></source>
@@ -9788,7 +9788,7 @@
<context context-type="sourcefile">src/app/components/document-list/document-card-small/document-card-small.component.html</context>
<context context-type="linenumber">97,98</context>
</context-group>
<target state="translated">Spremenjeno: <x id="INTERPOLATION" equiv-text="{{ document().modified | customDate }}"/></target>
<target state="needs-translation">Modified: <x id="INTERPOLATION" equiv-text="{{ document().modified | customDate }}"/></target>
</trans-unit>
<trans-unit id="197162226430950645" datatype="html">
<source>{VAR_PLURAL, plural, =1 {1 page} other {<x id="INTERPOLATION"/> pages}}</source>
@@ -11312,7 +11312,7 @@
<context context-type="sourcefile">src/app/components/manage/mail/processed-mail-dialog/processed-mail-dialog.component.html</context>
<context context-type="linenumber">2</context>
</context-group>
<target state="translated">Obdelana pošta za <x id="START_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;em&gt;"/><x id="INTERPOLATION" equiv-text="{{ rule().name }}"/><x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/></target>
<target state="needs-translation">Processed Mail for <x id="START_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;em&gt;"/><x id="INTERPOLATION" equiv-text="{{ rule().name }}"/><x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/></target>
</trans-unit>
<trans-unit id="1991019495862291373" datatype="html">
<source>No processed email messages found.</source>
@@ -11328,7 +11328,7 @@
<context context-type="sourcefile">src/app/components/manage/mail/processed-mail-dialog/processed-mail-dialog.component.html</context>
<context context-type="linenumber">29</context>
</context-group>
<target state="translated">Izberi vsa obdelana e-poštna sporočila</target>
<target state="needs-translation">Select all processed email messages</target>
</trans-unit>
<trans-unit id="8691920320483720007" datatype="html">
<source>Received</source>
+1 -11
View File
@@ -1264,17 +1264,7 @@ def task_failure_handler(
"error_message": str(exception) if exception else "Unknown error",
}
if 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),
)
)
tb_str = "".join(_tb.format_tb(traceback))
result_data["traceback"] = tb_str[:5000]
now = timezone.now()
+3 -3
View File
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-23 19:21+0000\n"
"PO-Revision-Date: 2026-07-25 00:51\n"
"PO-Revision-Date: 2026-07-23 19:23\n"
"Last-Translator: \n"
"Language-Team: Catalan\n"
"Language: ca_ES\n"
@@ -1914,7 +1914,7 @@ msgstr "Estableix l'idioma de sortida de LLM"
#: paperless/models.py:370
msgid "Sets the LLM timeout in seconds"
msgstr "Estableix temps d'espera en segons"
msgstr ""
#: paperless/models.py:376
msgid "paperless application settings"
@@ -2386,7 +2386,7 @@ msgstr "uid"
#: paperless_mail/models.py:342
msgid "uid validity"
msgstr "validació uid"
msgstr ""
#: paperless_mail/models.py:350
msgid "subject"
+36 -36
View File
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-23 19:21+0000\n"
"PO-Revision-Date: 2026-07-25 00:51\n"
"PO-Revision-Date: 2026-07-23 19:23\n"
"Last-Translator: \n"
"Language-Team: Czech\n"
"Language: cs_CZ\n"
@@ -261,11 +261,11 @@ msgstr ""
#: documents/models.py:331
msgid "version label"
msgstr "označení verze"
msgstr ""
#: documents/models.py:335
msgid "Optional short label for a document version."
msgstr "Volitelné krátké označení verze dokumentu."
msgstr ""
#: documents/models.py:340 documents/models.py:851 documents/models.py:905
#: documents/models.py:1892
@@ -582,7 +582,7 @@ msgstr "filtrovací pravidla"
#: documents/models.py:679 documents/models.py:934
msgid "Pending"
msgstr "Čekající"
msgstr ""
#: documents/models.py:680 documents/models.py:757
msgid "Started"
@@ -602,7 +602,7 @@ msgstr ""
#: documents/models.py:686
msgid "Consume File"
msgstr "Zpracování souboru"
msgstr "Soubor zpracování"
#: documents/models.py:687
msgid "Train Classifier"
@@ -610,7 +610,7 @@ msgstr "Trénovací klasifikátor"
#: documents/models.py:688
msgid "Sanity Check"
msgstr "Kontrola zdraví"
msgstr ""
#: documents/models.py:689
msgid "Index Optimize"
@@ -622,31 +622,31 @@ msgstr "Načíst poštu"
#: documents/models.py:691
msgid "LLM Index"
msgstr "Index LLM"
msgstr ""
#: documents/models.py:692
msgid "Empty Trash"
msgstr "Vyprázdnění koše"
msgstr ""
#: documents/models.py:693
msgid "Check Workflows"
msgstr "Kontrola postupů"
msgstr ""
#: documents/models.py:694
msgid "Bulk Update"
msgstr "Hromadná aktualizace"
msgstr ""
#: documents/models.py:695
msgid "Reprocess Document"
msgstr "Opětovné zpracování dokumentu"
msgstr ""
#: documents/models.py:696
msgid "Build Share Link"
msgstr "Sestavení odkazu ke sdílení"
msgstr ""
#: documents/models.py:697
msgid "Bulk Delete"
msgstr "Hromadné smazání"
msgstr ""
#: documents/models.py:706 documents/models.py:1277
msgid "Scheduled"
@@ -662,19 +662,19 @@ msgstr ""
#: documents/models.py:709
msgid "Folder Consume"
msgstr "Zpracování složky"
msgstr ""
#: documents/models.py:710
msgid "Email Consume"
msgstr "Zpracování e-mailu"
msgstr ""
#: documents/models.py:711
msgid "System"
msgstr "Systém"
msgstr ""
#: documents/models.py:712
msgid "Manual"
msgstr "Ruční"
msgstr ""
#: documents/models.py:718
msgid "Task ID"
@@ -750,7 +750,7 @@ msgstr ""
#: documents/models.py:806
msgid "Tasks"
msgstr "Úlohy"
msgstr ""
#: documents/models.py:836
msgid "Note for the document"
@@ -802,7 +802,7 @@ msgstr ""
#: documents/models.py:937
msgid "Failed"
msgstr "Selhané"
msgstr ""
#: documents/models.py:984
msgid "size (bytes)"
@@ -826,7 +826,7 @@ msgstr ""
#: documents/models.py:1017
msgid "share link bundles"
msgstr "balíčky sdílení odkazů"
msgstr ""
#: documents/models.py:1020
#, python-format
@@ -971,7 +971,7 @@ msgstr "má tento typ dokumentu"
#: documents/models.py:1377
msgid "has one of these document types"
msgstr "má jeden z následujících typů dokumentů"
msgstr ""
#: documents/models.py:1384
msgid "does not have these document type(s)"
@@ -1342,7 +1342,7 @@ msgstr "spuštění pracovních postupů"
#: documents/serialisers.py:2763 documents/views.py:298 documents/views.py:2541
#: paperless_mail/serialisers.py:155
msgid "Insufficient permissions."
msgstr "Nedostatečná oprávnění."
msgstr ""
#: documents/serialisers.py:710
msgid "Invalid color."
@@ -1655,7 +1655,7 @@ msgstr ""
#: documents/views.py:4512
#, python-format
msgid "Insufficient permissions to share document %(id)s."
msgstr "Nedostatečná oprávnění ke sdílení dokumentu %(id)s."
msgstr ""
#: documents/views.py:4558
msgid "Bundle is already being processed."
@@ -1779,7 +1779,7 @@ msgstr "Nastaví režim OCR"
#: paperless/models.py:131
msgid "Controls archive file generation"
msgstr "Ovládá generování archivních souborů"
msgstr ""
#: paperless/models.py:139
msgid "Sets image DPI fallback value"
@@ -1867,7 +1867,7 @@ msgstr "Nastaví mapování čárových kódů na štítky"
#: paperless/models.py:285
msgid "Enables splitting on tag barcodes"
msgstr "Umožňuje rozdělení podle čárových kódů štítků"
msgstr ""
#: paperless/models.py:294
msgid "Enables AI features"
@@ -1875,47 +1875,47 @@ msgstr ""
#: paperless/models.py:300
msgid "Sets the LLM embedding backend"
msgstr "Nastaví backend pro vkládání LLM"
msgstr ""
#: paperless/models.py:308
msgid "Sets the LLM embedding model"
msgstr "Nastaví model vkládání LLM"
msgstr ""
#: paperless/models.py:315
msgid "Sets the LLM embedding endpoint, optional"
msgstr "Nastaví koncový bod vkládání LLM, volitelné"
msgstr ""
#: paperless/models.py:322
msgid "Sets the LLM embedding chunk size"
msgstr "Nastaví velikost bloků vkládání LLM"
msgstr ""
#: paperless/models.py:328
msgid "Sets the LLM context size"
msgstr "Nastaví velikost kontextu LLM"
msgstr ""
#: paperless/models.py:334
msgid "Sets the LLM backend"
msgstr "Nastaví backend LLM"
msgstr ""
#: paperless/models.py:342
msgid "Sets the LLM model"
msgstr "Nastaví model LLM"
msgstr ""
#: paperless/models.py:349
msgid "Sets the LLM API key"
msgstr "Nastaví klíč API LLM"
msgstr ""
#: paperless/models.py:356
msgid "Sets the LLM endpoint, optional"
msgstr "Nastaví koncový bod LLM, volitelné"
msgstr ""
#: paperless/models.py:363
msgid "Sets the LLM output language"
msgstr "Nastaví výstupní jazyk LLM"
msgstr ""
#: paperless/models.py:370
msgid "Sets the LLM timeout in seconds"
msgstr "Nastaví časový limit LLM v sekundách"
msgstr ""
#: paperless/models.py:376
msgid "paperless application settings"
+1 -1
View File
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-23 19:21+0000\n"
"PO-Revision-Date: 2026-07-23 22:54\n"
"PO-Revision-Date: 2026-07-23 19:23\n"
"Last-Translator: \n"
"Language-Team: German\n"
"Language: de_DE\n"
+30 -30
View File
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-23 19:21+0000\n"
"PO-Revision-Date: 2026-07-25 00:51\n"
"PO-Revision-Date: 2026-07-23 19:23\n"
"Last-Translator: \n"
"Language-Team: Dutch\n"
"Language: nl_NL\n"
@@ -558,11 +558,11 @@ msgstr "mimetype is"
#: documents/models.py:632
msgid "simple title search"
msgstr "eenvoudige titel zoeken"
msgstr ""
#: documents/models.py:633
msgid "simple text search"
msgstr "eenvoudige tekst zoeken"
msgstr ""
#: documents/models.py:643
msgid "rule type"
@@ -586,19 +586,19 @@ msgstr "In behandeling"
#: documents/models.py:680 documents/models.py:757
msgid "Started"
msgstr "Gestart"
msgstr ""
#: documents/models.py:681
msgid "Success"
msgstr "Geslaagd"
msgstr ""
#: documents/models.py:682
msgid "Failure"
msgstr "Mislukt"
msgstr ""
#: documents/models.py:683
msgid "Revoked"
msgstr "Ingetrokken"
msgstr ""
#: documents/models.py:686
msgid "Consume File"
@@ -606,15 +606,15 @@ msgstr "Gebruik bestand"
#: documents/models.py:687
msgid "Train Classifier"
msgstr "Train Classifier"
msgstr ""
#: documents/models.py:688
msgid "Sanity Check"
msgstr "Gezondheidscheck"
msgstr ""
#: documents/models.py:689
msgid "Index Optimize"
msgstr "Index Optimaliseren"
msgstr ""
#: documents/models.py:690 documents/models.py:1282
msgid "Mail Fetch"
@@ -622,23 +622,23 @@ msgstr "E-mails ophalen"
#: documents/models.py:691
msgid "LLM Index"
msgstr "LLM Index"
msgstr ""
#: documents/models.py:692
msgid "Empty Trash"
msgstr "Prullenbak legen"
msgstr ""
#: documents/models.py:693
msgid "Check Workflows"
msgstr "Controleer Workflows"
msgstr ""
#: documents/models.py:694
msgid "Bulk Update"
msgstr "Bulk bijwerken"
msgstr ""
#: documents/models.py:695
msgid "Reprocess Document"
msgstr "Document opnieuw verwerken"
msgstr ""
#: documents/models.py:696
msgid "Build Share Link"
@@ -646,7 +646,7 @@ msgstr "Bouw Deel Link"
#: documents/models.py:697
msgid "Bulk Delete"
msgstr "Bulk verwijderen"
msgstr ""
#: documents/models.py:706 documents/models.py:1277
msgid "Scheduled"
@@ -658,23 +658,23 @@ msgstr "Web interface"
#: documents/models.py:708
msgid "API Upload"
msgstr "API Upload"
msgstr ""
#: documents/models.py:709
msgid "Folder Consume"
msgstr "Map inlezen"
msgstr ""
#: documents/models.py:710
msgid "Email Consume"
msgstr "Email Inlezen"
msgstr ""
#: documents/models.py:711
msgid "System"
msgstr "Systeem"
msgstr ""
#: documents/models.py:712
msgid "Manual"
msgstr "Handmatig"
msgstr ""
#: documents/models.py:718
msgid "Task ID"
@@ -682,7 +682,7 @@ msgstr "Taak ID"
#: documents/models.py:719
msgid "Celery task ID"
msgstr "Celery taak ID"
msgstr ""
#: documents/models.py:725
msgid "Task Type"
@@ -690,35 +690,35 @@ msgstr "Taak type"
#: documents/models.py:726
msgid "The kind of work being performed"
msgstr "Het soort werk dat wordt uitgevoerd"
msgstr ""
#: documents/models.py:733
msgid "Trigger Source"
msgstr "Trigger bron"
msgstr ""
#: documents/models.py:734
msgid "What initiated this task"
msgstr "Wat begon deze taak"
msgstr ""
#: documents/models.py:743
msgid "Status"
msgstr "Status"
msgstr ""
#: documents/models.py:763
msgid "Completed"
msgstr "Voltooid"
msgstr ""
#: documents/models.py:771
msgid "Duration (seconds)"
msgstr "Duur (seconden)"
msgstr ""
#: documents/models.py:772
msgid "Elapsed time from start to completion"
msgstr "Verstreken tijd van begin tot voltooiing"
msgstr ""
#: documents/models.py:778
msgid "Wait Time (seconds)"
msgstr "Wachttijd (seconden)"
msgstr ""
#: documents/models.py:779
msgid "Time from task creation to worker pickup"
+2 -2
View File
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-23 19:21+0000\n"
"PO-Revision-Date: 2026-07-24 12:40\n"
"PO-Revision-Date: 2026-07-23 19:23\n"
"Last-Translator: \n"
"Language-Team: Slovenian\n"
"Language: sl_SI\n"
@@ -2386,7 +2386,7 @@ msgstr "uid"
#: paperless_mail/models.py:342
msgid "uid validity"
msgstr "veljavnost uid-a"
msgstr ""
#: paperless_mail/models.py:350
msgid "subject"
+4 -4
View File
@@ -272,7 +272,10 @@ class MailDocumentParser:
logger.debug("Building formatted text from email")
self._text = build_formatted_text(mail)
self._date = mail.date
if is_naive(mail.date):
self._date = make_aware(mail.date)
else:
self._date = mail.date
logger.debug("Creating a PDF from the email")
if self._mailrule_id:
@@ -499,9 +502,6 @@ class MailDocumentParser:
f"Could not parse {filepath}: {err}",
) from err
if is_naive(parsed.date):
parsed.date = make_aware(parsed.date)
return parsed
def tika_parse(self, html: str) -> str:
+33 -7
View File
@@ -3,7 +3,9 @@ Built-in remote-OCR document parser.
Handles documents by sending them to a configured remote OCR engine
(currently Azure AI Vision / Document Intelligence) and retrieving both
the extracted text and a searchable PDF with an embedded text layer.
the extracted text and a searchable PDF with an embedded text layer. For
born-digital PDFs that need no archive copy, the remote call is skipped
entirely in favor of locally-extracted text (see ``RemoteDocumentParser.parse``).
When no engine is configured, ``score()`` returns ``None`` so the parser
is effectively invisible to the registry the tesseract parser handles
@@ -21,6 +23,8 @@ from typing import Self
from django.conf import settings
from paperless.parsers.utils import extract_pdf_text
from paperless.parsers.utils import post_process_text
from paperless.version import __full_version_str__
if TYPE_CHECKING:
@@ -69,8 +73,11 @@ class RemoteDocumentParser:
"""Parse documents via a remote OCR API (currently Azure AI Vision).
This parser sends documents to a remote engine that returns both
extracted text and a searchable PDF with an embedded text layer.
It does not depend on Tesseract or ocrmypdf.
extracted text and a searchable PDF with an embedded text layer,
except when ``parse()`` is called with ``produce_archive=False`` for
a PDF, in which case the remote call is skipped and only locally
extracted text is returned (no archive). It does not depend on
Tesseract or ocrmypdf.
Class attributes
----------------
@@ -159,8 +166,11 @@ class RemoteDocumentParser:
Returns
-------
bool
Always True the remote engine always returns a PDF with an
embedded text layer that serves as the archive copy.
Always True the remote engine is capable of returning a PDF
with an embedded text layer to serve as the archive copy.
Whether it actually does so for a given document depends on
``produce_archive`` passed to :meth:`parse` (see there for when
the remote engine call, and thus archive generation, is skipped).
"""
return True
@@ -217,6 +227,12 @@ class RemoteDocumentParser:
) -> None:
"""Send the document to the remote engine and store results.
When *produce_archive* is False for a PDF, the caller (via
``documents.consumer.should_produce_archive``) has already determined
that the document is born-digital and needs no archive skip the
remote engine entirely rather than re-OCRing it and creating a
duplicate text layer.
Parameters
----------
document_path:
@@ -224,8 +240,8 @@ class RemoteDocumentParser:
mime_type:
Detected MIME type of the document.
produce_archive:
Ignored the remote engine always returns a searchable PDF,
which is stored as the archive copy regardless of this flag.
Whether an archive copy is wanted. For PDFs, False skips the
remote engine and uses locally-extracted text instead.
"""
config = RemoteEngineConfig(
engine=settings.REMOTE_OCR_ENGINE,
@@ -240,6 +256,16 @@ class RemoteDocumentParser:
self._text = ""
return
if not produce_archive and mime_type == "application/pdf":
logger.debug(
"Remote OCR: skipped — no archive requested, "
"using locally-extracted text",
)
self._text = (
post_process_text(extract_pdf_text(document_path, log=logger)) or ""
)
return
if config.engine == "azureai":
self._text = self._azure_ai_vision_parse(document_path, config)
+6 -19
View File
@@ -3,7 +3,6 @@ from __future__ import annotations
import importlib.resources
import logging
import os
import re
import shutil
import tempfile
from pathlib import Path
@@ -25,9 +24,9 @@ from paperless.config import OcrConfig
from paperless.models import CleanChoices
from paperless.models import ModeChoices
from paperless.models import OutputTypeChoices
from paperless.parsers.utils import PDF_TEXT_MIN_LENGTH
from paperless.parsers.utils import extract_pdf_text
from paperless.parsers.utils import is_tagged_pdf
from paperless.parsers.utils import pdf_has_digital_text
from paperless.parsers.utils import post_process_text
from paperless.parsers.utils import read_file_handle_unicode_errors
from paperless.version import __full_version_str__
@@ -510,8 +509,10 @@ class RasterisedDocumentParser:
if mime_type == "application/pdf":
text_original = self.extract_text(None, document_path)
original_has_text = is_tagged_pdf(document_path, log=self.log) or (
text_original is not None and len(text_original) > PDF_TEXT_MIN_LENGTH
original_has_text = pdf_has_digital_text(
document_path,
text_original,
log=self.log,
)
else:
text_original = None
@@ -656,17 +657,3 @@ class RasterisedDocumentParser:
f"No text was found in {document_path}, the content will be empty.",
)
self.text = ""
def post_process_text(text: str | None) -> str | None:
if not text:
return None
collapsed_spaces = re.sub(r"([^\S\r\n]+)", " ", text)
no_leading_whitespace = re.sub(r"([\n\r]+)([^\S\n\r]+)", "\\1", collapsed_spaces)
no_trailing_whitespace = re.sub(r"([^\S\n\r]+)$", "", no_leading_whitespace)
# TODO: this needs a rework
# replace \0 prevents issues with saving to postgres.
# text may contain \0 when this character is present in PDF files.
return no_trailing_whitespace.strip().replace("\0", " ")
-5
View File
@@ -421,11 +421,6 @@ class TikaDocumentParser:
logger.info("Converting %s to PDF as %s", document_path, pdf_path)
with self._gotenberg_client.libre_office.to_pdf() as route:
# Preserve document fields as authored. updateIndexes (Gotenberg's
# default) triggers a refresh() that rewrites dynamic fields like
# auto-dates to the current date.
route.update_indexes(update_indexes=False)
# Set the output format of the resulting PDF.
# OutputTypeConfig reads the database-stored ApplicationConfiguration
# first, then falls back to the PAPERLESS_OCR_OUTPUT_TYPE env var.
+57
View File
@@ -65,6 +65,63 @@ def is_tagged_pdf(
return False
def pdf_has_digital_text(
path: Path,
text: str | None,
log: logging.Logger | None = None,
) -> bool:
"""Return True if a PDF already has a usable, born-digital text layer.
Combines the tagged-PDF check with an extracted-text length check.
Shared by the tesseract and remote OCR parsers to decide whether
OCR_MODE=auto/off should skip (re-)OCRing a document.
Parameters
----------
path:
Absolute path to the PDF file.
text:
Text already extracted from the PDF (e.g. via ``extract_pdf_text``),
or ``None``.
log:
Logger for warnings. Falls back to the module-level logger when omitted.
Returns
-------
bool
``True`` when the document already contains a text layer.
"""
return is_tagged_pdf(path, log=log) or (
text is not None and len(text) > PDF_TEXT_MIN_LENGTH
)
def post_process_text(text: str | None) -> str | None:
"""Normalise whitespace in extracted OCR/PDF text and strip NUL bytes.
Parameters
----------
text:
Raw extracted text, or ``None``.
Returns
-------
str | None
Cleaned text, or ``None`` when *text* is falsy.
"""
if not text:
return None
collapsed_spaces = re.sub(r"([^\S\r\n]+)", " ", text)
no_leading_whitespace = re.sub(r"([\n\r]+)([^\S\n\r]+)", "\\1", collapsed_spaces)
no_trailing_whitespace = re.sub(r"([^\S\n\r]+)$", "", no_leading_whitespace)
# TODO: this needs a rework
# replace \0 prevents issues with saving to postgres.
# text may contain \0 when this character is present in PDF files.
return no_trailing_whitespace.strip().replace("\0", " ")
def extract_pdf_text(
path: Path,
log: logging.Logger | None = None,
@@ -145,41 +145,6 @@ class TestEmailFileParsing:
assert parsed_msg.text == "This is just a simple Text Mail.\n"
assert parsed_msg.to == ("some@one.de",)
def test_parse_file_to_message_makes_naive_date_aware(
self,
mocker: MockerFixture,
mail_parser: MailDocumentParser,
simple_txt_email_file: Path,
) -> None:
"""
GIVEN:
- An email whose parsed date is naive (no tzinfo)
WHEN:
- The .eml file is parsed into a MailMessage
THEN:
- The resulting message date is made timezone-aware
"""
mock_message = mocker.Mock(
from_values="mail@someserver.de",
date=datetime.datetime(2022, 10, 12, 21, 40, 43),
)
mocker.patch(
"paperless.parsers.mail.MailMessage.from_bytes",
return_value=mock_message,
)
parsed_msg = mail_parser.parse_file_to_message(simple_txt_email_file)
assert timezone.is_aware(parsed_msg.date)
assert parsed_msg.date.replace(tzinfo=None) == datetime.datetime(
2022,
10,
12,
21,
40,
43,
)
class TestEmailMetadataExtraction:
"""
@@ -336,6 +336,117 @@ class TestRemoteParserParse:
assert remote_parser.get_date() is None
# ---------------------------------------------------------------------------
# parse() — produce_archive=False skips the remote engine (PDFs only)
# ---------------------------------------------------------------------------
class TestRemoteParserSkipsWhenNoArchiveWanted:
"""When the caller has already decided no archive is needed for a PDF
(documents.consumer.should_produce_archive), the remote engine call is
skipped entirely in favor of locally-extracted text.
"""
def test_pdf_skips_azure_when_no_archive_requested(
self,
remote_parser: RemoteDocumentParser,
simple_digital_pdf_file: Path,
azure_client: Mock,
) -> None:
"""
GIVEN: produce_archive=False for a PDF
WHEN: parse() is called
THEN: Azure is never invoked, no archive is produced, and text
comes from local pdftotext extraction
"""
remote_parser.parse(
simple_digital_pdf_file,
"application/pdf",
produce_archive=False,
)
azure_client.begin_analyze_document.assert_not_called()
assert remote_parser.get_archive_path() is None
assert remote_parser.get_text() != ""
def test_pdf_no_archive_requested_text_matches_local_extraction(
self,
remote_parser: RemoteDocumentParser,
simple_digital_pdf_file: Path,
azure_client: Mock,
mocker: MockerFixture,
) -> None:
"""
GIVEN: produce_archive=False for a PDF
WHEN: parse() is called
THEN: the returned text is exactly the locally-extracted text,
not anything from the (unused) Azure mock
"""
mocker.patch(
"paperless.parsers.remote.extract_pdf_text",
return_value="Local digital text.",
)
remote_parser.parse(
simple_digital_pdf_file,
"application/pdf",
produce_archive=False,
)
assert remote_parser.get_text() == "Local digital text."
def test_pdf_no_archive_requested_closes_no_client(
self,
remote_parser: RemoteDocumentParser,
simple_digital_pdf_file: Path,
azure_client: Mock,
) -> None:
remote_parser.parse(
simple_digital_pdf_file,
"application/pdf",
produce_archive=False,
)
azure_client.close.assert_not_called()
def test_non_pdf_still_calls_azure_when_no_archive_requested(
self,
remote_parser: RemoteDocumentParser,
simple_digital_pdf_file: Path,
azure_client: Mock,
) -> None:
"""
Images have no local-text fallback, so produce_archive=False does
not skip the remote engine for non-PDF MIME types.
"""
remote_parser.parse(
simple_digital_pdf_file,
"image/png",
produce_archive=False,
)
azure_client.begin_analyze_document.assert_called_once()
assert remote_parser.get_text() == _DEFAULT_TEXT
@pytest.mark.usefixtures("no_engine_settings")
def test_unconfigured_engine_takes_precedence_over_skip(
self,
remote_parser: RemoteDocumentParser,
simple_digital_pdf_file: Path,
) -> None:
"""An unconfigured engine still short-circuits before the
produce_archive check, returning empty text as before.
"""
remote_parser.parse(
simple_digital_pdf_file,
"application/pdf",
produce_archive=False,
)
assert remote_parser.get_text() == ""
assert remote_parser.get_archive_path() is None
# ---------------------------------------------------------------------------
# parse() — Azure failure path
# ---------------------------------------------------------------------------
@@ -21,7 +21,7 @@ from documents.parsers import run_convert
from paperless.models import ModeChoices
from paperless.parsers import ParserProtocol
from paperless.parsers.tesseract import RasterisedDocumentParser
from paperless.parsers.tesseract import post_process_text
from paperless.parsers.utils import post_process_text
if TYPE_CHECKING:
from pathlib import Path
@@ -223,11 +223,4 @@ class TestTikaParser:
assert form_field_found
# Field updates must be disabled so LibreOffice preserves document
# fields (e.g. auto-date fields) as authored rather than refreshing
# them to the current date.
assert any(
b'name="updateIndexes"' in part and b"false" in part for part in parts
)
httpx_mock.reset()