]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Add an option to disable matching
authorBrandon Rothweiler <brandonrothweiler@gmail.com>
Wed, 22 Feb 2023 01:01:30 +0000 (20:01 -0500)
committerBrandon Rothweiler <brandonrothweiler@gmail.com>
Wed, 22 Feb 2023 01:01:30 +0000 (20:01 -0500)
docs/advanced_usage.md
src-ui/src/app/components/common/edit-dialog/edit-dialog.component.ts
src-ui/src/app/components/manage/management-list/management-list.component.ts
src-ui/src/app/data/matching-model.ts
src/documents/matching.py
src/documents/migrations/1032_alter_correspondent_matching_algorithm_and_more.py [new file with mode: 0644]
src/documents/models.py

index cd82ab78e2670bd7c88cd5f4e3690b292f8b2374..55ca8ee74a9308f016afad410e55c92de1cf6d45 100644 (file)
@@ -9,7 +9,7 @@ Paperless will compare the matching algorithms defined by every tag,
 correspondent, document type, and storage path in your database to see
 if they apply to the text in a document. In other words, if you define a
 tag called `Home Utility` that had a `match` property of `bc hydro` and
-a `matching_algorithm` of `literal`, Paperless will automatically tag
+a `matching_algorithm` of `Exact`, Paperless will automatically tag
 your newly-consumed document with your `Home Utility` tag so long as the
 text `bc hydro` appears in the body of the document somewhere.
 
@@ -25,12 +25,13 @@ documents.
 
 The following algorithms are available:
 
+- **None:** No matching will be performed.
 - **Any:** Looks for any occurrence of any word provided in match in
   the PDF. If you define the match as `Bank1 Bank2`, it will match
   documents containing either of these terms.
 - **All:** Requires that every word provided appears in the PDF,
   albeit not in the order provided.
-- **Literal:** Matches only if the match appears exactly as provided
+- **Exact:** Matches only if the match appears exactly as provided
   (i.e. preserve ordering) in the PDF.
 - **Regular expression:** Parses the match as a regular expression and
   tries to find a match within the document.
index 056ad65a02789dc348b800a7c2bf6269bf495294..94fe79d2a3294188d88c8ab4543cbe13d585edf5 100644 (file)
@@ -2,7 +2,11 @@ import { Directive, EventEmitter, Input, OnInit, Output } from '@angular/core'
 import { FormGroup } from '@angular/forms'
 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
 import { Observable } from 'rxjs'
-import { MATCHING_ALGORITHMS, MATCH_AUTO } from 'src/app/data/matching-model'
+import {
+  MATCHING_ALGORITHMS,
+  MATCH_AUTO,
+  MATCH_NONE,
+} from 'src/app/data/matching-model'
 import { ObjectWithId } from 'src/app/data/object-with-id'
 import { ObjectWithPermissions } from 'src/app/data/object-with-permissions'
 import { PaperlessUser } from 'src/app/data/paperless-user'
