Format Python code with black

This commit is contained in:
kpj
2022-02-27 15:26:41 +01:00
parent f0ffc69010
commit c56cb25b5f
136 changed files with 6142 additions and 3811 deletions

View File

@@ -19,7 +19,7 @@ class Command(BaseCommand):
parser.add_argument(
"--passphrase",
help="If PAPERLESS_PASSPHRASE isn't set already, you need to "
"specify it here"
"specify it here",
)
def handle(self, *args, **options):
@@ -50,12 +50,12 @@ class Command(BaseCommand):
def __gpg_to_unencrypted(passphrase):
encrypted_files = Document.objects.filter(
storage_type=Document.STORAGE_TYPE_GPG)
storage_type=Document.STORAGE_TYPE_GPG
)
for document in encrypted_files:
print("Decrypting {}".format(
document).encode('utf-8'))
print("Decrypting {}".format(document).encode("utf-8"))
old_paths = [document.source_path, document.thumbnail_path]
@@ -66,10 +66,11 @@ class Command(BaseCommand):
ext = os.path.splitext(document.filename)[1]
if not ext == '.gpg':
if not ext == ".gpg":
raise CommandError(
f"Abort: encrypted file {document.source_path} does not "
f"end with .gpg")
f"end with .gpg"
)
document.filename = os.path.splitext(document.filename)[0]
@@ -80,7 +81,8 @@ class Command(BaseCommand):
f.write(raw_thumb)
Document.objects.filter(id=document.id).update(
storage_type=document.storage_type, filename=document.filename)
storage_type=document.storage_type, filename=document.filename
)
for path in old_paths:
os.unlink(path)

View File

