Merge branch 'dev' into fix-7807

This commit is contained in:
Trenton H 2024-10-01 08:39:15 -07:00 committed by GitHub
commit 67f71cb1cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 429 additions and 143 deletions

View File

@ -62,7 +62,6 @@ repos:
rev: v6.2.1
hooks:
- id: beautysh
language_version: '3.10'
additional_dependencies:
- setuptools
args:

View File

@ -35,7 +35,7 @@ inotifyrecursive = "~=0.3"
langdetect = "*"
mysqlclient = "*"
nltk = "*"
ocrmypdf = "~=15.4"
ocrmypdf = "~=16.5"
pathvalidate = "*"
pdf2image = "*"
psycopg = {version = "*", extras = ["c"]}

98
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "e2c4bfb1db243ebdfd0a4ca4a1709c35599e4f3999187870f268416aa01a225f"
"sha256": "1be8ddf875b6aa77fcf61f5c065c9dc3941cad4b9285ce64da60b5684357dade"
},
"pipfile-spec": 6,
"requires": {},
@ -261,14 +261,6 @@
"markers": "python_version >= '3.8'",
"version": "==4.2.0"
},
"chardet": {
"hashes": [
"sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7",
"sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"
],
"markers": "python_version >= '3.7'",
"version": "==5.2.0"
},
"charset-normalizer": {
"hashes": [
"sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027",
@ -1212,12 +1204,12 @@
},
"ocrmypdf": {
"hashes": [
"sha256:13fd388035b5f4bb673bff570cfc2cf72e51168646d5401de9e48ca355917c6d",
"sha256:4696c81cc5b5d64f31ccfe685d10baeb69b42bb0974acddf292d8cf9d97605c3"
"sha256:9222b1b0818b65c891559b84efab2e84434c71149b3aaaa6dc654457e0b66b14",
"sha256:cd96bddfb3a986be7bf7857757919332e1db5dab780eb7b321fdea38f60127ac"
],
"index": "pypi",
"markers": "python_version >= '3.9'",
"version": "==15.4.4"
"markers": "python_version >= '3.10'",
"version": "==16.5.0"
},
"packaging": {
"hashes": [
@ -1244,7 +1236,7 @@
"index": "pypi",
"version": "==1.17.0"
},
"pdfminer.six": {
"pdfminer-six": {
"hashes": [
"sha256:c631a46d5da957a9ffe4460c5dce21e8431dabb615fee5f9f4400603a58d95a6",
"sha256:f4f70e74174b4b3542fcb8406a210b6e2e27cd0f0b5fd04534a8cc0d8951e38c"
@ -1252,6 +1244,64 @@
"markers": "python_version >= '3.8'",
"version": "==20240706"
},
"pi-heif": {
"hashes": [
"sha256:00a6d72ba2cc1477c8a909bfbbac4f5d931a25a88979077b231b76e7b9c80ba6",
"sha256:054cd3544e421b342b15b5eb8db4de222a09ca3ae441f4fa5943f80d9e65c5d6",
"sha256:0962b4cd828ad1ae94f9cd8e95ed0741cddcd19082cb97d5b69bfe1ac6623eb9",
"sha256:0a690159607beaa6712f2c8abaa5168a22314d18f00a617d691548f5acba8070",
"sha256:0d5dd431dbf7be88267fbfb08623bcf2d16628cdcbc898bcc0e05412dc43fd26",
"sha256:1159f54d76b860cc27753c9925e2923959d8b5277372db946cb1078fa11ed1ea",
"sha256:18d113c14fecadb90c3d8838240120e6f93671618eb96d776f994b314f1f858c",
"sha256:24ca403e556c84ce0e36ea1477530f7854e71c2523eb1a97c91d5d9ce8bbc548",
"sha256:286a5d2b5036cf3da8f1a2e1ad54044aaabe4d46b178057323f5a6ce19417741",
"sha256:2b892ebc898ca32c1a1ec9e72658c0d14de5ac31c1bd61a8aa66dc645080e32f",
"sha256:2c912219964dc864e1454ab4f43d97cbf6a88d065410a16936e7c59b1290a7da",
"sha256:34725b542bd2737be7e7909fff1fb6d39760d3d395a36ce6fae5280e88ba94a6",
"sha256:3529f904f51594a613759ab610799ce34b615339d67e642843eec1ac7868814d",
"sha256:3c09d22ed75200372b8102debf4ba69d8f63c595870505b9188d6c9a9b48e1f2",
"sha256:3fa5366b2f555b6b3a56b09aa74f178a040edb174b29060d8d56c03eea154e43",
"sha256:45d360c3a056d9c81b0480a546f291bbc53caf70705f3a49d082e728735ed4ae",
"sha256:4d88aba685051131f103a7afc428412abd7d09640719635f8880898b0e7aec97",
"sha256:4ecb9031ad1cb7eed1591cba95420964557cff8fc63bab9bdc204d53301e502f",
"sha256:5254dc3121d2a38036beae631aae620d0c942f03973ec134ae9827b60e7d5c0b",
"sha256:5424435551e606e1ac515de46a2b1c6d8e82c7a89473bb7cf9398368f051d675",
"sha256:571d69be0088336c4251d7301f3fdc0fecab45e38286e71a23e64814489c5a15",
"sha256:573602d8c68f4ff93c4d35439d7566b3f2d4ab774925367aece20f9cd0ba243d",
"sha256:64ed341f91763e29096b0ddb38b50d13879d06039889d458fc7dac6d5c03dd80",
"sha256:6541a05177c3d8f00e56f4cc8ee9c681eb25fcdc917065acbc426847eb8aea97",
"sha256:6c7a28547e3f1e2f43b395d2764f693fcfa4eb8a4da0d5815c7eb3eeda745fbb",
"sha256:71309d2a632c0b8716ccbbb9e413ee28b8439967c45c92de68888fe4acf80244",
"sha256:742560127423bd179605325a41322df800ca02df768e872bfe189fe371f61578",
"sha256:74d4b07f0589df9fac138ecbcccd248217a12bbebd3443153158d7f54522e257",
"sha256:79969f90a5a01b9a82b18bb0667392da733790585531b3183b7f375b9e88dbcd",
"sha256:7a9a95f54cb3a473005572f7309666b71d03c1764134b2df0ed796744c7aa069",
"sha256:7acdd41dc72c01c1f2cfd91624a1c102ecc324fff6a501ab981c6f803f673b1b",
"sha256:7e0c3286f106f2d22d394b844c0e015f132567d70b31fef6d3cc846b8fe9dbc6",
"sha256:83548aa70e44fef865c2b2575ed949f2e6eba756b114ca6ad525ef56b5449d57",
"sha256:86f7aad733292fea8a2869814117caf11ed424731bd90fe1693b2ccbfcc6bfed",
"sha256:886fbbda898559eba0843feca17e6c7e43c13336404817c6d07a01d4955c3d33",
"sha256:8d0a7529225f1a25231d8f2cfd39f722c31e5396581eeeaa7a30793188e8b4f7",
"sha256:9ff516f9f5118a8f2e47531611324e6a07848e4f1f17c5df485de734e50dee7e",
"sha256:a4b3690f03636944b13ab313d21ee90a46d5fa35a15d884563b0ff400b813042",
"sha256:aac4fc247139081b30581cadbea00bb4c4fb7274140eaa1147e22bcf7ece7525",
"sha256:ad3f54dcc54a4c2ed1c58a135375330fe7b2ba2c2a8a816d3296c12e9d8c284c",
"sha256:b2af8ac6bd93e5df02b9f292a10664524844f37b39079e55aa9ef5857a3b0a22",
"sha256:c5bded35d1cefb594f6ce9d775e3e6b750a32926779f7b496f0f8d4992db09e1",
"sha256:cab6f7a00ccbcc3087d400a544e62ef30eff6339cf0d600588b92b1e7ca49d96",
"sha256:ccd611653581f39c77ab8222a660e471e724d8f7c6f4e50760b10ce06769d9d8",
"sha256:cfa979043be0d4ad1b37f6794fdff010cf69e5ada1ef74eef4a5b3983d3b8881",
"sha256:d7dc682acccd81857fd4b5849ebe7b9504e11eab493ffa0905ea25eaf5fb0f93",
"sha256:e568a323548896848489035c5bb2e4de13df07fbdbd33831b165ff545066b97f",
"sha256:f19d8cdffbc5e8e9f3676839c8632ffd161d17f84f614cad9b98a58e27ffd3a7",
"sha256:f1b7c4daeaffb235e73fc54132f4aa8bcb229dcb463ac0b4def9e1aee5793165",
"sha256:f792a278335c278d2c092a62aaad3a7362021f9341f988b1b8b3ca4783651e49",
"sha256:fae39eec07f4b477c582ddd75d38610553c1b6d19cd6ce4a3ded4c7e0ee029ac",
"sha256:fe0e424d08d59c5a1d74dfa7239b40a935b5a526305ebecd2c27755aa3442225"
],
"markers": "python_version >= '3.8'",
"version": "==0.18.0"
},
"pikepdf": {
"hashes": [
"sha256:01be001988ce0f6a5a89319f37fc14f27df75c4e332222ed8e993d14405acb02",
@ -1788,14 +1838,6 @@
"markers": "python_version >= '3.8'",
"version": "==2024.9.11"
},
"reportlab": {
"hashes": [
"sha256:6e4d86647b8bfd772f475a58f9b0dcba4b340b1969f0db36333089f6ca9ab362",
"sha256:a00b57292e156a7bda84edf31d60c25578153076c8fb96331d0c59eddda052c8"
],
"markers": "python_version >= '3.7' and python_version < '4'",
"version": "==4.2.4"
},
"requests": {
"hashes": [
"sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760",
@ -3227,12 +3269,12 @@
},
"mkdocs-material": {
"hashes": [
"sha256:1843c5171ad6b489550aeaf7358e5b7128cc03ddcf0fb4d91d19aa1e691a63b8",
"sha256:d4779051d52ba9f1e7e344b34de95449c7c366c212b388e4a2db9a3db043c228"
"sha256:0f2f68c8db89523cb4a59705cd01b4acd62b2f71218ccb67e1e004e560410d2b",
"sha256:25faa06142afa38549d2b781d475a86fb61de93189f532b88e69bf11e5e5c3be"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==9.5.38"
"version": "==9.5.39"
},
"mkdocs-material-extensions": {
"hashes": [
@ -3528,12 +3570,12 @@
},
"pytest-httpx": {
"hashes": [
"sha256:6d47849691faf11d2532565d0c8e0e02b9f4ee730da31687feae315581d7520c",
"sha256:755b8edca87c974dd4f3605c374fda11db84631de3d163b99c0df5807023a19a"
"sha256:685d93ce5e5edb5e52310b72342cdc190bebf83aab058328943dd8bd8f6ac790",
"sha256:7807647e8254e5cff79bf2041ae272449ce915d3cf1bbecaa581c384163adb87"
],
"index": "pypi",
"markers": "python_version >= '3.9'",
"version": "==0.30.0"
"version": "==0.32.0"
},
"pytest-mock": {
"hashes": [

View File

@ -360,10 +360,10 @@ If you want to build the documentation locally, this is how you do it:
The docker image is primarily built by the GitHub actions workflow, but
it can be faster when developing to build and tag an image locally.
Building the image works as with any image:
Make sure you have the `docker-buildx` package installed. Building the image works as with any image:
```
docker build --file Dockerfile --tag paperless:local --progress simple .
docker build --file Dockerfile --tag paperless:local .
```
## Extending Paperless-ngx

View File

@ -132,3 +132,11 @@ Multiple options for ASGI servers exist:
- `daphne` as a standalone server, which is the reference
implementation for ASGI.
- `uvicorn` as a standalone server
## _What about the Redis licensing change and using one of the open source forks_?
Currently (October 2024), forks of Redis such as Valkey or Redirect are not officially supported by our upstream
libraries, so using one of these to replace Redis is not officially supported.
However, they do claim to be compatible with the Redis protocol and will likely work, but we will
not be updating from using Redis as the broker officially just yet.

View File

@ -560,7 +560,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">72</context>
<context context-type="linenumber">75</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context>
@ -726,7 +726,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
<context context-type="linenumber">137</context>
<context context-type="linenumber">146</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.html</context>
@ -1100,11 +1100,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
<context context-type="linenumber">99</context>
<context context-type="linenumber">108</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
<context context-type="linenumber">111</context>
<context context-type="linenumber">120</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.html</context>
@ -1406,7 +1406,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
<context context-type="linenumber">81</context>
<context context-type="linenumber">82</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.html</context>
@ -1505,11 +1505,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
<context context-type="linenumber">100</context>
<context context-type="linenumber">109</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
<context context-type="linenumber">114</context>
<context context-type="linenumber">123</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.html</context>
@ -1565,11 +1565,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.html</context>
<context context-type="linenumber">41</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.html</context>
<context context-type="linenumber">52</context>
<context context-type="linenumber">59</context>
</context-group>
</trans-unit>
<trans-unit id="6338800642797811873" datatype="html">
@ -1668,7 +1668,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">71</context>
<context context-type="linenumber">74</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html</context>
@ -2227,7 +2227,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context>
<context context-type="linenumber">179</context>
<context context-type="linenumber">194</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
@ -2430,11 +2430,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">107</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
<context context-type="linenumber">108</context>
<context context-type="linenumber">117</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.html</context>
@ -2470,11 +2470,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.html</context>
<context context-type="linenumber">40</context>
<context context-type="linenumber">47</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.html</context>
<context context-type="linenumber">49</context>
<context context-type="linenumber">56</context>
</context-group>
</trans-unit>
<trans-unit id="9124347207158517893" datatype="html">
@ -2578,7 +2578,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context>
<context context-type="linenumber">181</context>
<context context-type="linenumber">196</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
@ -3666,166 +3666,185 @@
<context context-type="linenumber">88</context>
</context-group>
</trans-unit>
<trans-unit id="5163375362523428079" datatype="html">
<source>Rule order</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">16</context>
</context-group>
</trans-unit>
<trans-unit id="4086606389696938932" datatype="html">
<source>Account</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">19</context>
<context context-type="linenumber">16</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
<context context-type="linenumber">80</context>
</context-group>
</trans-unit>
<trans-unit id="220550782947016929" datatype="html">
<source>Order</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">19</context>
</context-group>
</trans-unit>
<trans-unit id="4816216590591222133" datatype="html">
<source>Enabled</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">22</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">19</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
<context context-type="linenumber">96</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.html</context>
<context context-type="linenumber">34</context>
</context-group>
</trans-unit>
<trans-unit id="4348351765075925931" datatype="html">
<source>Paperless will only process mails that match <x id="START_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;em&gt;"/>all<x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/> of the criteria specified below.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">24</context>
<context context-type="linenumber">27</context>
</context-group>
</trans-unit>
<trans-unit id="7046259383943324039" datatype="html">
<source>Folder</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">26</context>
<context context-type="linenumber">29</context>
</context-group>
</trans-unit>
<trans-unit id="1391527525114848695" datatype="html">
<source>Subfolders must be separated by a delimiter, often a dot (&apos;.&apos;) or slash (&apos;/&apos;), but it varies by mail server.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">26</context>
<context context-type="linenumber">29</context>
</context-group>
</trans-unit>
<trans-unit id="101686279614365671" datatype="html">
<source>Maximum age (days)</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">27</context>
<context context-type="linenumber">30</context>
</context-group>
</trans-unit>
<trans-unit id="6925928412364847639" datatype="html">
<source>Filter from</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">30</context>
<context context-type="linenumber">33</context>
</context-group>
</trans-unit>
<trans-unit id="8977094263269822022" datatype="html">
<source>Filter to</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">31</context>
<context context-type="linenumber">34</context>
</context-group>
</trans-unit>
<trans-unit id="8497813481090627874" datatype="html">
<source>Filter subject</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">32</context>
<context context-type="linenumber">35</context>
</context-group>
</trans-unit>
<trans-unit id="7314357616097563149" datatype="html">
<source>Filter body</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">33</context>
<context context-type="linenumber">36</context>
</context-group>
</trans-unit>
<trans-unit id="559099472394646919" datatype="html">
<source>Consumption scope</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">39</context>
<context context-type="linenumber">42</context>
</context-group>
</trans-unit>
<trans-unit id="56643687972548912" datatype="html">
<source>See docs for .eml processing requirements</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">39</context>
<context context-type="linenumber">42</context>
</context-group>
</trans-unit>
<trans-unit id="7093509971705471817" datatype="html">
<source>Attachment type</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">40</context>
<context context-type="linenumber">43</context>
</context-group>
</trans-unit>
<trans-unit id="2873939123535615966" datatype="html">
<source>Include only files matching</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">43</context>
<context context-type="linenumber">46</context>
</context-group>
</trans-unit>
<trans-unit id="7233407036155150477" datatype="html">
<source>Optional. Wildcards e.g. *.pdf or *invoice* allowed. Can be comma-separated list. Case insensitive.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">43</context>
<context context-type="linenumber">46</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">44</context>
<context context-type="linenumber">47</context>
</context-group>
</trans-unit>
<trans-unit id="1546332577833742677" datatype="html">
<source>Exclude files matching</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">44</context>
<context context-type="linenumber">47</context>
</context-group>
</trans-unit>
<trans-unit id="9216117865911519658" datatype="html">
<source>Action</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">50</context>
<context context-type="linenumber">53</context>
</context-group>
</trans-unit>
<trans-unit id="7841986067387421166" datatype="html">
<source>Only performed if the mail is processed.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">50</context>
<context context-type="linenumber">53</context>
</context-group>
</trans-unit>
<trans-unit id="1261794314435932203" datatype="html">
<source>Action parameter</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">52</context>
<context context-type="linenumber">55</context>
</context-group>
</trans-unit>
<trans-unit id="6093797930511670257" datatype="html">
<source>Assign title from</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">54</context>
<context context-type="linenumber">57</context>
</context-group>
</trans-unit>
<trans-unit id="5232720756589450549" datatype="html">
<source>Assign owner from rule</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">55</context>
<context context-type="linenumber">58</context>
</context-group>
</trans-unit>
<trans-unit id="6695990587380209737" datatype="html">
<source>Assign document type</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">59</context>
<context context-type="linenumber">62</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
@ -3836,14 +3855,14 @@
<source>Assign correspondent from</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">60</context>
<context context-type="linenumber">63</context>
</context-group>
</trans-unit>
<trans-unit id="4875491778188965469" datatype="html">
<source>Assign correspondent</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">62</context>
<context context-type="linenumber">65</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
@ -3854,7 +3873,7 @@
<source>Error</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html</context>
<context context-type="linenumber">69</context>
<context context-type="linenumber">72</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
@ -4166,17 +4185,6 @@
<context context-type="linenumber">18</context>
</context-group>
</trans-unit>
<trans-unit id="4816216590591222133" datatype="html">
<source>Enabled</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">19</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.html</context>
<context context-type="linenumber">30</context>
</context-group>
</trans-unit>
<trans-unit id="1586840222182376783" datatype="html">
<source>Triggers</source>
<context-group purpose="location">
@ -5043,19 +5051,19 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
<context context-type="linenumber">101</context>
<context context-type="linenumber">110</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
<context context-type="linenumber">119</context>
<context context-type="linenumber">128</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.html</context>
<context context-type="linenumber">42</context>
<context context-type="linenumber">49</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.html</context>
<context context-type="linenumber">57</context>
<context context-type="linenumber">64</context>
</context-group>
</trans-unit>
<trans-unit id="595732867213154214" datatype="html">
@ -5358,6 +5366,10 @@
<context context-type="sourcefile">src/app/components/common/toasts/toasts.component.html</context>
<context context-type="linenumber">26</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
<context context-type="linenumber">81</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.html</context>
<context context-type="linenumber">19</context>
@ -7513,11 +7525,22 @@
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="5769292297914455214" datatype="html">
<source>Disabled</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
<context context-type="linenumber">96</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.html</context>
<context context-type="linenumber">34</context>
</context-group>
</trans-unit>
<trans-unit id="6751234988479444294" datatype="html">
<source>No mail rules defined.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
<context context-type="linenumber">128</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="3178554336792037159" datatype="html">
@ -7590,46 +7613,67 @@
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="3574401690710711341" datatype="html">
<source>Rule &quot;<x id="PH" equiv-text="rule.name"/>&quot; enabled.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context>
<context context-type="linenumber">178</context>
</context-group>
</trans-unit>
<trans-unit id="7171685227222299542" datatype="html">
<source>Rule &quot;<x id="PH" equiv-text="rule.name"/>&quot; disabled.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context>
<context context-type="linenumber">179</context>
</context-group>
</trans-unit>
<trans-unit id="684458488797860482" datatype="html">
<source>Error toggling rule.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context>
<context context-type="linenumber">183</context>
</context-group>
</trans-unit>
<trans-unit id="3896080636020672118" datatype="html">
<source>Confirm delete mail rule</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context>
<context context-type="linenumber">177</context>
<context context-type="linenumber">192</context>
</context-group>
</trans-unit>
<trans-unit id="2250372580580310337" datatype="html">
<source>This operation will permanently delete this mail rule.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context>
<context context-type="linenumber">178</context>
<context context-type="linenumber">193</context>
</context-group>
</trans-unit>
<trans-unit id="9077981247971516916" datatype="html">
<source>Deleted mail rule</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context>
<context context-type="linenumber">187</context>
<context context-type="linenumber">202</context>
</context-group>
</trans-unit>
<trans-unit id="2033194641751367552" datatype="html">
<source>Error deleting mail rule.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context>
<context context-type="linenumber">196</context>
<context context-type="linenumber">211</context>
</context-group>
</trans-unit>
<trans-unit id="3061362835271417984" datatype="html">
<source>Permissions updated</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context>
<context context-type="linenumber">218</context>
<context context-type="linenumber">233</context>
</context-group>
</trans-unit>
<trans-unit id="4639647950943944112" datatype="html">
<source>Error updating permissions</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context>
<context context-type="linenumber">223</context>
<context context-type="linenumber">238</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
@ -7879,18 +7923,11 @@
<context context-type="linenumber">9</context>
</context-group>
</trans-unit>
<trans-unit id="5769292297914455214" datatype="html">
<source>Disabled</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.html</context>
<context context-type="linenumber">30</context>
</context-group>
</trans-unit>
<trans-unit id="1624023882313260402" datatype="html">
<source>No workflows defined.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.html</context>
<context context-type="linenumber">66</context>
<context context-type="linenumber">73</context>
</context-group>
</trans-unit>
<trans-unit id="4200688335642457098" datatype="html">
@ -7935,6 +7972,27 @@
<context context-type="linenumber">128</context>
</context-group>
</trans-unit>
<trans-unit id="5459159218551862653" datatype="html">
<source>Enabled workflow</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.ts</context>
<context context-type="linenumber">139</context>
</context-group>
</trans-unit>
<trans-unit id="6035681056091592756" datatype="html">
<source>Disabled workflow</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.ts</context>
<context context-type="linenumber">140</context>
</context-group>
</trans-unit>
<trans-unit id="1376040678213338380" datatype="html">
<source>Error toggling workflow.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.ts</context>
<context context-type="linenumber">146</context>
</context-group>
</trans-unit>
<trans-unit id="2649252321173430744" datatype="html">
<source>Not Found</source>
<context-group purpose="location">
@ -8779,21 +8837,21 @@
<source>Successfully completed one-time migratration of settings to the database!</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">573</context>
<context context-type="linenumber">574</context>
</context-group>
</trans-unit>
<trans-unit id="5558341108007064934" datatype="html">
<source>Unable to migrate settings to the database, please try saving manually.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">574</context>
<context context-type="linenumber">575</context>
</context-group>
</trans-unit>
<trans-unit id="1168781785897678748" datatype="html">
<source>You can restart the tour from the settings page.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">644</context>
<context context-type="linenumber">645</context>
</context-group>
</trans-unit>
<trans-unit id="3852289441366561594" datatype="html">

View File

@ -65,10 +65,6 @@ form {
--pngx-focus-alpha: 0;
}
.cursor-pointer {
cursor: pointer;
}
.mh-75 {
max-height: 75vh;
}

View File

@ -12,12 +12,15 @@
<div class="col-md-4">
<pngx-input-text [horizontal]="true" i18n-title title="Name" formControlName="name" [error]="error?.name" autocomplete="off"></pngx-input-text>
</div>
<div class="col-md-4">
<pngx-input-number [horizontal]="true" i18n-title title="Rule order" formControlName="order" [showAdd]="false" [error]="error?.order"></pngx-input-number>
</div>
<div class="col-md-4">
<div class="col-md-3">
<pngx-input-select [horizontal]="true" i18n-title title="Account" [items]="accounts" formControlName="account"></pngx-input-select>
</div>
<div class="col-md-3">
<pngx-input-number [horizontal]="true" i18n-title title="Order" formControlName="order" [showAdd]="false" [error]="error?.order"></pngx-input-number>
</div>
<div class="col-md-2 pt-2">
<pngx-input-switch [horizontal]="true" i18n-title title="Enabled" formControlName="enabled"></pngx-input-switch>
</div>
</div>
<hr class="mt-0"/>
<div class="row">

View File

@ -24,6 +24,7 @@ import { TextComponent } from '../../input/text/text.component'
import { EditDialogMode } from '../edit-dialog.component'
import { MailRuleEditDialogComponent } from './mail-rule-edit-dialog.component'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
import { SwitchComponent } from '../../input/switch/switch.component'
describe('MailRuleEditDialogComponent', () => {
let component: MailRuleEditDialogComponent
@ -43,6 +44,7 @@ describe('MailRuleEditDialogComponent', () => {
TagsComponent,
SafeHtmlPipe,
CheckComponent,
SwitchComponent,
],
imports: [FormsModule, ReactiveFormsModule, NgSelectModule, NgbModule],
providers: [

View File

@ -153,6 +153,7 @@ export class MailRuleEditDialogComponent extends EditDialogComponent<MailRule> {
return new FormGroup({
name: new FormControl(null),
account: new FormControl(null),
enabled: new FormControl(true),
folder: new FormControl('INBOX'),
filter_from: new FormControl(null),
filter_to: new FormControl(null),

View File

@ -6,10 +6,6 @@ tr {
user-select: none;
}
.cursor-pointer {
cursor: pointer;
}
.table-row-selected {
background-color: var(--pngx-primary-faded);
}

View File

@ -78,6 +78,7 @@
<div class="col" i18n>Name</div>
<div class="col d-none d-sm-block" i18n>Sort Order</div>
<div class="col" i18n>Account</div>
<div class="col d-none d-sm-block" i18n>Status</div>
<div class="col" i18n>Actions</div>
</div>
</li>
@ -86,8 +87,16 @@
<li class="list-group-item">
<div class="row">
<div class="col d-flex align-items-center"><button class="btn btn-link p-0 text-start" type="button" (click)="editMailRule(rule)" [disabled]="!permissionsService.currentUserCan(PermissionAction.Change, PermissionType.MailRule)">{{rule.name}}</button></div>
<div class="col d-flex align-items-center d-none d-sm-block">{{rule.order}}</div>
<div class="col d-flex align-items-center d-none d-sm-flex">{{rule.order}}</div>
<div class="col d-flex align-items-center">{{(mailAccountService.getCached(rule.account) | async)?.name}}</div>
<div class="col d-flex align-items-center d-none d-sm-flex">
<div class="form-check form-switch mb-0">
<input #inputField type="checkbox" class="form-check-input cursor-pointer" [id]="rule.id+'_enable'" [(ngModel)]="rule.enabled" (change)="onMailRuleEnableToggled(rule)" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.MailRule }">
<label class="form-check-label cursor-pointer" [for]="rule.id+'_enable'">
<code> @if(rule.enabled) { <ng-container i18n>Enabled</ng-container> } @else { <span i18n class="text-muted">Disabled</span> }</code>
</label>
</div>
</div>
<div class="col">
<div class="btn-group d-block d-sm-none">
<div ngbDropdown container="body" class="d-inline-block">

View File

@ -43,14 +43,15 @@ import { EditDialogMode } from '../../common/edit-dialog/edit-dialog.component'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { SwitchComponent } from '../../common/input/switch/switch.component'
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
import { By } from '@angular/platform-browser'
const mailAccounts = [
{ id: 1, name: 'account1' },
{ id: 2, name: 'account2' },
]
const mailRules = [
{ id: 1, name: 'rule1', owner: 1, account: 1 },
{ id: 2, name: 'rule2', owner: 2, account: 2 },
{ id: 1, name: 'rule1', owner: 1, account: 1, enabled: true },
{ id: 2, name: 'rule2', owner: 2, account: 2, enabled: true },
]
describe('MailComponent', () => {
@ -321,4 +322,30 @@ describe('MailComponent', () => {
dialog.confirmClicked.emit({ permissions: perms, merge: true })
expect(accountPatchSpy).toHaveBeenCalled()
})
it('should update mail rule when enable is toggled', () => {
completeSetup()
const patchSpy = jest.spyOn(mailRuleService, 'patch')
const toggleInput = fixture.debugElement.query(
By.css('input[type="checkbox"]')
)
const toastErrorSpy = jest.spyOn(toastService, 'showError')
const toastInfoSpy = jest.spyOn(toastService, 'showInfo')
// fail first
patchSpy.mockReturnValueOnce(
throwError(() => new Error('Error getting config'))
)
toggleInput.nativeElement.click()
expect(patchSpy).toHaveBeenCalled()
expect(toastErrorSpy).toHaveBeenCalled()
// succeed second
patchSpy.mockReturnValueOnce(of(mailRules[0] as MailRule))
toggleInput.nativeElement.click()
patchSpy.mockReturnValueOnce(
of({ ...mailRules[0], enabled: false } as MailRule)
)
toggleInput.nativeElement.click()
expect(patchSpy).toHaveBeenCalled()
expect(toastInfoSpy).toHaveBeenCalled()
})
})

View File

@ -170,6 +170,21 @@ export class MailComponent
this.editMailRule(clone, true)
}
onMailRuleEnableToggled(rule: MailRule) {
this.mailRuleService.patch(rule).subscribe({
next: () => {
this.toastService.showInfo(
rule.enabled
? $localize`Rule "${rule.name}" enabled.`
: $localize`Rule "${rule.name}" disabled.`
)
},
error: (e) => {
this.toastService.showError($localize`Error toggling rule.`, e)
},
})
}
deleteMailRule(rule: MailRule) {
const modal = this.modalService.open(ConfirmDialogComponent, {
backdrop: 'static',

View File

@ -15,9 +15,9 @@
<li class="list-group-item">
<div class="row">
<div class="col" i18n>Name</div>
<div class="col d-none d-sm-block" i18n>Sort order</div>
<div class="col d-none d-sm-flex" i18n>Sort order</div>
<div class="col" i18n>Status</div>
<div class="col d-none d-sm-block" i18n>Triggers</div>
<div class="col d-none d-sm-flex" i18n>Triggers</div>
<div class="col" i18n>Actions</div>
</div>
</li>
@ -26,9 +26,16 @@
<li class="list-group-item">
<div class="row">
<div class="col d-flex align-items-center"><button class="btn btn-link p-0 text-start" type="button" (click)="editWorkflow(workflow)" [disabled]="!permissionsService.currentUserCan(PermissionAction.Change, PermissionType.Workflow)">{{workflow.name}}</button></div>
<div class="col d-flex align-items-center d-none d-sm-block"><code>{{workflow.order}}</code></div>
<div class="col d-flex align-items-center"><code> @if(workflow.enabled) { <ng-container i18n>Enabled</ng-container> } @else { <span i18n class="text-muted">Disabled</span> }</code></div>
<div class="col d-flex align-items-center d-none d-sm-block">{{getTypesList(workflow)}}</div>
<div class="col d-flex align-items-center d-none d-sm-flex"><code>{{workflow.order}}</code></div>
<div class="col d-flex align-items-center">
<div class="form-check form-switch mb-0">
<input #inputField type="checkbox" class="form-check-input cursor-pointer" [id]="workflow.id+'_enable'" [(ngModel)]="workflow.enabled" (change)="onWorkflowEnableToggled(workflow)" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.Workflow }">
<label class="form-check-label cursor-pointer" [for]="workflow.id+'_enable'">
<code> @if(workflow.enabled) { <ng-container i18n>Enabled</ng-container> } @else { <span i18n class="text-muted">Disabled</span> }</code>
</label>
</div>
</div>
<div class="col d-flex align-items-center d-none d-sm-flex">{{getTypesList(workflow)}}</div>
<div class="col">
<div class="btn-group d-block d-sm-none">

View File

@ -211,4 +211,27 @@ describe('WorkflowsComponent', () => {
editDialog.confirmClicked.emit()
expect(reloadSpy).toHaveBeenCalled()
})
it('should update workflow when enable is toggled', () => {
const patchSpy = jest.spyOn(workflowService, 'patch')
const toggleInput = fixture.debugElement.query(
By.css('input[type="checkbox"]')
)
const toastErrorSpy = jest.spyOn(toastService, 'showError')
const toastInfoSpy = jest.spyOn(toastService, 'showInfo')
// fail first
patchSpy.mockReturnValueOnce(
throwError(() => new Error('Error getting config'))
)
toggleInput.nativeElement.click()
expect(patchSpy).toHaveBeenCalled()
expect(toastErrorSpy).toHaveBeenCalled()
// succeed second
patchSpy.mockReturnValueOnce(of(workflows[0]))
toggleInput.nativeElement.click()
patchSpy.mockReturnValueOnce(of({ ...workflows[0], enabled: false }))
toggleInput.nativeElement.click()
expect(patchSpy).toHaveBeenCalled()
expect(toastInfoSpy).toHaveBeenCalled()
})
})

View File

@ -130,4 +130,21 @@ export class WorkflowsComponent
})
})
}
onWorkflowEnableToggled(workflow: Workflow) {
this.workflowService.patch(workflow).subscribe({
next: () => {
this.toastService.showInfo(
workflow.enabled
? $localize`Enabled workflow`
: $localize`Disabled workflow`
)
this.workflowService.clearCache()
this.reload()
},
error: (e) => {
this.toastService.showError($localize`Error toggling workflow.`, e)
},
})
}
}

View File

@ -39,6 +39,8 @@ export interface MailRule extends ObjectWithPermissions {
order: number
enabled: boolean
folder: string
filter_from: string

View File

@ -18,6 +18,7 @@ const mail_rules = [
id: 1,
account: 1,
order: 1,
enabled: true,
folder: 'INBOX',
filter_from: null,
filter_to: null,
@ -36,6 +37,7 @@ const mail_rules = [
id: 2,
account: 1,
order: 1,
enabled: true,
folder: 'INBOX',
filter_from: null,
filter_to: null,
@ -54,6 +56,7 @@ const mail_rules = [
id: 3,
account: 1,
order: 1,
enabled: true,
folder: 'INBOX',
filter_from: null,
filter_to: null,

View File

@ -369,6 +369,10 @@ textarea,
cursor: not-allowed;
}
.cursor-pointer {
cursor: pointer;
}
ul.pagination {
margin-bottom: 0;
}

View File

@ -8,7 +8,7 @@ class TestMigrateWorkflow(TestMigrations):
dependencies = (
(
"paperless_mail",
"0025_alter_mailaccount_owner_alter_mailrule_owner_and_more",
"0026_mailrule_enabled",
),
)

View File

@ -53,7 +53,7 @@ class MailRuleAdmin(GuardedModelAdmin):
}
fieldsets = (
(None, {"fields": ("name", "order", "account", "folder")}),
(None, {"fields": ("name", "order", "account", "enabled", "folder")}),
(
_("Filter"),
{

View File

@ -544,6 +544,9 @@ class MailAccountHandler(LoggingMixin):
)
for rule in account.rules.order_by("order"):
if not rule.enabled:
self.log.debug(f"Rule {rule}: Skipping disabled rule")
continue
try:
total_processed_files += self._handle_mail_rule(
M,

View File

@ -0,0 +1,21 @@
# Generated by Django 5.1.1 on 2024-09-30 15:17
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
(
"paperless_mail",
"0025_alter_mailaccount_owner_alter_mailrule_owner_and_more",
),
]
operations = [
migrations.AddField(
model_name="mailrule",
name="enabled",
field=models.BooleanField(default=True, verbose_name="enabled"),
),
]

View File

@ -115,6 +115,8 @@ class MailRule(document_models.ModelWithOwner):
verbose_name=_("account"),
)
enabled = models.BooleanField(_("enabled"), default=True)
folder = models.CharField(
_("folder"),
default="INBOX",

View File

@ -74,6 +74,7 @@ class MailRuleSerializer(OwnedObjectSerializer):
"id",
"name",
"account",
"enabled",
"folder",
"filter_from",
"filter_to",

View File

@ -1388,6 +1388,41 @@ class TestMail(
self.assertEqual(len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", False)), 0)
self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 3)
def test_disabled_rule(self):
"""
GIVEN:
- Mail rule is disabled
WHEN:
- Mail account is handled
THEN:
- Should not process any messages
"""
account = MailAccount.objects.create(
name="test",
imap_server="",
username="admin",
password="secret",
)
MailRule.objects.create(
name="testrule",
account=account,
action=MailRule.MailAction.MARK_READ,
enabled=False,
)
self.mail_account_handler.handle_mail_account(account)
self.mailMocker.apply_mail_actions()
self.assertEqual(len(self.mailMocker.bogus_mailbox.messages), 3)
self.assertEqual(len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", False)), 2)
self.mail_account_handler.handle_mail_account(account)
self.mailMocker.apply_mail_actions()
self.assertEqual(
len(self.mailMocker.bogus_mailbox.fetch("UNSEEN", False)),
2,
) # still 2
class TestManagementCommand(TestCase):
@mock.patch(

View File

@ -497,6 +497,7 @@ class TestParser:
assert mail_parser.archive_path is not None
@pytest.mark.httpx_mock(can_send_already_matched_responses=True)
def test_generate_pdf_html_email(
self,
httpx_mock: HTTPXMock,
@ -575,6 +576,7 @@ class TestParser:
with pytest.raises(ParseError):
mail_parser.parse(html_email_file, "message/rfc822")
@pytest.mark.httpx_mock(can_send_already_matched_responses=True)
def test_generate_pdf_html_email_merge_failure(
self,
httpx_mock: HTTPXMock,

View File

@ -5,7 +5,6 @@ from pathlib import Path
import pytest
from httpx import codes
from httpx._multipart import DataField
from pytest_django.fixtures import SettingsWrapper
from pytest_httpx import HTTPXMock
@ -128,11 +127,22 @@ class TestTikaParser:
tika_parser.convert_to_pdf(sample_odt_file, None)
request = httpx_mock.get_request()
found = False
for field in request.stream.fields:
if isinstance(field, DataField) and field.name == "pdfa":
assert field.value == expected_form_value
found = True
assert found, "pdfFormat was not found"
httpx_mock.reset(assert_all_responses_were_requested=False)
expected_field_name = "pdfa"
content_type = request.headers["Content-Type"]
assert "multipart/form-data" in content_type
boundary = content_type.split("boundary=")[1]
parts = request.content.split(f"--{boundary}".encode())
form_field_found = any(
f'name="{expected_field_name}"'.encode() in part
and expected_form_value.encode() in part
for part in parts
)
assert form_field_found
httpx_mock.reset()