paperless-ngx/src/documents/bulk_edit.py

128 lines
3.3 KiB
Python
Raw Normal View History

import itertools
2020-12-11 14:27:54 +01:00
from django.db.models import Q
from django_q.tasks import async_task
from documents.models import Correspondent
from documents.models import Document
from documents.models import DocumentType
Feature: Dynamic document storage pathes (#916) * Added devcontainer * Add feature storage pathes * Exclude tests and add versioning * Check escaping * Check escaping * Check quoting * Echo * Escape * Escape : * Double escape \ * Escaping * Remove if * Escape colon * Missing \ * Esacpe : * Escape all * test * Remove sed * Fix exclude * Remove SED command * Add LD_LIBRARY_PATH * Adjusted to v1.7 * Updated test-cases * Remove devcontainer * Removed internal build-file * Run pre-commit * Corrected flak8 error * Adjusted to v1.7 * Updated test-cases * Corrected flak8 error * Adjusted to new plural translations * Small adjustments due to code-review backend * Adjusted line-break * Removed PAPERLESS prefix from settings variables * Corrected style change due to search+replace * First documentation draft * Revert changes to Pipfile * Add sphinx-autobuild with keep-outdated * Revert merge error that results in wrong storage path is evaluated * Adjust styles of generated files ... * Adds additional testing to cover dynamic storage path functionality * Remove unnecessary condition * Add hint to edit storage path dialog * Correct spelling of pathes to paths * Minor documentation tweaks * Minor typo * improving wrapping of filter editor buttons with new storage path button * Update .gitignore * Fix select border radius in non input-groups * Better storage path edit hint * Add note to edit storage path dialog re document_renamer * Add note to bulk edit storage path re document_renamer * Rename FILTER_STORAGE_DIRECTORY to PATH * Fix broken filter rule parsing * Show default storage if unspecified * Remove note re storage path on bulk edit * Add basic validation of filename variables Co-authored-by: Markus Kling <markus@markus-kling.net> Co-authored-by: Trenton Holmes <holmes.trenton@gmail.com> Co-authored-by: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Co-authored-by: Quinn Casey <quinn@quinncasey.com>
2022-05-19 23:42:25 +02:00
from documents.models import StoragePath
2020-11-30 13:58:40 +01:00
2020-12-11 14:27:54 +01:00
def set_correspondent(doc_ids, correspondent):
if correspondent:
correspondent = Correspondent.objects.get(id=correspondent)
2020-11-30 13:58:40 +01:00
2022-02-27 15:26:41 +01:00
qs = Document.objects.filter(Q(id__in=doc_ids) & ~Q(correspondent=correspondent))
2020-12-11 14:27:54 +01:00
affected_docs = [doc.id for doc in qs]
qs.update(correspondent=correspondent)
2020-11-30 13:58:40 +01:00
2022-02-27 15:26:41 +01:00
async_task("documents.tasks.bulk_update_documents", document_ids=affected_docs)
2020-11-30 13:58:40 +01:00
2020-12-11 14:27:54 +01:00
return "OK"
2020-11-30 13:58:40 +01:00
Feature: Dynamic document storage pathes (#916) * Added devcontainer * Add feature storage pathes * Exclude tests and add versioning * Check escaping * Check escaping * Check quoting * Echo * Escape * Escape : * Double escape \ * Escaping * Remove if * Escape colon * Missing \ * Esacpe : * Escape all * test * Remove sed * Fix exclude * Remove SED command * Add LD_LIBRARY_PATH * Adjusted to v1.7 * Updated test-cases * Remove devcontainer * Removed internal build-file * Run pre-commit * Corrected flak8 error * Adjusted to v1.7 * Updated test-cases * Corrected flak8 error * Adjusted to new plural translations * Small adjustments due to code-review backend * Adjusted line-break * Removed PAPERLESS prefix from settings variables * Corrected style change due to search+replace * First documentation draft * Revert changes to Pipfile * Add sphinx-autobuild with keep-outdated * Revert merge error that results in wrong storage path is evaluated * Adjust styles of generated files ... * Adds additional testing to cover dynamic storage path functionality * Remove unnecessary condition * Add hint to edit storage path dialog * Correct spelling of pathes to paths * Minor documentation tweaks * Minor typo * improving wrapping of filter editor buttons with new storage path button * Update .gitignore * Fix select border radius in non input-groups * Better storage path edit hint * Add note to edit storage path dialog re document_renamer * Add note to bulk edit storage path re document_renamer * Rename FILTER_STORAGE_DIRECTORY to PATH * Fix broken filter rule parsing * Show default storage if unspecified * Remove note re storage path on bulk edit * Add basic validation of filename variables Co-authored-by: Markus Kling <markus@markus-kling.net> Co-authored-by: Trenton Holmes <holmes.trenton@gmail.com> Co-authored-by: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Co-authored-by: Quinn Casey <quinn@quinncasey.com>
2022-05-19 23:42:25 +02:00
def set_storage_path(doc_ids, storage_path):
if storage_path:
storage_path = StoragePath.objects.get(id=storage_path)
qs = Document.objects.filter(
Q(id__in=doc_ids) & ~Q(storage_path=storage_path),
)
affected_docs = [doc.id for doc in qs]
qs.update(storage_path=storage_path)
async_task(
"documents.tasks.bulk_update_documents",
document_ids=affected_docs,
)
return "OK"
2020-12-11 14:27:54 +01:00
def set_document_type(doc_ids, document_type):
if document_type:
document_type = DocumentType.objects.get(id=document_type)
2020-11-30 13:58:40 +01:00
2022-02-27 15:26:41 +01:00
qs = Document.objects.filter(Q(id__in=doc_ids) & ~Q(document_type=document_type))
2020-12-11 14:27:54 +01:00
affected_docs = [doc.id for doc in qs]
qs.update(document_type=document_type)
2020-11-30 13:58:40 +01:00
2022-02-27 15:26:41 +01:00
async_task("documents.tasks.bulk_update_documents", document_ids=affected_docs)
2020-11-30 13:58:40 +01:00
2020-12-11 14:27:54 +01:00
return "OK"
2020-12-06 14:39:53 +01:00
2020-12-11 14:27:54 +01:00
def add_tag(doc_ids, tag):
2020-12-06 14:39:53 +01:00
2020-12-11 14:27:54 +01:00
qs = Document.objects.filter(Q(id__in=doc_ids) & ~Q(tags__id=tag))
affected_docs = [doc.id for doc in qs]
DocumentTagRelationship = Document.tags.through
2022-02-27 15:26:41 +01:00
DocumentTagRelationship.objects.bulk_create(
[DocumentTagRelationship(document_id=doc, tag_id=tag) for doc in affected_docs],
2022-02-27 15:26:41 +01:00
)
2020-12-11 14:27:54 +01:00
2022-02-27 15:26:41 +01:00
async_task("documents.tasks.bulk_update_documents", document_ids=affected_docs)
2020-12-11 14:27:54 +01:00
return "OK"
def remove_tag(doc_ids, tag):
qs = Document.objects.filter(Q(id__in=doc_ids) & Q(tags__id=tag))
affected_docs = [doc.id for doc in qs]
DocumentTagRelationship = Document.tags.through
DocumentTagRelationship.objects.filter(
Q(document_id__in=affected_docs) & Q(tag_id=tag),
2020-12-11 14:27:54 +01:00
).delete()
2022-02-27 15:26:41 +01:00
async_task("documents.tasks.bulk_update_documents", document_ids=affected_docs)
2020-12-11 14:27:54 +01:00
return "OK"
def modify_tags(doc_ids, add_tags, remove_tags):
qs = Document.objects.filter(id__in=doc_ids)
affected_docs = [doc.id for doc in qs]
DocumentTagRelationship = Document.tags.through
DocumentTagRelationship.objects.filter(
document_id__in=affected_docs,
tag_id__in=remove_tags,
).delete()
2022-02-27 15:26:41 +01:00
DocumentTagRelationship.objects.bulk_create(
[
DocumentTagRelationship(document_id=doc, tag_id=tag)
for (doc, tag) in itertools.product(affected_docs, add_tags)
],
ignore_conflicts=True,
)
2022-02-27 15:26:41 +01:00
async_task("documents.tasks.bulk_update_documents", document_ids=affected_docs)
return "OK"
2020-12-11 14:27:54 +01:00
def delete(doc_ids):
Document.objects.filter(id__in=doc_ids).delete()
2021-02-15 13:26:36 +01:00
from documents import index
with index.open_index_writer() as writer:
for id in doc_ids:
index.remove_document_by_id(writer, id)
2020-12-11 14:27:54 +01:00
return "OK"
2022-06-22 05:53:41 -07:00
def redo_ocr(doc_ids):
async_task("documents.tasks.redo_ocr", document_ids=doc_ids)
return "OK"