@@ -16,8 +16,7 @@ from whoosh.writing import AsyncWriter
from documents.models import Document
from ... import index
from ...file_handling import create_source_path_directory, \
generate_unique_filename
from ...file_handling import create_source_path_directory, generate_unique_filename
from ...parsers import get_parser_class_for_mime_type
@@ -32,51 +31,49 @@ def handle_document(document_id):
parser_class = get_parser_class_for_mime_type(mime_type)
if not parser_class:
logger.error(f"No parser found for mime type {mime_type}, cannot "
f"archive document {document} (ID: {document_id})")
logger.error(
f"No parser found for mime type {mime_type}, cannot "
f"archive document {document} (ID: {document_id})"
)
return
parser = parser_class(logging_group=uuid.uuid4())
try:
parser.parse(
document.source_path,
mime_type,
document.get_public_filename())
parser.parse(document.source_path, mime_type, document.get_public_filename())
thumbnail = parser.get_optimised_thumbnail(
document.source_path,
mime_type,
document.get_public_filename()
document.source_path, mime_type, document.get_public_filename()
)
if parser.get_archive_path():
with transaction.atomic():
with open(parser.get_archive_path(), 'rb') as f:
with open(parser.get_archive_path(), "rb") as f:
checksum = hashlib.md5(f.read()).hexdigest()
# I'm going to save first so that in case the file move
# fails, the database is rolled back.
# We also don't use save() since that triggers the filehandling
# logic, and we don't want that yet (file not yet in place)
document.archive_filename = generate_unique_filename(
document, archive_filename=True)
document, archive_filename=True
)
Document.objects.filter(pk=document.pk).update(
archive_checksum=checksum,
content=parser.get_text(),
archive_filename=document.archive_filename
archive_filename=document.archive_filename,
)
with FileLock(settings.MEDIA_LOCK):
create_source_path_directory(document.archive_path)
shutil.move(parser.get_archive_path(),
document.archive_path)
shutil.move(parser.get_archive_path(), document.archive_path)
shutil.move(thumbnail, document.thumbnail_path)
with index.open_index_writer() as writer:
index.update_document(writer, document)
except Exception as e:
logger.exception(f"Error while parsing document {document} "
f"(ID: {document_id})")
logger.exception(
f"Error while parsing document {document} " f"(ID: {document_id})"
)
finally:
parser.cleanup()
@@ -88,29 +85,33 @@ class Command(BaseCommand):
and document types to all documents, effectively allowing you to
back-tag all previously indexed documents with metadata created (or
modified) after their initial import.
""".replace(" ", "")
""".replace(
" ", ""
)
def add_arguments(self, parser):
parser.add_argument(
"-f", "--overwrite",
"-f",
"--overwrite",
default=False,
action="store_true",
help="Recreates the archived document for documents that already "
"have an archived version."
"have an archived version.",
)
parser.add_argument(
"-d", "--document",
"-d",
"--document",
default=None,
type=int,
required=False,
help="Specify the ID of a document, and this command will only "
"run on this specific document."
"run on this specific document.",
)
parser.add_argument(
"--no-progress-bar",
default=False,
action="store_true",
help="If set, the progress bar will not be shown"
help="If set, the progress bar will not be shown",
)
def handle(self, *args, **options):
@@ -119,18 +120,17 @@ class Command(BaseCommand):
overwrite = options["overwrite"]
if options['document']:
documents = Document.objects.filter(pk=options['document'])
if options["document"]:
documents = Document.objects.filter(pk=options["document"])
else:
documents = Document.objects.all()
document_ids = list(map(
lambda doc: doc.id,
filter(
lambda d: overwrite or not d.has_archive_version,
documents
document_ids = list(
map(
lambda doc: doc.id,
filter(lambda d: overwrite or not d.has_archive_version, documents),
)
))
)
# Note to future self: this prevents django from reusing database
# conncetions between processes, which is bad and does not work
@@ -141,13 +141,12 @@ class Command(BaseCommand):
logging.getLogger().handlers[0].level = logging.ERROR
with multiprocessing.Pool(processes=settings.TASK_WORKERS) as pool:
list(tqdm.tqdm(
pool.imap_unordered(
handle_document,
document_ids
),
total=len(document_ids),
disable=options['no_progress_bar']
))
list(
tqdm.tqdm(
pool.imap_unordered(handle_document, document_ids),
total=len(document_ids),
disable=options["no_progress_bar"],
)
)
except KeyboardInterrupt:
print("Aborting...")

View File

@@ -23,24 +23,21 @@ logger = logging.getLogger("paperless.management.consumer")
def _tags_from_path(filepath):
"""Walk up the directory tree from filepath to CONSUMPTION_DIR
and get or create Tag IDs for every directory.
and get or create Tag IDs for every directory.
"""
tag_ids = set()
path_parts = Path(filepath).relative_to(
settings.CONSUMPTION_DIR).parent.parts
path_parts = Path(filepath).relative_to(settings.CONSUMPTION_DIR).parent.parts
for part in path_parts:
tag_ids.add(Tag.objects.get_or_create(name__iexact=part, defaults={
"name": part
})[0].pk)
tag_ids.add(
Tag.objects.get_or_create(name__iexact=part, defaults={"name": part})[0].pk
)
return tag_ids
def _is_ignored(filepath: str) -> bool:
filepath_relative = PurePath(filepath).relative_to(
settings.CONSUMPTION_DIR)
return any(
filepath_relative.match(p) for p in settings.CONSUMER_IGNORE_PATTERNS)
filepath_relative = PurePath(filepath).relative_to(settings.CONSUMPTION_DIR)
return any(filepath_relative.match(p) for p in settings.CONSUMER_IGNORE_PATTERNS)
def _consume(filepath):
@@ -48,13 +45,11 @@ def _consume(filepath):
return
if not os.path.isfile(filepath):
logger.debug(
f"Not consuming file {filepath}: File has moved.")
logger.debug(f"Not consuming file {filepath}: File has moved.")
return
if not is_file_ext_supported(os.path.splitext(filepath)[1]):
logger.warning(
f"Not consuming file {filepath}: Unknown file extension.")
logger.warning(f"Not consuming file {filepath}: Unknown file extension.")
return
tag_ids = None
@@ -66,10 +61,12 @@ def _consume(filepath):
try:
logger.info(f"Adding {filepath} to the task queue.")
async_task("documents.tasks.consume_file",
filepath,
override_tag_ids=tag_ids if tag_ids else None,
task_name=os.path.basename(filepath)[:100])
async_task(
"documents.tasks.consume_file",
filepath,
override_tag_ids=tag_ids if tag_ids else None,
task_name=os.path.basename(filepath)[:100],
)
except Exception as e:
# Catch all so that the consumer won't crash.
# This is also what the test case is listening for to check for
@@ -88,8 +85,9 @@ def _consume_wait_unmodified(file):
try:
new_mtime = os.stat(file).st_mtime
except FileNotFoundError:
logger.debug(f"File {file} moved while waiting for it to remain "
f"unmodified.")
logger.debug(
f"File {file} moved while waiting for it to remain " f"unmodified."
)
return
if new_mtime == mtime:
_consume(file)
@@ -102,16 +100,11 @@ def _consume_wait_unmodified(file):
class Handler(FileSystemEventHandler):
def on_created(self, event):
Thread(
target=_consume_wait_unmodified, args=(event.src_path,)
).start()
Thread(target=_consume_wait_unmodified, args=(event.src_path,)).start()
def on_moved(self, event):
Thread(
target=_consume_wait_unmodified, args=(event.dest_path,)
).start()
Thread(target=_consume_wait_unmodified, args=(event.dest_path,)).start()
class Command(BaseCommand):
@@ -130,26 +123,19 @@ class Command(BaseCommand):
"directory",
default=settings.CONSUMPTION_DIR,
nargs="?",
help="The consumption directory."
)
parser.add_argument(
"--oneshot",
action="store_true",
help="Run only once."
help="The consumption directory.",
)
parser.add_argument("--oneshot", action="store_true", help="Run only once.")
def handle(self, *args, **options):
directory = options["directory"]
recursive = settings.CONSUMER_RECURSIVE
if not directory:
raise CommandError(
"CONSUMPTION_DIR does not appear to be set."
)
raise CommandError("CONSUMPTION_DIR does not appear to be set.")
if not os.path.isdir(directory):
raise CommandError(
f"Consumption directory {directory} does not exist")
raise CommandError(f"Consumption directory {directory} does not exist")
if recursive:
for dirpath, _, filenames in os.walk(directory):
@@ -171,8 +157,7 @@ class Command(BaseCommand):
logger.debug("Consumer exiting.")
def handle_polling(self, directory, recursive):
logger.info(
f"Polling directory for changes: {directory}")
logger.info(f"Polling directory for changes: {directory}")
self.observer = PollingObserver(timeout=settings.CONSUMER_POLLING)
self.observer.schedule(Handler(), directory, recursive=recursive)
self.observer.start()
@@ -186,8 +171,7 @@ class Command(BaseCommand):
self.observer.join()
def handle_inotify(self, directory, recursive):
logger.info(
f"Using inotify to watch directory for changes: {directory}")
logger.info(f"Using inotify to watch directory for changes: {directory}")
inotify = INotify()
inotify_flags = flags.CLOSE_WRITE | flags.MOVED_TO

