paperless-ngx/src/documents/views.py

197 lines
6.4 KiB
Python
Raw Normal View History

2020-10-21 12:53:14 +02:00
from django.db.models import Count, Max
2020-10-27 17:35:52 +01:00
from django.http import HttpResponse, HttpResponseBadRequest
from django.views.decorators.cache import cache_control
from django.views.generic import TemplateView
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.views import APIView
from paperless.db import GnuPG
from paperless.views import StandardPagination
from rest_framework.filters import OrderingFilter, SearchFilter
2016-03-01 18:57:12 +00:00
from rest_framework.mixins import (
DestroyModelMixin,
ListModelMixin,
RetrieveModelMixin,
UpdateModelMixin
)
2016-03-01 18:57:12 +00:00
from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import (
GenericViewSet,
ModelViewSet,
ReadOnlyModelViewSet
)
2018-09-26 10:51:42 +02:00
from .filters import (
CorrespondentFilterSet,
DocumentFilterSet,
TagFilterSet,
DocumentTypeFilterSet
)
import documents.index as index
2020-10-27 17:35:52 +01:00
from .forms import UploadForm
2018-09-05 15:25:14 +02:00
from .models import Correspondent, Document, Log, Tag, DocumentType
2016-03-01 18:57:12 +00:00
from .serialisers import (
CorrespondentSerializer,
DocumentSerializer,
LogSerializer,
2018-09-05 15:25:14 +02:00
TagSerializer,
2018-09-25 16:09:33 +02:00
DocumentTypeSerializer
)
2016-01-01 16:13:59 +00:00
2016-03-03 18:09:10 +00:00
class IndexView(TemplateView):
template_name = "index.html"
2016-02-16 09:28:34 +00:00
class CorrespondentViewSet(ModelViewSet):
model = Correspondent
2020-10-21 12:53:14 +02:00
queryset = Correspondent.objects.annotate(document_count=Count('documents'), last_correspondence=Max('documents__created'))
serializer_class = CorrespondentSerializer
2016-02-21 00:55:38 +00:00
pagination_class = StandardPagination
2016-03-01 18:57:12 +00:00
permission_classes = (IsAuthenticated,)
filter_backends = (DjangoFilterBackend, OrderingFilter)
filter_class = CorrespondentFilterSet
2020-10-21 12:53:14 +02:00
ordering_fields = ("name", "document_count", "last_correspondence")
2016-02-16 09:28:34 +00:00
class TagViewSet(ModelViewSet):
model = Tag
2020-10-21 12:53:14 +02:00
queryset = Tag.objects.annotate(document_count=Count('documents'))
2016-02-16 09:28:34 +00:00
serializer_class = TagSerializer
2016-02-21 00:55:38 +00:00
pagination_class = StandardPagination
2016-03-01 18:57:12 +00:00
permission_classes = (IsAuthenticated,)
filter_backends = (DjangoFilterBackend, OrderingFilter)
filter_class = TagFilterSet
2020-10-21 12:53:14 +02:00
ordering_fields = ("name", "document_count")
2016-02-16 09:28:34 +00:00
2018-09-05 15:25:14 +02:00
class DocumentTypeViewSet(ModelViewSet):
model = DocumentType
2020-10-21 12:53:14 +02:00
queryset = DocumentType.objects.annotate(document_count=Count('documents'))
2018-09-05 15:25:14 +02:00
serializer_class = DocumentTypeSerializer
pagination_class = StandardPagination
permission_classes = (IsAuthenticated,)
filter_backends = (DjangoFilterBackend, OrderingFilter)
filter_class = DocumentTypeFilterSet
2020-10-21 12:53:14 +02:00
ordering_fields = ("name", "document_count")
2018-09-05 15:25:14 +02:00
2016-03-01 18:57:12 +00:00
class DocumentViewSet(RetrieveModelMixin,
UpdateModelMixin,
DestroyModelMixin,
ListModelMixin,
GenericViewSet):
2016-02-16 09:28:34 +00:00
model = Document
2016-02-21 00:55:38 +00:00
queryset = Document.objects.all()
2016-02-16 09:28:34 +00:00
serializer_class = DocumentSerializer
2016-02-21 00:55:38 +00:00
pagination_class = StandardPagination
2016-03-01 18:57:12 +00:00
permission_classes = (IsAuthenticated,)
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
filter_class = DocumentFilterSet
2016-03-09 01:05:46 +00:00
search_fields = ("title", "correspondent__name", "content")
2016-03-13 16:45:12 +00:00
ordering_fields = (
"id", "title", "correspondent__name", "created", "modified", "added", "archive_serial_number")
def file_response(self, pk, disposition):
#TODO: this should not be necessary here.
content_types = {
Document.TYPE_PDF: "application/pdf",
Document.TYPE_PNG: "image/png",
Document.TYPE_JPG: "image/jpeg",
Document.TYPE_GIF: "image/gif",
Document.TYPE_TIF: "image/tiff",
Document.TYPE_CSV: "text/csv",
Document.TYPE_MD: "text/markdown",
Document.TYPE_TXT: "text/plain"
}
doc = Document.objects.get(id=pk)
if doc.storage_type == Document.STORAGE_TYPE_UNENCRYPTED:
file_handle = doc.source_file
else:
file_handle = GnuPG.decrypted(doc.source_file)
response = HttpResponse(file_handle, content_type=content_types[doc.file_type])
response["Content-Disposition"] = '{}; filename="{}"'.format(
disposition, doc.file_name)
return response
@action(methods=['post'], detail=False)
def post_document(self, request, pk=None):
2020-10-27 17:35:52 +01:00
#TODO: is this a good implementation?
form = UploadForm(data=request.POST, files=request.FILES)
if form.is_valid():
form.save()
return Response("OK")
else:
return HttpResponseBadRequest(str(form.errors))
@action(methods=['get'], detail=True)
def preview(self, request, pk=None):
response = self.file_response(pk, "inline")
return response
@action(methods=['get'], detail=True)
@cache_control(public=False, max_age=315360000)
def thumb(self, request, pk=None):
return HttpResponse(Document.objects.get(id=pk).thumbnail_file, content_type='image/png')
@action(methods=['get'], detail=True)
def download(self, request, pk=None):
return self.file_response(pk, "attachment")
2016-03-01 18:57:12 +00:00
class LogViewSet(ReadOnlyModelViewSet):
model = Log
queryset = Log.objects.all().by_group()
serializer_class = LogSerializer
pagination_class = StandardPagination
permission_classes = (IsAuthenticated,)
filter_backends = (DjangoFilterBackend, OrderingFilter)
ordering_fields = ("time",)
class SearchView(APIView):
2020-10-27 17:07:13 +01:00
permission_classes = (IsAuthenticated,)
ix = index.open_index()
2020-10-27 17:07:13 +01:00
def get(self, request, format=None):
if 'query' in request.query_params:
query = request.query_params['query']
query_results = index.query_index(self.ix, query)
for r in query_results:
r['document'] = DocumentSerializer(Document.objects.get(id=r['id'])).data
return Response(query_results)
else:
return Response([])
2020-10-27 17:07:13 +01:00
class SearchAutoCompleteView(APIView):
permission_classes = (IsAuthenticated,)
ix = index.open_index()
def get(self, request, format=None):
if 'term' in request.query_params:
term = request.query_params['term']
else:
term = None
if 'limit' in request.query_params:
limit = int(request.query_params['limit'])
else:
limit = 10
if term is not None:
return Response(index.autocomplete(self.ix, term, limit))
else:
return Response([])