mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	The first stages of getting thumbnails back
This commit is contained in:
		
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -57,7 +57,9 @@ docs/_build/ | ||||
| target/ | ||||
|  | ||||
| # Stored PDFs | ||||
| media/* | ||||
| media/documents/*.gpg | ||||
| media/documents/thumbnails/*.gpg | ||||
| media/documents/originals/*.gpg | ||||
|  | ||||
| # Sqlite database | ||||
| db.sqlite3 | ||||
| @@ -74,4 +76,3 @@ docker-compose.env | ||||
| # Used for development | ||||
| scripts/import-for-development | ||||
| environment | ||||
|  | ||||
|   | ||||
							
								
								
									
										0
									
								
								media/documents/originals/.keep
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								media/documents/originals/.keep
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								media/documents/thumbnails/.keep
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								media/documents/thumbnails/.keep
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										101
									
								
								src/documents/migrations/0012_auto_20160305_0040.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								src/documents/migrations/0012_auto_20160305_0040.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| # -*- coding: utf-8 -*- | ||||
| # Generated by Django 1.9.2 on 2016-03-05 00:40 | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| import gnupg | ||||
| import os | ||||
| import re | ||||
| import shutil | ||||
| import subprocess | ||||
| import tempfile | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.db import migrations | ||||
|  | ||||
|  | ||||
| class GnuPG(object): | ||||
|     """ | ||||
|     A handy singleton to use when handling encrypted files. | ||||
|     """ | ||||
|  | ||||
|     gpg = gnupg.GPG(gnupghome=settings.GNUPG_HOME) | ||||
|  | ||||
|     @classmethod | ||||
|     def decrypted(cls, file_handle): | ||||
|         return cls.gpg.decrypt_file( | ||||
|             file_handle, passphrase=settings.PASSPHRASE).data | ||||
|  | ||||
|     @classmethod | ||||
|     def encrypted(cls, file_handle): | ||||
|         return cls.gpg.encrypt_file( | ||||
|             file_handle, | ||||
|             recipients=None, | ||||
|             passphrase=settings.PASSPHRASE, | ||||
|             symmetric=True | ||||
|         ).data | ||||
|  | ||||
|  | ||||
| def move_documents_and_create_thumbnails(apps, schema_editor): | ||||
|  | ||||
|     documents = os.listdir(os.path.join(settings.MEDIA_ROOT, "documents")) | ||||
|  | ||||
|     if not documents: | ||||
|         return | ||||
|  | ||||
|     print("\n") | ||||
|  | ||||
|     for f in sorted(documents): | ||||
|  | ||||
|         if not f.endswith("gpg"): | ||||
|             continue | ||||
|  | ||||
|         print("    * Generating a thumbnail for {}".format(f)) | ||||
|  | ||||
|         thumb_temp = tempfile.mkdtemp( | ||||
|             prefix="paperless", dir=settings.SCRATCH_DIR) | ||||
|         orig_temp = tempfile.mkdtemp( | ||||
|             prefix="paperless", dir=settings.SCRATCH_DIR) | ||||
|  | ||||
|         orig_source = os.path.join(settings.MEDIA_ROOT, "documents", f) | ||||
|         orig_target = os.path.join(orig_temp, f.replace(".gpg", "")) | ||||
|  | ||||
|         with open(orig_source, "rb") as encrypted: | ||||
|             with open(orig_target, "wb") as unencrypted: | ||||
|                 unencrypted.write(GnuPG.decrypted(encrypted)) | ||||
|  | ||||
|         subprocess.Popen(( | ||||
|             settings.CONVERT_BINARY, | ||||
|             "-scale", "500x500", | ||||
|             orig_target, | ||||
|             os.path.join(thumb_temp, "convert-%04d.jpg") | ||||
|         )).wait() | ||||
|  | ||||
|         thumb_source = os.path.join(thumb_temp, "convert-0000.jpg") | ||||
|         thumb_target = os.path.join( | ||||
|             settings.MEDIA_ROOT, | ||||
|             "documents", | ||||
|             "thumbnails", | ||||
|             re.sub(r"(\d+)\.\w+(\.gpg)", "\\1.jpg\\2", f) | ||||
|         ) | ||||
|         with open(thumb_source, "rb") as unencrypted: | ||||
|             with open(thumb_target, "wb") as encrypted: | ||||
|                 encrypted.write(GnuPG.encrypted(unencrypted)) | ||||
|  | ||||
|         shutil.rmtree(thumb_temp) | ||||
|         shutil.rmtree(orig_temp) | ||||
|  | ||||
|         shutil.move( | ||||
|             os.path.join(settings.MEDIA_ROOT, "documents", f), | ||||
|             os.path.join(settings.MEDIA_ROOT, "documents", "originals", f), | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class Migration(migrations.Migration): | ||||
|  | ||||
|     dependencies = [ | ||||
|         ('documents', '0011_auto_20160303_1929'), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
|         migrations.RunPython(move_documents_and_create_thumbnails), | ||||
|     ] | ||||
| @@ -171,6 +171,7 @@ class Document(models.Model): | ||||
|         return os.path.join( | ||||
|             settings.MEDIA_ROOT, | ||||
|             "documents", | ||||
|             "originals", | ||||
|             "{:07}.{}.gpg".format(self.pk, self.file_type) | ||||
|         ) | ||||
|  | ||||
| @@ -184,7 +185,24 @@ class Document(models.Model): | ||||
|  | ||||
|     @property | ||||
|     def download_url(self): | ||||
|         return reverse("fetch", kwargs={"pk": self.pk}) | ||||
|         return reverse("fetch", kwargs={"kind": "doc", "pk": self.pk}) | ||||
|  | ||||
|     @property | ||||
|     def thumbnail_path(self): | ||||
|         return os.path.join( | ||||
|             settings.MEDIA_ROOT, | ||||
|             "documents", | ||||
|             "thumbnails", | ||||
|             "{:07}.jpg.gpg".format(self.pk) | ||||
|         ) | ||||
|  | ||||
|     @property | ||||
|     def thumbnail_file(self): | ||||
|         return open(self.thumbnail_path, "rb") | ||||
|  | ||||
|     @property | ||||
|     def thumbnail_url(self): | ||||
|         return reverse("fetch", kwargs={"kind": "thumb", "pk": self.pk}) | ||||
|  | ||||
|  | ||||
| class Log(models.Model): | ||||
|   | ||||
| @@ -35,7 +35,7 @@ class FetchView(LoginRequiredMixin, DetailView): | ||||
|  | ||||
|     def render_to_response(self, context, **response_kwargs): | ||||
|         """ | ||||
|         Override the default to return the unencrypted PDF as raw data. | ||||
|         Override the default to return the unencrypted image/PDF as raw data. | ||||
|         """ | ||||
|  | ||||
|         content_types = { | ||||
| @@ -46,6 +46,12 @@ class FetchView(LoginRequiredMixin, DetailView): | ||||
|             Document.TYPE_TIF: "image/tiff", | ||||
|         } | ||||
|  | ||||
|         if self.kwargs["kind"] == "thumb": | ||||
|             return HttpResponse( | ||||
|                 GnuPG.decrypted(self.object.thumb_file), | ||||
|                 content_type=content_types[Document.TYPE_JPG] | ||||
|             ) | ||||
|  | ||||
|         response = HttpResponse( | ||||
|             GnuPG.decrypted(self.object.source_file), | ||||
|             content_type=content_types[self.object.file_type] | ||||
|   | ||||
| @@ -44,7 +44,11 @@ urlpatterns = [ | ||||
|     # url(r"^$", IndexView.as_view(), name="index"), | ||||
|  | ||||
|     # File downloads | ||||
|     url(r"^fetch/(?P<pk>\d+)$", FetchView.as_view(), name="fetch"), | ||||
|     url( | ||||
|         r"^fetch/(?P<kind>doc|thumb)/(?P<pk>\d+)$", | ||||
|         FetchView.as_view(), | ||||
|         name="fetch" | ||||
|     ), | ||||
|  | ||||
|     # The Django admin | ||||
|     url(r"admin/", admin.site.urls), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Daniel Quinn
					Daniel Quinn