View File

@@ -8,7 +8,9 @@ class Command(BaseCommand):
help = """
Trains the classifier on your data and saves the resulting models to a
file. The document consumer will then automatically use this new model.
""".replace(" ", "")
""".replace(
" ", ""
)
def __init__(self, *args, **kwargs):
BaseCommand.__init__(self, *args, **kwargs)

View File

@@ -12,10 +12,19 @@ from django.core.management.base import BaseCommand, CommandError
from django.db import transaction
from filelock import FileLock
from documents.models import Document, Correspondent, Tag, DocumentType, \
SavedView, SavedViewFilterRule
from documents.settings import EXPORTER_FILE_NAME, EXPORTER_THUMBNAIL_NAME, \
EXPORTER_ARCHIVE_NAME
from documents.models import (
Document,
Correspondent,
Tag,
DocumentType,
SavedView,
SavedViewFilterRule,
)
from documents.settings import (
EXPORTER_FILE_NAME,
EXPORTER_THUMBNAIL_NAME,
EXPORTER_ARCHIVE_NAME,
)
from paperless.db import GnuPG
from paperless_mail.models import MailAccount, MailRule
from ...file_handling import generate_filename, delete_empty_directories
@@ -27,41 +36,46 @@ class Command(BaseCommand):
Decrypt and rename all files in our collection into a given target
directory. And include a manifest file containing document data for
easy import.
""".replace(" ", "")
""".replace(
" ", ""
)
def add_arguments(self, parser):
parser.add_argument("target")
parser.add_argument(
"-c", "--compare-checksums",
"-c",
"--compare-checksums",
default=False,
action="store_true",
help="Compare file checksums when determining whether to export "
"a file or not. If not specified, file size and time "
"modified is used instead."
"a file or not. If not specified, file size and time "
"modified is used instead.",
)
parser.add_argument(
"-f", "--use-filename-format",
"-f",
"--use-filename-format",
default=False,
action="store_true",
help="Use PAPERLESS_FILENAME_FORMAT for storing files in the "
"export directory, if configured."
"export directory, if configured.",
)
parser.add_argument(
"-d", "--delete",
"-d",
"--delete",
default=False,
action="store_true",
help="After exporting, delete files in the export directory that "
"do not belong to the current export, such as files from "
"deleted documents."
"do not belong to the current export, such as files from "
"deleted documents.",
)
parser.add_argument(
"--no-progress-bar",
default=False,
action="store_true",
help="If set, the progress bar will not be shown"
help="If set, the progress bar will not be shown",
)
def __init__(self, *args, **kwargs):
@@ -76,9 +90,9 @@ class Command(BaseCommand):
def handle(self, *args, **options):
self.target = options["target"]
self.compare_checksums = options['compare_checksums']
self.use_filename_format = options['use_filename_format']
self.delete = options['delete']
self.compare_checksums = options["compare_checksums"]
self.use_filename_format = options["use_filename_format"]
self.delete = options["delete"]
if not os.path.exists(self.target):
raise CommandError("That path doesn't exist")
@@ -87,7 +101,7 @@ class Command(BaseCommand):
raise CommandError("That path doesn't appear to be writable")
with FileLock(settings.MEDIA_LOCK):
self.dump(options['no_progress_bar'])
self.dump(options["no_progress_bar"])
def dump(self, progress_bar_disable=False):
# 1. Take a snapshot of what files exist in the current export folder
@@ -100,43 +114,48 @@ class Command(BaseCommand):
# documents
with transaction.atomic():
manifest = json.loads(
serializers.serialize("json", Correspondent.objects.all()))
serializers.serialize("json", Correspondent.objects.all())
)
manifest += json.loads(serializers.serialize(
"json", Tag.objects.all()))
manifest += json.loads(serializers.serialize("json", Tag.objects.all()))
manifest += json.loads(serializers.serialize(
"json", DocumentType.objects.all()))
manifest += json.loads(
serializers.serialize("json", DocumentType.objects.all())
)
documents = Document.objects.order_by("id")
document_map = {d.pk: d for d in documents}
document_manifest = json.loads(
serializers.serialize("json", documents))
document_manifest = json.loads(serializers.serialize("json", documents))
manifest += document_manifest
manifest += json.loads(serializers.serialize(
"json", MailAccount.objects.all()))
manifest += json.loads(
serializers.serialize("json", MailAccount.objects.all())
)
manifest += json.loads(serializers.serialize(
"json", MailRule.objects.all()))
manifest += json.loads(
serializers.serialize("json", MailRule.objects.all())
)
manifest += json.loads(serializers.serialize(
"json", SavedView.objects.all()))
manifest += json.loads(
serializers.serialize("json", SavedView.objects.all())
)
manifest += json.loads(serializers.serialize(
"json", SavedViewFilterRule.objects.all()))
manifest += json.loads(
serializers.serialize("json", SavedViewFilterRule.objects.all())
)
manifest += json.loads(serializers.serialize(
"json", User.objects.all()))
manifest += json.loads(serializers.serialize("json", User.objects.all()))
# 3. Export files from each document
for index, document_dict in tqdm.tqdm(
enumerate(document_manifest),
total=len(document_manifest),
disable=progress_bar_disable
disable=progress_bar_disable,
):
# 3.1. store files unencrypted
document_dict["fields"]["storage_type"] = Document.STORAGE_TYPE_UNENCRYPTED # NOQA: E501
document_dict["fields"][
"storage_type"
] = Document.STORAGE_TYPE_UNENCRYPTED # NOQA: E501
document = document_map[document_dict["pk"]]
@@ -145,11 +164,10 @@ class Command(BaseCommand):
while True:
if self.use_filename_format:
base_name = generate_filename(
document, counter=filename_counter,
append_gpg=False)
document, counter=filename_counter, append_gpg=False
)
else:
base_name = document.get_public_filename(
counter=filename_counter)
base_name = document.get_public_filename(counter=filename_counter)
if base_name not in self.exported_files:
self.exported_files.append(base_name)
@@ -193,22 +211,19 @@ class Command(BaseCommand):
f.write(GnuPG.decrypted(document.archive_path))
os.utime(archive_target, times=(t, t))
else:
self.check_and_copy(document.source_path,
document.checksum,
original_target)
self.check_and_copy(
document.source_path, document.checksum, original_target
)
self.check_and_copy(document.thumbnail_path,
None,
thumbnail_target)
self.check_and_copy(document.thumbnail_path, None, thumbnail_target)
if archive_target:
self.check_and_copy(document.archive_path,
document.archive_checksum,
archive_target)
self.check_and_copy(
document.archive_path, document.archive_checksum, archive_target
)
# 4. write manifest to target forlder
manifest_path = os.path.abspath(
os.path.join(self.target, "manifest.json"))
manifest_path = os.path.abspath(os.path.join(self.target, "manifest.json"))
with open(manifest_path, "w") as f:
json.dump(manifest, f, indent=2)
@@ -222,8 +237,9 @@ class Command(BaseCommand):
for f in self.files_in_export_dir:
os.remove(f)
delete_empty_directories(os.path.abspath(os.path.dirname(f)),
os.path.abspath(self.target))
delete_empty_directories(
os.path.abspath(os.path.dirname(f)), os.path.abspath(self.target)
)
def check_and_copy(self, source, source_checksum, target):
if os.path.abspath(target) in self.files_in_export_dir:

View File

@@ -12,8 +12,11 @@ from django.db.models.signals import post_save, m2m_changed
from filelock import FileLock
from documents.models import Document
from documents.settings import EXPORTER_FILE_NAME, EXPORTER_THUMBNAIL_NAME, \
EXPORTER_ARCHIVE_NAME
from documents.settings import (
EXPORTER_FILE_NAME,
EXPORTER_THUMBNAIL_NAME,
EXPORTER_ARCHIVE_NAME,
)
from ...file_handling import create_source_path_directory
from ...signals.handlers import update_filename_and_move_files
@@ -32,7 +35,9 @@ class Command(BaseCommand):
help = """
Using a manifest.json file, load the data from there, and import the
documents it refers to.
""".replace(" ", "")
""".replace(
" ", ""
)
def add_arguments(self, parser):
parser.add_argument("source")
@@ -40,7 +45,7 @@ class Command(BaseCommand):
"--no-progress-bar",
default=False,
action="store_true",
help="If set, the progress bar will not be shown"
help="If set, the progress bar will not be shown",
)
def __init__(self, *args, **kwargs):
@@ -67,26 +72,27 @@ class Command(BaseCommand):
self.manifest = json.load(f)
self._check_manifest()
with disable_signal(post_save,
receiver=update_filename_and_move_files,
sender=Document):
with disable_signal(m2m_changed,
receiver=update_filename_and_move_files,
sender=Document.tags.through):
with disable_signal(
post_save, receiver=update_filename_and_move_files, sender=Document
):
with disable_signal(
m2m_changed,
receiver=update_filename_and_move_files,
sender=Document.tags.through,
):
# Fill up the database with whatever is in the manifest
call_command("loaddata", manifest_path)
self._import_files_from_manifest(options['no_progress_bar'])
self._import_files_from_manifest(options["no_progress_bar"])
print("Updating search index...")
call_command('document_index', 'reindex')
call_command("document_index", "reindex")
@staticmethod
def _check_manifest_exists(path):
if not os.path.exists(path):
raise CommandError(
"That directory doesn't appear to contain a manifest.json "
"file."
"That directory doesn't appear to contain a manifest.json " "file."
)
def _check_manifest(self):
@@ -98,15 +104,15 @@ class Command(BaseCommand):
if EXPORTER_FILE_NAME not in record:
raise CommandError(
'The manifest file contains a record which does not '
'refer to an actual document file.'
"The manifest file contains a record which does not "
"refer to an actual document file."
)
doc_file = record[EXPORTER_FILE_NAME]
if not os.path.exists(os.path.join(self.source, doc_file)):
raise CommandError(
'The manifest file refers to "{}" which does not '
'appear to be in the source directory.'.format(doc_file)
"appear to be in the source directory.".format(doc_file)
)
if EXPORTER_ARCHIVE_NAME in record:
@@ -125,14 +131,11 @@ class Command(BaseCommand):
print("Copy files into paperless...")
manifest_documents = list(filter(
lambda r: r["model"] == "documents.document",
self.manifest))
manifest_documents = list(
filter(lambda r: r["model"] == "documents.document", self.manifest)
)
for record in tqdm.tqdm(
manifest_documents,
disable=progress_bar_disable
):
for record in tqdm.tqdm(manifest_documents, disable=progress_bar_disable):
document = Document.objects.get(pk=record["pk"])

