mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
Merge pull request #883 from paperless-ngx/feature-version-export-import
Fix: Include version in export for better error messages
This commit is contained in:
commit
b325233b2d
@ -287,6 +287,10 @@ When you use the provided docker compose script, put the export inside the
|
|||||||
``export`` folder in your paperless source directory. Specify ``../export``
|
``export`` folder in your paperless source directory. Specify ``../export``
|
||||||
as the ``source``.
|
as the ``source``.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Importing from a previous version of Paperless may work, but for best results
|
||||||
|
it is suggested to match the versions.
|
||||||
|
|
||||||
.. _utilities-retagger:
|
.. _utilities-retagger:
|
||||||
|
|
||||||
|
@ -152,4 +152,4 @@ class Command(BaseCommand):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print("Aborting...")
|
self.stdout.write(self.style.NOTICE(("Aborting...")))
|
||||||
|
@ -22,6 +22,7 @@ from documents.settings import EXPORTER_ARCHIVE_NAME
|
|||||||
from documents.settings import EXPORTER_FILE_NAME
|
from documents.settings import EXPORTER_FILE_NAME
|
||||||
from documents.settings import EXPORTER_THUMBNAIL_NAME
|
from documents.settings import EXPORTER_THUMBNAIL_NAME
|
||||||
from filelock import FileLock
|
from filelock import FileLock
|
||||||
|
from paperless import version
|
||||||
from paperless.db import GnuPG
|
from paperless.db import GnuPG
|
||||||
from paperless_mail.models import MailAccount
|
from paperless_mail.models import MailAccount
|
||||||
from paperless_mail.models import MailRule
|
from paperless_mail.models import MailRule
|
||||||
@ -232,12 +233,18 @@ class Command(BaseCommand):
|
|||||||
archive_target,
|
archive_target,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 4. write manifest to target forlder
|
# 4.1 write manifest to target folder
|
||||||
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:
|
with open(manifest_path, "w") as f:
|
||||||
json.dump(manifest, f, indent=2)
|
json.dump(manifest, f, indent=2)
|
||||||
|
|
||||||
|
# 4.2 write version information to target folder
|
||||||
|
version_path = os.path.abspath(os.path.join(self.target, "version.json"))
|
||||||
|
|
||||||
|
with open(version_path, "w") as f:
|
||||||
|
json.dump({"version": version.__full_version_str__}, f, indent=2)
|
||||||
|
|
||||||
if self.delete:
|
if self.delete:
|
||||||
# 5. Remove files which we did not explicitly export in this run
|
# 5. Remove files which we did not explicitly export in this run
|
||||||
|
|
||||||
|
@ -6,9 +6,11 @@ from contextlib import contextmanager
|
|||||||
|
|
||||||
import tqdm
|
import tqdm
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.core.exceptions import FieldDoesNotExist
|
||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.core.management.base import CommandError
|
from django.core.management.base import CommandError
|
||||||
|
from django.core.serializers.base import DeserializationError
|
||||||
from django.db.models.signals import m2m_changed
|
from django.db.models.signals import m2m_changed
|
||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
from documents.models import Document
|
from documents.models import Document
|
||||||
@ -16,6 +18,7 @@ from documents.settings import EXPORTER_ARCHIVE_NAME
|
|||||||
from documents.settings import EXPORTER_FILE_NAME
|
from documents.settings import EXPORTER_FILE_NAME
|
||||||
from documents.settings import EXPORTER_THUMBNAIL_NAME
|
from documents.settings import EXPORTER_THUMBNAIL_NAME
|
||||||
from filelock import FileLock
|
from filelock import FileLock
|
||||||
|
from paperless import version
|
||||||
|
|
||||||
from ...file_handling import create_source_path_directory
|
from ...file_handling import create_source_path_directory
|
||||||
from ...signals.handlers import update_filename_and_move_files
|
from ...signals.handlers import update_filename_and_move_files
|
||||||
@ -53,6 +56,7 @@ class Command(BaseCommand):
|
|||||||
BaseCommand.__init__(self, *args, **kwargs)
|
BaseCommand.__init__(self, *args, **kwargs)
|
||||||
self.source = None
|
self.source = None
|
||||||
self.manifest = None
|
self.manifest = None
|
||||||
|
self.version = None
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
|
||||||
@ -66,12 +70,30 @@ class Command(BaseCommand):
|
|||||||
if not os.access(self.source, os.R_OK):
|
if not os.access(self.source, os.R_OK):
|
||||||
raise CommandError("That path doesn't appear to be readable")
|
raise CommandError("That path doesn't appear to be readable")
|
||||||
|
|
||||||
manifest_path = os.path.join(self.source, "manifest.json")
|
manifest_path = os.path.normpath(os.path.join(self.source, "manifest.json"))
|
||||||
self._check_manifest_exists(manifest_path)
|
self._check_manifest_exists(manifest_path)
|
||||||
|
|
||||||
with open(manifest_path) as f:
|
with open(manifest_path) as f:
|
||||||
self.manifest = json.load(f)
|
self.manifest = json.load(f)
|
||||||
|
|
||||||
|
version_path = os.path.normpath(os.path.join(self.source, "version.json"))
|
||||||
|
if os.path.exists(version_path):
|
||||||
|
with open(version_path) as f:
|
||||||
|
self.version = json.load(f)["version"]
|
||||||
|
# Provide an initial warning if needed to the user
|
||||||
|
if self.version != version.__full_version_str__:
|
||||||
|
self.stdout.write(
|
||||||
|
self.style.WARNING(
|
||||||
|
"Version mismatch: "
|
||||||
|
f"Currently {version.__full_version_str__},"
|
||||||
|
f" importing {self.version}."
|
||||||
|
" Continuing, but import may fail.",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.stdout.write(self.style.NOTICE("No version.json file located"))
|
||||||
|
|
||||||
self._check_manifest()
|
self._check_manifest()
|
||||||
with disable_signal(
|
with disable_signal(
|
||||||
post_save,
|
post_save,
|
||||||
@ -84,12 +106,36 @@ class Command(BaseCommand):
|
|||||||
sender=Document.tags.through,
|
sender=Document.tags.through,
|
||||||
):
|
):
|
||||||
# Fill up the database with whatever is in the manifest
|
# Fill up the database with whatever is in the manifest
|
||||||
call_command("loaddata", manifest_path)
|
try:
|
||||||
|
call_command("loaddata", manifest_path)
|
||||||
|
except (FieldDoesNotExist, DeserializationError) as e:
|
||||||
|
self.stdout.write(self.style.ERROR("Database import failed"))
|
||||||
|
if (
|
||||||
|
self.version is not None
|
||||||
|
and self.version != version.__full_version_str__
|
||||||
|
):
|
||||||
|
self.stdout.write(
|
||||||
|
self.style.ERROR(
|
||||||
|
"Version mismatch: "
|
||||||
|
f"Currently {version.__full_version_str__},"
|
||||||
|
f" importing {self.version}",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
raise e
|
||||||
|
else:
|
||||||
|
self.stdout.write(
|
||||||
|
self.style.ERROR("No version information present"),
|
||||||
|
)
|
||||||
|
raise e
|
||||||
|
|
||||||
self._import_files_from_manifest(options["no_progress_bar"])
|
self._import_files_from_manifest(options["no_progress_bar"])
|
||||||
|
|
||||||
print("Updating search index...")
|
self.stdout.write("Updating search index...")
|
||||||
call_command("document_index", "reindex")
|
call_command(
|
||||||
|
"document_index",
|
||||||
|
"reindex",
|
||||||
|
no_progress_bar=options["no_progress_bar"],
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _check_manifest_exists(path):
|
def _check_manifest_exists(path):
|
||||||
@ -132,7 +178,7 @@ class Command(BaseCommand):
|
|||||||
os.makedirs(settings.THUMBNAIL_DIR, exist_ok=True)
|
os.makedirs(settings.THUMBNAIL_DIR, exist_ok=True)
|
||||||
os.makedirs(settings.ARCHIVE_DIR, exist_ok=True)
|
os.makedirs(settings.ARCHIVE_DIR, exist_ok=True)
|
||||||
|
|
||||||
print("Copy files into paperless...")
|
self.stdout.write("Copy files into paperless...")
|
||||||
|
|
||||||
manifest_documents = list(
|
manifest_documents = list(
|
||||||
filter(lambda r: r["model"] == "documents.document", self.manifest),
|
filter(lambda r: r["model"] == "documents.document", self.manifest),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user