条码处理
条码处理
相关源文件
本章引用的主要源码文件:
src/documents/barcodes.pysrc/documents/bulk_edit.pysrc/documents/data_models.pysrc/documents/tests/test_api_bulk_edit.pysrc/documents/tests/test_barcodes.pysrc/documents/tests/test_bulk_edit.pysrc/documents/tests/utils.py
目的与范围
Paperless-ngx 中的条码处理系统能够在消费管线中检测并利用文档中嵌入的条码。该系统提供三个主要功能:
- 文档分离:根据分隔条码将多页文档拆分为多个文档。
- ASN 分配:从条码中提取并分配归档序列号(ASN)。
- 标签分配:根据条码内容和正则表达式映射创建并分配标签。
该逻辑封装在 BarcodePlugin 中,它实现了 ConsumeTaskPlugin 接口,并在消费任务的早期阶段运行。
来源:src/documents/barcodes.py:82-83、src/documents/barcodes.py:42-80、src/documents/tasks.py:146-149
条码处理架构
条码处理系统是文档消费管线中的一个模块化组件。它与 ConsumableDocument 和 DocumentMetadataOverrides 交互,以影响最终文档的创建或拆分方式。
文档管线中的条码处理
来源:src/documents/tasks.py:135-200、src/documents/barcodes.py:110-155、src/documents/plugins/base.py:24-25
条码插件组件
该系统使用 Barcode 数据类来表示检测到的值及其位置,而 BarcodePlugin 则管理检测和应用逻辑。
来源:src/documents/barcodes.py:41-80、src/documents/barcodes.py:82-134、src/paperless/config.py:33-33
配置选项
条码处理行为由 BarcodeConfig 控制。这些设置通常来自环境变量。
| 配置项 | BarcodeConfig 中的属性 | 用途 |
|---|---|---|
CONSUMER_ENABLE_BARCODES | barcodes_enabled | 启用文档分离 |
CONSUMER_BARCODE_STRING | barcode_string | 用于分离的字符串(默认值:PATCHT) |
CONSUMER_BARCODE_SCANNER | barcode_scanner | 库选择:PYZBAR 或 ZXING |
CONSUMER_ENABLE_ASN_BARCODE | barcode_enable_asn | 启用 ASN 提取 |
CONSUMER_ASN_BARCODE_PREFIX | barcode_asn_prefix | ASN 的前缀(默认值:ASN) |
CONSUMER_ENABLE_TAG_BARCODE | barcode_enable_tag | 启用标签提取 |
CONSUMER_TAG_BARCODE_MAPPING | barcode_tag_mapping | 标签的正则表达式映射 |
CONSUMER_BARCODE_TIFF_SUPPORT | barcode_enable_tiff_support | 支持 image/tiff |
来源:src/documents/barcodes.py:49-50、src/documents/barcodes.py:92-101、src/paperless/config.py:33-33
条码检测过程
BarcodePlugin.detect() 方法负责从文档页面中提取条码值。
来源:src/documents/barcodes.py:154-162、src/documents/barcodes.py:219-306、src/documents/barcodes.py:184-217
扫描实现
- ZXing:使用
zxingcpp进行检测。对于变形的条码通常更稳健,并支持更广泛的格式,包括 Aztec 和 PDF417。src/documents/barcodes.py:184-198 - Pyzbar:使用
pyzbar(ZBar)。对于标准一维条码和二维码效率较高。src/documents/barcodes.py:200-217
文档分离
当 barcodes_enabled 为 true 时,插件会识别"分离页面",这些页面上的条码值与 barcode_string 匹配。
- 识别:
get_separation_pages()返回一个字典,将页面索引映射到一个布尔值,指示该页面是否为 ASN 条码(如果配置了,它也可以作为分隔符)。src/documents/barcodes.py:389-411 - 拆分:插件使用
pikepdf提取分隔符之间的页面范围。src/documents/barcodes.py:413-468 - 任务创建:对于每个拆分,通过 Celery 调度一个新的
consume_file任务,并将original_path设置为父文档的路径。src/documents/barcodes.py:448-461 - 终止:通过抛出
StopConsumeTaskError来中止原始消费任务。src/documents/barcodes.py:468-468
来源:src/documents/barcodes.py:389-468、src/documents/tasks.py:146-155
ASN 和标签提取
ASN 分配
如果启用了 barcode_enable_asn,插件会搜索第一个与 barcode_asn_prefix 匹配的条码。它会去除非数字字符,并将结果赋值给 self.metadata.asn。如果 ASN 已存在于数据库中,并且设置了 skip_asn_if_exists,则会跳过分配。
来源:src/documents/barcodes.py:136-153、src/documents/barcodes.py:308-341
标签分配
如果启用了 barcode_enable_tag,插件会遍历所有检测到的条码,并将它们与 barcode_tag_mapping 进行匹配。
- 映射:一个字典,其中键是正则表达式模式。如果条码值匹配,则映射值(支持正则表达式替换)被用作标签名称。
src/documents/barcodes.py:356-367 - 创建:使用
Tag.objects.get_or_create在数据库中检索或创建标签。src/documents/barcodes.py:372-378 - 拆分:如果启用了
barcode_tag_split,则仅在处理生成的拆分文档时提取标签,而不是在原始多页文件中提取。src/documents/barcodes.py:168-171
来源:src/documents/barcodes.py:343-387、src/documents/barcodes.py:164-181
替换中的 ASN 冲突处理
在文档替换等批量操作期间,bulk_edit.py 中的 release_archive_serial_numbers 用于临时清除 ASN,以防止在通过相同条码消费新版本时发生唯一性冲突。
来源:src/documents/bulk_edit.py:65-78、src/documents/bulk_edit.py:81-89