split views for label and label with doc, restore sanity

This commit is contained in:
Tomáš Mládek 2020-04-01 21:00:11 +02:00
parent 24d3f4686a
commit b7b4f7f92c
5 changed files with 37 additions and 32 deletions

View file

@ -4,7 +4,6 @@ from django.core.exceptions import ValidationError
from django.core.files.storage import FileSystemStorage from django.core.files.storage import FileSystemStorage
from django.db import models from django.db import models
from django.db.models import Count from django.db.models import Count
from django.urls import reverse
from model_utils.models import SoftDeletableModel from model_utils.models import SoftDeletableModel
@ -67,8 +66,8 @@ class Document(SoftDeletableModel):
@property @property
def url(self): def url(self):
if self.is_local_pdf: if self.file:
return reverse("pile:label", args=[self.id]) + "?fallback=1" return f"/docs/{self.file.url}"
return self.external_url return self.external_url
@property @property

View file

@ -39,12 +39,12 @@
{% if document.is_local_pdf %} {% if document.is_local_pdf %}
<div class="doc-link"> <div class="doc-link">
<span class="doc-link-intro">Access file as:</span> <span class="doc-link-intro">Access file as:</span>
<a href="{{ document.url }}">Entry #{{ document.id }} of /-\ pile</a> <a href="{% url "pile:retrieve" document.id %}">Entry #{{ document.id }} of /-\ pile</a>
</div> </div>
<div class="doc-link"> <div class="doc-link">
<span class="doc-link-intro">Get original document at: </span> <span class="doc-link-intro">Get original document at: </span>
<a href="/docs/{{ document.file.url }}">{{ document.file.url }}</a> <a href="{{ document.url }}">{{ document.url }}</a>
</div> </div>
{% else %} {% else %}
<div class="doc-link"> <div class="doc-link">

View file

@ -21,7 +21,7 @@
{% for document in documents %} {% for document in documents %}
<div class="text doc-item"> <div class="text doc-item">
<a class="doc-item-link" href="{{ document.url }}">🔗</a> <a class="doc-item-link" href="{% url "pile:retrieve" document.id %}">🔗</a>
<a href="{% url "pile:document" document.id %}"> <a href="{% url "pile:document" document.id %}">
<div class="doc-item-text"> <div class="doc-item-text">
<h2>{{ document.title }}</h2> <h2>{{ document.title }}</h2>

View file

@ -7,6 +7,7 @@ urlpatterns = [
path('', views.IndexView.as_view(), name='index'), path('', views.IndexView.as_view(), name='index'),
path('tag/<name_or_id>', views.TagView.as_view(), name='tag'), path('tag/<name_or_id>', views.TagView.as_view(), name='tag'),
path('item/<int:document_id>', views.DocumentView.as_view(), name='document'), path('item/<int:document_id>', views.DocumentView.as_view(), name='document'),
path('label/<int:document_id>', views.DocumentWithLabel.as_view(), name='label'), path('label/<int:document_id>', views.LabelView.as_view(), name='label'),
path('retrieve/<int:document_id>', views.DocumentWithLabelView.as_view(), name='retrieve'),
path('feed', views.RecentlyUploadedFeed()) path('feed', views.RecentlyUploadedFeed())
] ]

View file

@ -8,7 +8,7 @@ import weasyprint
from PyPDF2 import PdfFileWriter, PdfFileReader from PyPDF2 import PdfFileWriter, PdfFileReader
from django.contrib.syndication.views import Feed from django.contrib.syndication.views import Feed
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.http import Http404, FileResponse from django.http import Http404, FileResponse, HttpRequest
from django.shortcuts import redirect from django.shortcuts import redirect
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.utils.text import slugify from django.utils.text import slugify
@ -102,23 +102,39 @@ class DocumentView(BasePileView):
} }
class DocumentWithLabel(BasePileViewMixin): class LabelView(BasePileViewMixin):
def get(self, request, document_id: int): def get(self, request: HttpRequest, document_id: int):
try: try:
document = self.documents.get(pk=document_id) document = self.documents.get(pk=document_id)
except ObjectDoesNotExist: except ObjectDoesNotExist:
raise Http404 raise Http404
label_stream = self.get_label(request, document)
return FileResponse(label_stream,
filename=f"pile_{document.id}__label__{slugify(document.title)}.pdf",
content_type="application/pdf")
@staticmethod
def get_label(request, document):
label_html = render_to_string("label.html", {'document': document}) label_html = render_to_string("label.html", {'document': document})
label_stream = io.BytesIO() stream = io.BytesIO()
weasyprint.HTML(base_url=request.build_absolute_uri(), string=label_html).write_pdf(label_stream) weasyprint.HTML(base_url=request.build_absolute_uri(), string=label_html).write_pdf(stream)
label_stream.seek(0) stream.seek(0)
return stream
class DocumentWithLabelView(BasePileViewMixin):
def get(self, request: HttpRequest, document_id: int):
try:
document = self.documents.get(pk=document_id)
except ObjectDoesNotExist:
raise Http404
final_stream = None
concat_succeeded = False
if document.is_local_pdf: if document.is_local_pdf:
try: try:
label_stream = LabelView.get_label(request, document)
with open(document.file.path, 'rb') as document_fp: with open(document.file.path, 'rb') as document_fp:
writer = PdfFileWriter() writer = PdfFileWriter()
for reader in map(PdfFileReader, (label_stream, document_fp)): for reader in map(PdfFileReader, (label_stream, document_fp)):
@ -127,26 +143,15 @@ class DocumentWithLabel(BasePileViewMixin):
writer.addMetadata({u'/Title': f"/-\\ pile #{document.id}: {document.title}"}) writer.addMetadata({u'/Title': f"/-\\ pile #{document.id}: {document.title}"})
final_stream = io.BytesIO() final_stream = io.BytesIO()
writer.write(final_stream) writer.write(final_stream)
final_stream.seek(0)
concat_succeeded = True final_stream.seek(0)
return FileResponse(final_stream,
filename=f"pile_{document.id}__label__{slugify(document.title)}.pdf",
content_type="application/pdf")
except Exception as exc: except Exception as exc:
logging.exception(exc) logging.exception(exc)
if not concat_succeeded: return redirect(document.url)
if self.request.GET.get("fallback"):
if document.is_local_pdf:
return FileResponse(document.file,
filename=f"pile_{document.id}__{slugify(document.title)}.pdf",
content_type="application/pdf")
else:
return redirect(document.external_url)
else:
label_stream.seek(0)
final_stream = label_stream
return FileResponse(final_stream,
filename=f"pile_{document.id}__{slugify(document.title)}.pdf",
content_type="application/pdf")
class RecentlyUploadedFeed(Feed): class RecentlyUploadedFeed(Feed):