@@ -91,7 +95,10 @@ export abstract class EditDialogComponent<
   }
 
   get patternRequired(): boolean {
-    return this.objectForm?.value.matching_algorithm !== MATCH_AUTO
+    return (
+      this.objectForm?.value.matching_algorithm !== MATCH_AUTO &&
+      this.objectForm?.value.matching_algorithm !== MATCH_NONE
+    )
   }
 
   save() {
index 0fa24e2525fe7c1bd465aaea04efe1d22e3ae28f..43a31f1ca58520412f922afcaafe06f670fdb85d 100644 (file)
@@ -12,6 +12,7 @@ import {
   MatchingModel,
   MATCHING_ALGORITHMS,
   MATCH_AUTO,
+  MATCH_NONE,
 } from 'src/app/data/matching-model'
 import { ObjectWithId } from 'src/app/data/object-with-id'
 import { ObjectWithPermissions } from 'src/app/data/object-with-permissions'
@@ -96,6 +97,8 @@ export abstract class ManagementListComponent<T extends ObjectWithId>
   getMatching(o: MatchingModel) {
     if (o.matching_algorithm == MATCH_AUTO) {
       return $localize`Automatic`
+    } else if (o.matching_algorithm == MATCH_NONE) {
+      return $localize`None`
     } else if (o.match && o.match.length > 0) {
       return `${
         MATCHING_ALGORITHMS.find((a) => a.id == o.matching_algorithm).shortName
index 387625b547cb618140554fdd0db3efb5c794db38..dc2f8298d1a4130216c2a773f2eb221d7f1db815 100644 (file)
@@ -1,5 +1,6 @@
 import { ObjectWithPermissions } from './object-with-permissions'
 
+export const MATCH_NONE = 0
 export const MATCH_ANY = 1
 export const MATCH_ALL = 2
 export const MATCH_LITERAL = 3
@@ -9,6 +10,11 @@ export const MATCH_AUTO = 6
 export const DEFAULT_MATCHING_ALGORITHM = MATCH_AUTO
 
 export const MATCHING_ALGORITHMS = [
+  {
+    id: MATCH_NONE,
+    shortName: $localize`None`,
+    name: $localize`None: Disable matching`,
+  },
   {
     id: MATCH_ANY,
     shortName: $localize`Any word`,
index 235263aa6eeecf1c432c4c4d488efa825c2b0475..c38761afa2a02c7d522687dad2ac9467aadea79f 100644 (file)
@@ -86,7 +86,10 @@ def matches(matching_model, document):
     if matching_model.is_insensitive:
         search_kwargs = {"flags": re.IGNORECASE}
 
-    if matching_model.matching_algorithm == MatchingModel.MATCH_ALL:
+    if matching_model.matching_algorithm == MatchingModel.MATCH_NONE:
+        return False
+
+    elif matching_model.matching_algorithm == MatchingModel.MATCH_ALL:
         for word in _split_match(matching_model):
             search_result = re.search(rf"\b{word}\b", document_content, **search_kwargs)
             if not search_result:
diff --git a/src/documents/migrations/1032_alter_correspondent_matching_algorithm_and_more.py b/src/documents/migrations/1032_alter_correspondent_matching_algorithm_and_more.py
new file mode 100644 (file)
index 0000000..88aa7f2
--- /dev/null
@@ -0,0 +1,81 @@
+# Generated by Django 4.1.7 on 2023-02-22 00:45
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("documents", "1031_remove_savedview_user_correspondent_owner_and_more"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="correspondent",
+            name="matching_algorithm",
+            field=models.PositiveIntegerField(
+                choices=[
+                    (0, "None"),
+                    (1, "Any word"),
+                    (2, "All words"),
+                    (3, "Exact match"),
+                    (4, "Regular expression"),
+                    (5, "Fuzzy word"),
+                    (6, "Automatic"),
+                ],
+                default=1,
+                verbose_name="matching algorithm",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="documenttype",
+            name="matching_algorithm",
+            field=models.PositiveIntegerField(
+                choices=[
+                    (0, "None"),
+                    (1, "Any word"),
+                    (2, "All words"),
+                    (3, "Exact match"),
+                    (4, "Regular expression"),
+                    (5, "Fuzzy word"),
+                    (6, "Automatic"),
+                ],
+                default=1,
+                verbose_name="matching algorithm",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="storagepath",
+            name="matching_algorithm",
+            field=models.PositiveIntegerField(
+                choices=[
+                    (0, "None"),
+                    (1, "Any word"),
+                    (2, "All words"),
+                    (3, "Exact match"),
+                    (4, "Regular expression"),
+                    (5, "Fuzzy word"),
+                    (6, "Automatic"),
+                ],
+                default=1,
+                verbose_name="matching algorithm",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="tag",
+            name="matching_algorithm",
+            field=models.PositiveIntegerField(
+                choices=[
+                    (0, "None"),
+                    (1, "Any word"),
+                    (2, "All words"),
+                    (3, "Exact match"),
+                    (4, "Regular expression"),
+                    (5, "Fuzzy word"),
+                    (6, "Automatic"),
+                ],
+                default=1,
+                verbose_name="matching algorithm",
+            ),
+        ),
+    ]
index 77dc8094407a01d424a8383ccfde519a195657e1..177885de0f03a59c1e72d4d3acbe49a02720cc6f 100644 (file)
@@ -24,6 +24,7 @@ TASK_STATE_CHOICES = sorted(zip(ALL_STATES, ALL_STATES))
 
 class MatchingModel(models.Model):
 
+    MATCH_NONE = 0
     MATCH_ANY = 1
     MATCH_ALL = 2
     MATCH_LITERAL = 3
@@ -32,6 +33,7 @@ class MatchingModel(models.Model):
     MATCH_AUTO = 6
 
     MATCHING_ALGORITHMS = (
+        (MATCH_NONE, _("None")),
         (MATCH_ANY, _("Any word")),
         (MATCH_ALL, _("All words")),
         (MATCH_LITERAL, _("Exact match")),