View File

@@ -9,17 +9,17 @@ class Command(BaseCommand):
help = "Manages the document index."
def add_arguments(self, parser):
parser.add_argument("command", choices=['reindex', 'optimize'])
parser.add_argument("command", choices=["reindex", "optimize"])
parser.add_argument(
"--no-progress-bar",
default=False,
action="store_true",
help="If set, the progress bar will not be shown"
help="If set, the progress bar will not be shown",
)
def handle(self, *args, **options):
with transaction.atomic():
if options['command'] == 'reindex':
index_reindex(progress_bar_disable=options['no_progress_bar'])
elif options['command'] == 'optimize':
if options["command"] == "reindex":
index_reindex(progress_bar_disable=options["no_progress_bar"])
elif options["command"] == "optimize":
index_optimize()

View File

@@ -11,14 +11,16 @@ class Command(BaseCommand):
help = """
This will rename all documents to match the latest filename format.
""".replace(" ", "")
""".replace(
" ", ""
)
def add_arguments(self, parser):
parser.add_argument(
"--no-progress-bar",
default=False,
action="store_true",
help="If set, the progress bar will not be shown"
help="If set, the progress bar will not be shown",
)
def handle(self, *args, **options):
@@ -26,7 +28,6 @@ class Command(BaseCommand):
logging.getLogger().handlers[0].level = logging.ERROR
for document in tqdm.tqdm(
Document.objects.all(),
disable=options['no_progress_bar']
Document.objects.all(), disable=options["no_progress_bar"]
):
post_save.send(Document, instance=document)

View File

@@ -18,60 +18,46 @@ class Command(BaseCommand):
and document types to all documents, effectively allowing you to
back-tag all previously indexed documents with metadata created (or
modified) after their initial import.
""".replace(" ", "")
""".replace(
" ", ""
)
def add_arguments(self, parser):
parser.add_argument(
"-c", "--correspondent",
default=False,
action="store_true"
)
parser.add_argument(
"-T", "--tags",
default=False,
action="store_true"
)
parser.add_argument(
"-t", "--document_type",
default=False,
action="store_true"
)
parser.add_argument(
"-i", "--inbox-only",
default=False,
action="store_true"
)
parser.add_argument("-c", "--correspondent", default=False, action="store_true")
parser.add_argument("-T", "--tags", default=False, action="store_true")
parser.add_argument("-t", "--document_type", default=False, action="store_true")
parser.add_argument("-i", "--inbox-only", default=False, action="store_true")
parser.add_argument(
"--use-first",
default=False,
action="store_true",
help="By default this command won't try to assign a correspondent "
"if more than one matches the document. Use this flag if "
"you'd rather it just pick the first one it finds."
"if more than one matches the document. Use this flag if "
"you'd rather it just pick the first one it finds.",
)
parser.add_argument(
"-f", "--overwrite",
"-f",
"--overwrite",
default=False,
action="store_true",
help="If set, the document retagger will overwrite any previously"
"set correspondent, document and remove correspondents, types"
"and tags that do not match anymore due to changed rules."
"set correspondent, document and remove correspondents, types"
"and tags that do not match anymore due to changed rules.",
)
parser.add_argument(
"--no-progress-bar",
default=False,
action="store_true",
help="If set, the progress bar will not be shown"
help="If set, the progress bar will not be shown",
)
parser.add_argument(
"--suggest",
default=False,
action="store_true",
help="Return the suggestion, don't change anything."
help="Return the suggestion, don't change anything.",
)
parser.add_argument(
"--base-url",
help="The base URL to use to build the link to the documents."
"--base-url", help="The base URL to use to build the link to the documents."
)
def handle(self, *args, **options):
@@ -86,38 +72,39 @@ class Command(BaseCommand):
classifier = load_classifier()
for document in tqdm.tqdm(
documents,
disable=options['no_progress_bar']
):
for document in tqdm.tqdm(documents, disable=options["no_progress_bar"]):
if options['correspondent']:
if options["correspondent"]:
set_correspondent(
sender=None,
document=document,
classifier=classifier,
replace=options['overwrite'],
use_first=options['use_first'],
suggest=options['suggest'],
base_url=options['base_url'],
color=color)
replace=options["overwrite"],
use_first=options["use_first"],
suggest=options["suggest"],
base_url=options["base_url"],
color=color,
)
if options['document_type']:
set_document_type(sender=None,
document=document,
classifier=classifier,
replace=options['overwrite'],
use_first=options['use_first'],
suggest=options['suggest'],
base_url=options['base_url'],
color=color)
if options["document_type"]:
set_document_type(
sender=None,
document=document,
classifier=classifier,
replace=options["overwrite"],
use_first=options["use_first"],
suggest=options["suggest"],
base_url=options["base_url"],
color=color,
)
if options['tags']:
if options["tags"]:
set_tags(
sender=None,
document=document,
classifier=classifier,
replace=options['overwrite'],
suggest=options['suggest'],
base_url=options['base_url'],
color=color)
replace=options["overwrite"],
suggest=options["suggest"],
base_url=options["base_url"],
color=color,
)

View File

@@ -6,18 +6,20 @@ class Command(BaseCommand):
help = """
This command checks your document archive for issues.
""".replace(" ", "")
""".replace(
" ", ""
)
def add_arguments(self, parser):
parser.add_argument(
"--no-progress-bar",
default=False,
action="store_true",
help="If set, the progress bar will not be shown"
help="If set, the progress bar will not be shown",
)
def handle(self, *args, **options):
messages = check_sanity(progress=not options['no_progress_bar'])
messages = check_sanity(progress=not options["no_progress_bar"])
messages.log_messages()

