mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-03-09 10:41:24 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eaf11ea134 | ||
|
|
a59f8cd1b1 | ||
|
|
e9affbc1cf | ||
|
|
aa8789ae31 | ||
|
|
5c310c51d4 | ||
|
|
cf3fa50b55 | ||
|
|
7f933d373f | ||
|
|
ece94379d8 |
@@ -15,7 +15,7 @@ services:
|
||||
POSTGRES_PASSWORD: paperless
|
||||
|
||||
webserver:
|
||||
image: jonaswinkler/paperless-ng:0.9.7
|
||||
image: jonaswinkler/paperless-ng:0.9.8
|
||||
restart: always
|
||||
depends_on:
|
||||
- db
|
||||
|
||||
@@ -5,7 +5,7 @@ services:
|
||||
restart: always
|
||||
|
||||
webserver:
|
||||
image: jonaswinkler/paperless-ng:0.9.7
|
||||
image: jonaswinkler/paperless-ng:0.9.8
|
||||
restart: always
|
||||
depends_on:
|
||||
- broker
|
||||
|
||||
@@ -6,6 +6,15 @@ Changelog
|
||||
*********
|
||||
|
||||
|
||||
paperless-ng 0.9.8
|
||||
##################
|
||||
|
||||
This release addresses two severe issues with the previous release.
|
||||
|
||||
* The delete buttons for document types, correspondents and tags were not working.
|
||||
* The document section in the admin was causing internal server errors (500).
|
||||
|
||||
|
||||
paperless-ng 0.9.7
|
||||
##################
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ export abstract class GenericListComponent<T extends ObjectWithId> implements On
|
||||
activeModal.componentInstance.message = "Associated documents will not be deleted."
|
||||
activeModal.componentInstance.btnClass = "btn-danger"
|
||||
activeModal.componentInstance.btnCaption = "Delete"
|
||||
activeModal.componentInstance.confirmPressed.subscribe(() => {
|
||||
activeModal.componentInstance.confirmClicked.subscribe(() => {
|
||||
this.service.delete(object).subscribe(_ => {
|
||||
activeModal.close()
|
||||
this.reloadData()
|
||||
|
||||
@@ -2,5 +2,5 @@ export const environment = {
|
||||
production: true,
|
||||
apiBaseUrl: "/api/",
|
||||
appTitle: "Paperless-ng",
|
||||
version: "0.9.7"
|
||||
version: "0.9.8"
|
||||
};
|
||||
|
||||
@@ -69,7 +69,7 @@ class DocumentAdmin(admin.ModelAdmin):
|
||||
|
||||
filter_horizontal = ("tags",)
|
||||
|
||||
ordering = ["-created", "correspondent"]
|
||||
ordering = ["-created"]
|
||||
|
||||
date_hierarchy = "created"
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import os
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from termcolor import colored as coloured
|
||||
|
||||
from documents.models import Document
|
||||
from paperless.db import GnuPG
|
||||
@@ -26,16 +25,14 @@ class Command(BaseCommand):
|
||||
def handle(self, *args, **options):
|
||||
|
||||
try:
|
||||
print(coloured(
|
||||
print(
|
||||
"\n\nWARNING: This script is going to work directly on your "
|
||||
"document originals, so\nWARNING: you probably shouldn't run "
|
||||
"this unless you've got a recent backup\nWARNING: handy. It "
|
||||
"*should* work without a hitch, but be safe and backup your\n"
|
||||
"WARNING: stuff first.\n\nHit Ctrl+C to exit now, or Enter to "
|
||||
"continue.\n\n",
|
||||
"yellow",
|
||||
attrs=("bold",)
|
||||
))
|
||||
"continue.\n\n"
|
||||
)
|
||||
__ = input()
|
||||
except KeyboardInterrupt:
|
||||
return
|
||||
@@ -57,8 +54,8 @@ class Command(BaseCommand):
|
||||
|
||||
for document in encrypted_files:
|
||||
|
||||
print(coloured("Decrypting {}".format(
|
||||
document).encode('utf-8'), "green"))
|
||||
print("Decrypting {}".format(
|
||||
document).encode('utf-8'))
|
||||
|
||||
old_paths = [document.source_path, document.thumbnail_path]
|
||||
|
||||
|
||||
@@ -6,13 +6,17 @@ import magic
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
from paperless.db import GnuPG
|
||||
|
||||
STORAGE_TYPE_UNENCRYPTED = "unencrypted"
|
||||
STORAGE_TYPE_GPG = "gpg"
|
||||
|
||||
def source_path(self):
|
||||
if self.filename:
|
||||
fname = str(self.filename)
|
||||
else:
|
||||
fname = "{:07}.{}".format(self.pk, self.file_type)
|
||||
if self.storage_type == self.STORAGE_TYPE_GPG:
|
||||
if self.storage_type == STORAGE_TYPE_GPG:
|
||||
fname += ".gpg"
|
||||
|
||||
return os.path.join(
|
||||
@@ -26,9 +30,18 @@ def add_mime_types(apps, schema_editor):
|
||||
documents = Document.objects.all()
|
||||
|
||||
for d in documents:
|
||||
d.mime_type = magic.from_file(source_path(d), mime=True)
|
||||
f = open(source_path(d), "rb")
|
||||
if d.storage_type == STORAGE_TYPE_GPG:
|
||||
|
||||
data = GnuPG.decrypted(f)
|
||||
else:
|
||||
data = f.read(1024)
|
||||
|
||||
d.mime_type = magic.from_buffer(data, mime=True)
|
||||
d.save()
|
||||
|
||||
f.close()
|
||||
|
||||
|
||||
def add_file_extensions(apps, schema_editor):
|
||||
Document = apps.get_model("documents", "Document")
|
||||
|
||||
29
src/documents/migrations/1009_auto_20201216_2005.py
Normal file
29
src/documents/migrations/1009_auto_20201216_2005.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# Generated by Django 3.1.4 on 2020-12-16 20:05
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('documents', '1008_auto_20201216_1736'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='correspondent',
|
||||
options={'ordering': ('name',)},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='documenttype',
|
||||
options={'ordering': ('name',)},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='savedview',
|
||||
options={'ordering': ('name',)},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='tag',
|
||||
options={'ordering': ('name',)},
|
||||
),
|
||||
]
|
||||
@@ -11,7 +11,6 @@ import dateutil.parser
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import models
|
||||
from django.db.models.functions import Lower
|
||||
from django.utils import timezone
|
||||
|
||||
from documents.file_handling import archive_name_from_filename
|
||||
@@ -61,7 +60,7 @@ class MatchingModel(models.Model):
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
ordering = (Lower("name"),)
|
||||
ordering = ("name",)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
@@ -79,6 +78,9 @@ class Correspondent(MatchingModel):
|
||||
# better safe than sorry.
|
||||
SAFE_REGEX = re.compile(r"^[\w\- ,.']+$")
|
||||
|
||||
class Meta:
|
||||
ordering = ("name",)
|
||||
|
||||
|
||||
class Tag(MatchingModel):
|
||||
|
||||
@@ -307,7 +309,7 @@ class SavedView(models.Model):
|
||||
|
||||
class Meta:
|
||||
|
||||
ordering = (Lower("name"),)
|
||||
ordering = ("name",)
|
||||
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
name = models.CharField(max_length=128)
|
||||
|
||||
@@ -169,7 +169,12 @@ class DocumentViewSet(RetrieveModelMixin,
|
||||
parser_class = get_parser_class_for_mime_type(mime_type)
|
||||
if parser_class:
|
||||
parser = parser_class(logging_group=None)
|
||||
return parser.extract_metadata(file, mime_type)
|
||||
|
||||
try:
|
||||
return parser.extract_metadata(file, mime_type)
|
||||
except Exception as e:
|
||||
# TODO: cover GPG errors, remove later.
|
||||
return []
|
||||
else:
|
||||
return []
|
||||
|
||||
@@ -215,7 +220,12 @@ class DocumentViewSet(RetrieveModelMixin,
|
||||
@cache_control(public=False, max_age=315360000)
|
||||
def thumb(self, request, pk=None):
|
||||
try:
|
||||
return HttpResponse(Document.objects.get(id=pk).thumbnail_file,
|
||||
doc = Document.objects.get(id=pk)
|
||||
if doc.storage_type == Document.STORAGE_TYPE_GPG:
|
||||
handle = GnuPG.decrypted(doc.thumbnail_file)
|
||||
else:
|
||||
handle = doc.thumbnail_file
|
||||
return HttpResponse(handle,
|
||||
content_type='image/png')
|
||||
except (FileNotFoundError, Document.DoesNotExist):
|
||||
raise Http404()
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = (0, 9, 7)
|
||||
__version__ = (0, 9, 8)
|
||||
|
||||
Reference in New Issue
Block a user