mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-10-26 14:25:06 +00:00
* Feature: store barcode contents, list and search them New setting PAPERLESS_CONSUMER_STORE_BARCODE_VALUES (off by default) stores all barcodes found during consumption with the document: page, type and content. They are listed on the metadata tab with a copy button, returned by the documents API and searchable with barcodes: in the advanced search. Versions keep their own barcodes, reprocessing reads them again. Refs #9898 * Tests: cover the remaining barcode branches Covers unchanged and failing barcode reads on reprocessing, unsupported files and DocumentBarcode.__str__, and uses toHaveLength in the barcode list spec as suggested by SonarCloud. * Address review: keep barcodes when they can't be read, format choices - Reprocessing and new versions keep the stored barcodes when the file can't be scanned or the scan fails, and replace them atomically. - Format is a TextChoices of the zxing-cpp formats, with a test. - Shared scan code, latest_version helper, TypedDict, serializer reuse. - Barcodes in the split manifest, export/import tests, pytest-style tests. * Barcode tests: TIFF reprocess, format check both ways, fixtures - Reprocessing a TIFF with TIFF support off keeps the stored barcodes. - The format test also fails when zxing-cpp drops a format. - Fixtures in place of the sample dir mixin, plugin-level disabled test. - Format labels aren't translated, OpenAPI enum named BarcodeFormatEnum. * Review: module-level zxing reader, shorter barcode docs - read_barcodes_zxing is a module-level function used by scan_pdf. - Drop the trivial __str__ test, mark it no cover. - Shorten the barcode docs and remove the duplicate in configuration.md. * Fix header * Use utility class * Return barcodes from the metadata endpoint only Drop the barcodes field and its prefetches from the document serializer, as agreed in the review. Also remove the now empty component stylesheet. --------- Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
111 lines
3.0 KiB
Python
111 lines
3.0 KiB
Python
"""
|
|
Factory-boy factories for documents app models.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import factory
|
|
from django.contrib.auth.models import User
|
|
|
|
from documents.models import Correspondent
|
|
from documents.models import Document
|
|
from documents.models import DocumentBarcode
|
|
from documents.models import DocumentType
|
|
from documents.models import MatchingModel
|
|
from documents.models import PaperlessTask
|
|
from documents.models import StoragePath
|
|
from documents.models import Tag
|
|
from paperless_testing.typed_factory import TypedModelFactory
|
|
|
|
|
|
class CorrespondentFactory(TypedModelFactory[Correspondent]):
|
|
class Meta:
|
|
model = Correspondent
|
|
|
|
name = factory.Sequence(lambda n: f"{factory.Faker('company')} {n}")
|
|
match = ""
|
|
matching_algorithm = MatchingModel.MATCH_NONE
|
|
|
|
|
|
class DocumentTypeFactory(TypedModelFactory[DocumentType]):
|
|
class Meta:
|
|
model = DocumentType
|
|
|
|
name = factory.Sequence(lambda n: f"{factory.Faker('bs')} {n}")
|
|
match = ""
|
|
matching_algorithm = MatchingModel.MATCH_NONE
|
|
|
|
|
|
class TagFactory(TypedModelFactory[Tag]):
|
|
class Meta:
|
|
model = Tag
|
|
|
|
name = factory.Sequence(lambda n: f"{factory.Faker('word')} {n}")
|
|
match = ""
|
|
matching_algorithm = MatchingModel.MATCH_NONE
|
|
is_inbox_tag = False
|
|
|
|
|
|
class StoragePathFactory(TypedModelFactory[StoragePath]):
|
|
class Meta:
|
|
model = StoragePath
|
|
|
|
name = factory.Sequence(
|
|
lambda n: f"{factory.Faker('file_path', depth=2, extension='')} {n}",
|
|
)
|
|
path = factory.LazyAttribute(lambda o: f"{o.name}/{{title}}")
|
|
match = ""
|
|
matching_algorithm = MatchingModel.MATCH_NONE
|
|
|
|
|
|
class DocumentFactory(TypedModelFactory[Document]):
|
|
class Meta:
|
|
model = Document
|
|
|
|
title = factory.Faker("sentence", nb_words=4)
|
|
checksum = factory.Faker("sha256")
|
|
content = factory.Faker("paragraph")
|
|
correspondent = None
|
|
document_type = None
|
|
storage_path = None
|
|
|
|
|
|
class DocumentBarcodeFactory(TypedModelFactory[DocumentBarcode]):
|
|
class Meta:
|
|
model = DocumentBarcode
|
|
|
|
document = factory.SubFactory(DocumentFactory)
|
|
page = 1
|
|
value = factory.Faker("uri")
|
|
format = DocumentBarcode.Format.QR_CODE
|
|
|
|
|
|
class UserFactory(TypedModelFactory[User]):
|
|
class Meta:
|
|
model = User
|
|
|
|
username = factory.Sequence(lambda n: f"user{n}")
|
|
is_staff = False
|
|
is_superuser = False
|
|
# Hashing a real password costs about half a second per user, and no test
|
|
# authenticates with its password. None gives the unusable password
|
|
# create_user() gives.
|
|
password = factory.django.Password(None)
|
|
|
|
class Params:
|
|
superuser = factory.Trait(is_staff=True, is_superuser=True)
|
|
staff = factory.Trait(is_staff=True)
|
|
|
|
|
|
class PaperlessTaskFactory(TypedModelFactory[PaperlessTask]):
|
|
class Meta:
|
|
model = PaperlessTask
|
|
|
|
task_id = factory.Faker("uuid4")
|
|
task_type = PaperlessTask.TaskType.CONSUME_FILE
|
|
trigger_source = PaperlessTask.TriggerSource.WEB_UI
|
|
status = PaperlessTask.Status.PENDING
|
|
input_data = factory.LazyFunction(dict)
|
|
result_data = None
|
|
acknowledged = False
|