View File

@@ -22,9 +22,7 @@ def _process_document(doc_in):
try:
thumb = parser.get_optimised_thumbnail(
document.source_path,
document.mime_type,
document.get_public_filename()
document.source_path, document.mime_type, document.get_public_filename()
)
shutil.move(thumb, document.thumbnail_path)
@@ -36,29 +34,32 @@ class Command(BaseCommand):
help = """
This will regenerate the thumbnails for all documents.
""".replace(" ", "")
""".replace(
" ", ""
)
def add_arguments(self, parser):
parser.add_argument(
"-d", "--document",
"-d",
"--document",
default=None,
type=int,
required=False,
help="Specify the ID of a document, and this command will only "
"run on this specific document."
"run on this specific document.",
)
parser.add_argument(
"--no-progress-bar",
default=False,
action="store_true",
help="If set, the progress bar will not be shown"
help="If set, the progress bar will not be shown",
)
def handle(self, *args, **options):
logging.getLogger().handlers[0].level = logging.ERROR
if options['document']:
documents = Document.objects.filter(pk=options['document'])
if options["document"]:
documents = Document.objects.filter(pk=options["document"])
else:
documents = Document.objects.all()
@@ -70,8 +71,10 @@ class Command(BaseCommand):
db.connections.close_all()
with multiprocessing.Pool() as pool:
list(tqdm.tqdm(
pool.imap_unordered(_process_document, ids),
total=len(ids),
disable=options['no_progress_bar']
))
list(
tqdm.tqdm(
pool.imap_unordered(_process_document, ids),
total=len(ids),
disable=options["no_progress_bar"],
)
)

View File

@@ -10,11 +10,11 @@ class Command(LoadDataCommand):
"""
def parse_name(self, fixture_name):
self.compression_formats['stdin'] = (lambda x, y: sys.stdin, None)
if fixture_name == '-':
return '-', 'json', 'stdin'
self.compression_formats["stdin"] = (lambda x, y: sys.stdin, None)
if fixture_name == "-":
return "-", "json", "stdin"
def find_fixtures(self, fixture_label):
if fixture_label == '-':
return [('-', None, '-')]
if fixture_label == "-":
return [("-", None, "-")]
return super(Command, self).find_fixtures(fixture_label)

