mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-12-22 01:55:49 -06:00
Compare commits
1 Commits
feature-in
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
edb915d805 |
@@ -45,7 +45,7 @@ dependencies = [
|
|||||||
"drf-writable-nested~=0.7.1",
|
"drf-writable-nested~=0.7.1",
|
||||||
"filelock~=3.20.0",
|
"filelock~=3.20.0",
|
||||||
"flower~=2.0.1",
|
"flower~=2.0.1",
|
||||||
"gotenberg-client~=0.12.0",
|
"gotenberg-client~=0.13.1",
|
||||||
"httpx-oauth~=0.16",
|
"httpx-oauth~=0.16",
|
||||||
"imap-tools~=1.11.0",
|
"imap-tools~=1.11.0",
|
||||||
"inotifyrecursive~=0.3",
|
"inotifyrecursive~=0.3",
|
||||||
|
|||||||
@@ -31,7 +31,6 @@
|
|||||||
"fi-FI": "src/locale/messages.fi_FI.xlf",
|
"fi-FI": "src/locale/messages.fi_FI.xlf",
|
||||||
"fr-FR": "src/locale/messages.fr_FR.xlf",
|
"fr-FR": "src/locale/messages.fr_FR.xlf",
|
||||||
"hu-HU": "src/locale/messages.hu_HU.xlf",
|
"hu-HU": "src/locale/messages.hu_HU.xlf",
|
||||||
"id-ID": "src/locale/messages.id_ID.xlf",
|
|
||||||
"it-IT": "src/locale/messages.it_IT.xlf",
|
"it-IT": "src/locale/messages.it_IT.xlf",
|
||||||
"ja-JP": "src/locale/messages.ja_JP.xlf",
|
"ja-JP": "src/locale/messages.ja_JP.xlf",
|
||||||
"lb-LU": "src/locale/messages.lb_LU.xlf",
|
"lb-LU": "src/locale/messages.lb_LU.xlf",
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import localeFa from '@angular/common/locales/fa'
|
|||||||
import localeFi from '@angular/common/locales/fi'
|
import localeFi from '@angular/common/locales/fi'
|
||||||
import localeFr from '@angular/common/locales/fr'
|
import localeFr from '@angular/common/locales/fr'
|
||||||
import localeHu from '@angular/common/locales/hu'
|
import localeHu from '@angular/common/locales/hu'
|
||||||
import localeId from '@angular/common/locales/id'
|
|
||||||
import localeIt from '@angular/common/locales/it'
|
import localeIt from '@angular/common/locales/it'
|
||||||
import localeJa from '@angular/common/locales/ja'
|
import localeJa from '@angular/common/locales/ja'
|
||||||
import localeKo from '@angular/common/locales/ko'
|
import localeKo from '@angular/common/locales/ko'
|
||||||
@@ -64,7 +63,6 @@ registerLocaleData(localeFa)
|
|||||||
registerLocaleData(localeFi)
|
registerLocaleData(localeFi)
|
||||||
registerLocaleData(localeFr)
|
registerLocaleData(localeFr)
|
||||||
registerLocaleData(localeHu)
|
registerLocaleData(localeHu)
|
||||||
registerLocaleData(localeId)
|
|
||||||
registerLocaleData(localeIt)
|
registerLocaleData(localeIt)
|
||||||
registerLocaleData(localeJa)
|
registerLocaleData(localeJa)
|
||||||
registerLocaleData(localeKo)
|
registerLocaleData(localeKo)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
@if (previewText) {
|
@if (previewText) {
|
||||||
<div class="bg-light p-3 overflow-auto whitespace-preserve" width="100%">{{previewText}}</div>
|
<div class="bg-light p-3 overflow-auto whitespace-preserve" width="100%">{{previewText}}</div>
|
||||||
} @else {
|
} @else {
|
||||||
<object [data]="previewUrl | safeUrl" width="100%" class="bg-light" [class.p-2]="!isPdf"></object>
|
<object [data]="previewURL | safeUrl" width="100%" class="bg-light" [class.p-2]="!isPdf"></object>
|
||||||
}
|
}
|
||||||
} @else {
|
} @else {
|
||||||
@if (requiresPassword) {
|
@if (requiresPassword) {
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
}
|
}
|
||||||
@if (!requiresPassword) {
|
@if (!requiresPassword) {
|
||||||
<pdf-viewer
|
<pdf-viewer
|
||||||
[src]="previewUrl"
|
[src]="previewURL"
|
||||||
[original-size]="false"
|
[original-size]="false"
|
||||||
[show-borders]="false"
|
[show-borders]="false"
|
||||||
[show-all]="true"
|
[show-all]="true"
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ export class PreviewPopupComponent implements OnDestroy {
|
|||||||
return (this.isPdf && this.useNativePdfViewer) || !this.isPdf
|
return (this.isPdf && this.useNativePdfViewer) || !this.isPdf
|
||||||
}
|
}
|
||||||
|
|
||||||
get previewUrl() {
|
get previewURL() {
|
||||||
return this.documentService.getPreviewUrl(this.document.id)
|
return this.documentService.getPreviewUrl(this.document.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ export class PreviewPopupComponent implements OnDestroy {
|
|||||||
init() {
|
init() {
|
||||||
if (this.document.mime_type?.includes('text')) {
|
if (this.document.mime_type?.includes('text')) {
|
||||||
this.http
|
this.http
|
||||||
.get(this.previewUrl, { responseType: 'text' })
|
.get(this.previewURL, { responseType: 'text' })
|
||||||
.pipe(first(), takeUntil(this.unsubscribeNotifier))
|
.pipe(first(), takeUntil(this.unsubscribeNotifier))
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (res) => {
|
next: (res) => {
|
||||||
@@ -126,6 +126,10 @@ export class PreviewPopupComponent implements OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get previewUrl() {
|
||||||
|
return this.documentService.getPreviewUrl(this.document.id)
|
||||||
|
}
|
||||||
|
|
||||||
mouseEnterPreview() {
|
mouseEnterPreview() {
|
||||||
this.mouseOnPreview = true
|
this.mouseOnPreview = true
|
||||||
if (!this.popover.isOpen()) {
|
if (!this.popover.isOpen()) {
|
||||||
|
|||||||
@@ -379,7 +379,7 @@
|
|||||||
<ng-template #previewContent>
|
<ng-template #previewContent>
|
||||||
<div class="thumb-preview position-absolute pe-none text-center" [class.fade]="previewLoaded">
|
<div class="thumb-preview position-absolute pe-none text-center" [class.fade]="previewLoaded">
|
||||||
@if (showThumbnailOverlay) {
|
@if (showThumbnailOverlay) {
|
||||||
<img [src]="thumbUrl" class="mx-auto" [attr.width]="previewZoomScale === 'page-fit' ? 'auto' : '100%'" [attr.height]="previewZoomScale === 'page-fit' ? '100%' : 'auto'" alt="Document loading..." i18n-alt />
|
<img [src]="thumbUrl | safeUrl" class="mx-auto" [attr.width]="previewZoomScale === 'page-fit' ? 'auto' : '100%'" [attr.height]="previewZoomScale === 'page-fit' ? '100%' : 'auto'" alt="Document loading..." i18n-alt />
|
||||||
}
|
}
|
||||||
<div class="position-absolute top-0 start-0 m-2 p-2 d-flex align-items-center justify-content-center">
|
<div class="position-absolute top-0 start-0 m-2 p-2 d-flex align-items-center justify-content-center">
|
||||||
<div>
|
<div>
|
||||||
@@ -414,7 +414,7 @@
|
|||||||
}
|
}
|
||||||
@case (ContentRenderType.Image) {
|
@case (ContentRenderType.Image) {
|
||||||
<div class="preview-sticky">
|
<div class="preview-sticky">
|
||||||
<img [src]="previewUrl" width="100%" height="100%" alt="{{title}}" />
|
<img [src]="previewUrl | safeUrl" width="100%" height="100%" alt="{{title}}" />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@case (ContentRenderType.TIFF) {
|
@case (ContentRenderType.TIFF) {
|
||||||
|
|||||||
@@ -136,12 +136,6 @@ const LANGUAGE_OPTIONS = [
|
|||||||
englishName: 'Hungarian',
|
englishName: 'Hungarian',
|
||||||
dateInputFormat: 'yyyy.mm.dd',
|
dateInputFormat: 'yyyy.mm.dd',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
code: 'id-id',
|
|
||||||
name: $localize`Indonesian`,
|
|
||||||
englishName: 'Indonesian',
|
|
||||||
dateInputFormat: 'dd-mm-yyyy',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
code: 'it-it',
|
code: 'it-it',
|
||||||
name: $localize`Italian`,
|
name: $localize`Italian`,
|
||||||
|
|||||||
@@ -171,7 +171,6 @@ import localeFa from '@angular/common/locales/fa'
|
|||||||
import localeFi from '@angular/common/locales/fi'
|
import localeFi from '@angular/common/locales/fi'
|
||||||
import localeFr from '@angular/common/locales/fr'
|
import localeFr from '@angular/common/locales/fr'
|
||||||
import localeHu from '@angular/common/locales/hu'
|
import localeHu from '@angular/common/locales/hu'
|
||||||
import localeId from '@angular/common/locales/id'
|
|
||||||
import localeIt from '@angular/common/locales/it'
|
import localeIt from '@angular/common/locales/it'
|
||||||
import localeJa from '@angular/common/locales/ja'
|
import localeJa from '@angular/common/locales/ja'
|
||||||
import localeKo from '@angular/common/locales/ko'
|
import localeKo from '@angular/common/locales/ko'
|
||||||
@@ -210,7 +209,6 @@ registerLocaleData(localeFa)
|
|||||||
registerLocaleData(localeFi)
|
registerLocaleData(localeFi)
|
||||||
registerLocaleData(localeFr)
|
registerLocaleData(localeFr)
|
||||||
registerLocaleData(localeHu)
|
registerLocaleData(localeHu)
|
||||||
registerLocaleData(localeId)
|
|
||||||
registerLocaleData(localeIt)
|
registerLocaleData(localeIt)
|
||||||
registerLocaleData(localeJa)
|
registerLocaleData(localeJa)
|
||||||
registerLocaleData(localeKo)
|
registerLocaleData(localeKo)
|
||||||
|
|||||||
@@ -186,11 +186,7 @@ class BarcodePlugin(ConsumeTaskPlugin):
|
|||||||
|
|
||||||
# Update/overwrite an ASN if possible
|
# Update/overwrite an ASN if possible
|
||||||
# After splitting, as otherwise each split document gets the same ASN
|
# After splitting, as otherwise each split document gets the same ASN
|
||||||
if (
|
if self.settings.barcode_enable_asn and (located_asn := self.asn) is not None:
|
||||||
self.settings.barcode_enable_asn
|
|
||||||
and not self.metadata.skip_asn
|
|
||||||
and (located_asn := self.asn) is not None
|
|
||||||
):
|
|
||||||
logger.info(f"Found ASN in barcode: {located_asn}")
|
logger.info(f"Found ASN in barcode: {located_asn}")
|
||||||
self.metadata.asn = located_asn
|
self.metadata.asn = located_asn
|
||||||
|
|
||||||
|
|||||||
@@ -433,8 +433,6 @@ def merge(
|
|||||||
|
|
||||||
if user is not None:
|
if user is not None:
|
||||||
overrides.owner_id = user.id
|
overrides.owner_id = user.id
|
||||||
# Avoid copying or detecting ASN from merged PDFs to prevent collision
|
|
||||||
overrides.skip_asn = True
|
|
||||||
|
|
||||||
logger.info("Adding merged document to the task queue.")
|
logger.info("Adding merged document to the task queue.")
|
||||||
|
|
||||||
|
|||||||
@@ -696,7 +696,7 @@ class ConsumerPlugin(
|
|||||||
pk=self.metadata.storage_path_id,
|
pk=self.metadata.storage_path_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.metadata.asn is not None and not self.metadata.skip_asn:
|
if self.metadata.asn is not None:
|
||||||
document.archive_serial_number = self.metadata.asn
|
document.archive_serial_number = self.metadata.asn
|
||||||
|
|
||||||
if self.metadata.owner_id:
|
if self.metadata.owner_id:
|
||||||
@@ -812,8 +812,8 @@ class ConsumerPreflightPlugin(
|
|||||||
"""
|
"""
|
||||||
Check that if override_asn is given, it is unique and within a valid range
|
Check that if override_asn is given, it is unique and within a valid range
|
||||||
"""
|
"""
|
||||||
if self.metadata.skip_asn or self.metadata.asn is None:
|
if self.metadata.asn is None:
|
||||||
# if skip is set or ASN is None
|
# check not necessary in case no ASN gets set
|
||||||
return
|
return
|
||||||
# Validate the range is above zero and less than uint32_t max
|
# Validate the range is above zero and less than uint32_t max
|
||||||
# otherwise, Whoosh can't handle it in the index
|
# otherwise, Whoosh can't handle it in the index
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ class DocumentMetadataOverrides:
|
|||||||
change_users: list[int] | None = None
|
change_users: list[int] | None = None
|
||||||
change_groups: list[int] | None = None
|
change_groups: list[int] | None = None
|
||||||
custom_fields: dict | None = None
|
custom_fields: dict | None = None
|
||||||
skip_asn: bool = False
|
|
||||||
|
|
||||||
def update(self, other: "DocumentMetadataOverrides") -> "DocumentMetadataOverrides":
|
def update(self, other: "DocumentMetadataOverrides") -> "DocumentMetadataOverrides":
|
||||||
"""
|
"""
|
||||||
@@ -50,8 +49,6 @@ class DocumentMetadataOverrides:
|
|||||||
self.storage_path_id = other.storage_path_id
|
self.storage_path_id = other.storage_path_id
|
||||||
if other.owner_id is not None:
|
if other.owner_id is not None:
|
||||||
self.owner_id = other.owner_id
|
self.owner_id = other.owner_id
|
||||||
if other.skip_asn:
|
|
||||||
self.skip_asn = True
|
|
||||||
|
|
||||||
# merge
|
# merge
|
||||||
if self.tag_ids is None:
|
if self.tag_ids is None:
|
||||||
|
|||||||
@@ -602,13 +602,11 @@ class TestPDFActions(DirectoriesMixin, TestCase):
|
|||||||
expected_filename,
|
expected_filename,
|
||||||
)
|
)
|
||||||
self.assertEqual(consume_file_args[1].title, None)
|
self.assertEqual(consume_file_args[1].title, None)
|
||||||
self.assertTrue(consume_file_args[1].skip_asn)
|
|
||||||
|
|
||||||
# With metadata_document_id overrides
|
# With metadata_document_id overrides
|
||||||
result = bulk_edit.merge(doc_ids, metadata_document_id=metadata_document_id)
|
result = bulk_edit.merge(doc_ids, metadata_document_id=metadata_document_id)
|
||||||
consume_file_args, _ = mock_consume_file.call_args
|
consume_file_args, _ = mock_consume_file.call_args
|
||||||
self.assertEqual(consume_file_args[1].title, "A (merged)")
|
self.assertEqual(consume_file_args[1].title, "A (merged)")
|
||||||
self.assertTrue(consume_file_args[1].skip_asn)
|
|
||||||
|
|
||||||
self.assertEqual(result, "OK")
|
self.assertEqual(result, "OK")
|
||||||
|
|
||||||
@@ -649,7 +647,6 @@ class TestPDFActions(DirectoriesMixin, TestCase):
|
|||||||
expected_filename,
|
expected_filename,
|
||||||
)
|
)
|
||||||
self.assertEqual(consume_file_args[1].title, None)
|
self.assertEqual(consume_file_args[1].title, None)
|
||||||
self.assertTrue(consume_file_args[1].skip_asn)
|
|
||||||
|
|
||||||
delete_documents_args, _ = mock_delete_documents.call_args
|
delete_documents_args, _ = mock_delete_documents.call_args
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
|||||||
@@ -412,14 +412,6 @@ class TestConsumer(
|
|||||||
self.assertEqual(document.archive_serial_number, 123)
|
self.assertEqual(document.archive_serial_number, 123)
|
||||||
self._assert_first_last_send_progress()
|
self._assert_first_last_send_progress()
|
||||||
|
|
||||||
def testMetadataOverridesSkipAsnPropagation(self):
|
|
||||||
overrides = DocumentMetadataOverrides()
|
|
||||||
incoming = DocumentMetadataOverrides(skip_asn=True)
|
|
||||||
|
|
||||||
overrides.update(incoming)
|
|
||||||
|
|
||||||
self.assertTrue(overrides.skip_asn)
|
|
||||||
|
|
||||||
def testOverrideTitlePlaceholders(self):
|
def testOverrideTitlePlaceholders(self):
|
||||||
c = Correspondent.objects.create(name="Correspondent Name")
|
c = Correspondent.objects.create(name="Correspondent Name")
|
||||||
dt = DocumentType.objects.create(name="DocType Name")
|
dt = DocumentType.objects.create(name="DocType Name")
|
||||||
|
|||||||
@@ -786,7 +786,6 @@ LANGUAGES = [
|
|||||||
("fi-fi", _("Finnish")),
|
("fi-fi", _("Finnish")),
|
||||||
("fr-fr", _("French")),
|
("fr-fr", _("French")),
|
||||||
("hu-hu", _("Hungarian")),
|
("hu-hu", _("Hungarian")),
|
||||||
("id-id", _("Indonesian")),
|
|
||||||
("it-it", _("Italian")),
|
("it-it", _("Italian")),
|
||||||
("ja-jp", _("Japanese")),
|
("ja-jp", _("Japanese")),
|
||||||
("ko-kr", _("Korean")),
|
("ko-kr", _("Korean")),
|
||||||
|
|||||||
@@ -1108,7 +1108,6 @@ class TestMail(
|
|||||||
self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 2)
|
self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 2)
|
||||||
self.assertEqual(len(self.mailMocker.bogus_mailbox.messages_spam), 1)
|
self.assertEqual(len(self.mailMocker.bogus_mailbox.messages_spam), 1)
|
||||||
|
|
||||||
@pytest.mark.flaky(reruns=4)
|
|
||||||
def test_error_skip_rule(self):
|
def test_error_skip_rule(self):
|
||||||
account = MailAccount.objects.create(
|
account = MailAccount.objects.create(
|
||||||
name="test2",
|
name="test2",
|
||||||
|
|||||||
8
uv.lock
generated
8
uv.lock
generated
@@ -1073,15 +1073,15 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gotenberg-client"
|
name = "gotenberg-client"
|
||||||
version = "0.12.0"
|
version = "0.13.1"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "httpx", extra = ["http2"], marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
|
{ name = "httpx", extra = ["http2"], marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
|
||||||
{ name = "typing-extensions", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux')" },
|
{ name = "typing-extensions", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux')" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/61/6d/07ea213c146bbe91dffebff2d8f4dc61e7076d3dd34d4fd1467f9163e752/gotenberg_client-0.12.0.tar.gz", hash = "sha256:1ab50878024469fc003c414ee9810ceeb00d4d7d7c36bd2fb75318fbff139e9b", size = 1210884, upload-time = "2025-10-15T15:32:37.669Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/e4/6c/aaadd6657ca42fbd148b1c00604b98c1ead5a22552f4e5365ce5f0632430/gotenberg_client-0.13.1.tar.gz", hash = "sha256:cdd6bbb535cd739b87446cd1b4f6347ed7f9af6a0d4b19baf7c064b75528ee54", size = 1211143, upload-time = "2025-12-04T20:45:24.151Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/12/39/fcb24ff053b1be7e5124f56c3d358706a23a328f685c6db33bc9dbc5472d/gotenberg_client-0.12.0-py3-none-any.whl", hash = "sha256:a540b35ac518e902c2860a88fbe448c15fe5a56fe8ec8604e6a2c8c2228fd0cb", size = 51051, upload-time = "2025-10-15T15:32:36.32Z" },
|
{ url = "https://files.pythonhosted.org/packages/79/f6/7a6e6785295332d2538f729ae19516cef712273a5ab8b90d015f08e37a45/gotenberg_client-0.13.1-py3-none-any.whl", hash = "sha256:613f7083a5e8a81699dd8d715c97e5806a424ac48920aad25d7c11b600cdfaf3", size = 51058, upload-time = "2025-12-04T20:45:22.603Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2282,7 +2282,7 @@ requires-dist = [
|
|||||||
{ name = "drf-writable-nested", specifier = "~=0.7.1" },
|
{ name = "drf-writable-nested", specifier = "~=0.7.1" },
|
||||||
{ name = "filelock", specifier = "~=3.20.0" },
|
{ name = "filelock", specifier = "~=3.20.0" },
|
||||||
{ name = "flower", specifier = "~=2.0.1" },
|
{ name = "flower", specifier = "~=2.0.1" },
|
||||||
{ name = "gotenberg-client", specifier = "~=0.12.0" },
|
{ name = "gotenberg-client", specifier = "~=0.13.1" },
|
||||||
{ name = "granian", extras = ["uvloop"], marker = "extra == 'webserver'", specifier = "~=2.5.1" },
|
{ name = "granian", extras = ["uvloop"], marker = "extra == 'webserver'", specifier = "~=2.5.1" },
|
||||||
{ name = "httpx-oauth", specifier = "~=0.16" },
|
{ name = "httpx-oauth", specifier = "~=0.16" },
|
||||||
{ name = "imap-tools", specifier = "~=1.11.0" },
|
{ name = "imap-tools", specifier = "~=1.11.0" },
|
||||||
|
|||||||
Reference in New Issue
Block a user