View File

@@ -12,16 +12,18 @@ class Command(BaseCommand):
help = """
Creates a Django superuser based on env variables.
""".replace(" ", "")
""".replace(
" ", ""
)
def handle(self, *args, **options):
username = os.getenv('PAPERLESS_ADMIN_USER')
username = os.getenv("PAPERLESS_ADMIN_USER")
if not username:
return
mail = os.getenv('PAPERLESS_ADMIN_MAIL', 'root@localhost')
password = os.getenv('PAPERLESS_ADMIN_PASSWORD')
mail = os.getenv("PAPERLESS_ADMIN_MAIL", "root@localhost")
password = os.getenv("PAPERLESS_ADMIN_PASSWORD")
# Check if user exists already, leave as is if it does
if User.objects.filter(username=username).exists():
@@ -32,11 +34,10 @@ class Command(BaseCommand):
elif password:
# Create superuser based on env variables
User.objects.create_superuser(username, mail, password)
self.stdout.write(
f'Created superuser "{username}" with provided password.')
self.stdout.write(f'Created superuser "{username}" with provided password.')
else:
self.stdout.write(
f'Did not create superuser "{username}".')
self.stdout.write(f'Did not create superuser "{username}".')
self.stdout.write(
'Make sure you specified "PAPERLESS_ADMIN_PASSWORD" in your '
'"docker-compose.env" file.')
'"docker-compose.env" file.'
)