217 lines
7.1 KiB
Python
217 lines
7.1 KiB
Python
from django.shortcuts import render, redirect, resolve_url
|
|
from django.views.generic.detail import DetailView, SingleObjectMixin, View
|
|
from django.views.generic.list import ListView
|
|
from django.views.generic.edit import CreateView, FormView, UpdateView
|
|
from django.http import FileResponse, HttpResponse
|
|
from django.db import IntegrityError
|
|
|
|
import json
|
|
|
|
from interface.views import EnsembleMixin, ProjectMixin
|
|
from interface.models import Project
|
|
from .models import Work, Document, Part, Playlist, INSTRUMENTS
|
|
from . import forms
|
|
from .pdf_utils import extract_pages, extract_and_concat
|
|
|
|
class PlaylistView(ProjectMixin, ListView):
|
|
template_name = "library/playlist_view.html"
|
|
model = Playlist
|
|
|
|
def post(self, request, **kwargs):
|
|
|
|
project = self.get_project()
|
|
|
|
project_works = project.works.all()
|
|
|
|
instruments = request.POST.getlist('instruments')
|
|
works = request.POST.getlist('works')
|
|
|
|
self.request.session['part'] = request.POST.get('part', '')
|
|
self.request.session['instrument'] = request.POST.get('instrument')
|
|
|
|
valid_pks = [ x.pk for x in project_works ]
|
|
|
|
sections = []
|
|
|
|
for i, pk in enumerate(works):
|
|
|
|
if int(pk) not in valid_pks:
|
|
raise Exception(f"Not a valid work pk: {pk}")
|
|
|
|
tag = instruments[i]
|
|
if tag == '-':
|
|
continue
|
|
|
|
part = Part.objects.filter(tag=tag, doc__work=pk).select_related('doc').get()
|
|
sections.append((part.doc.upload.path, part.doc.work.name, part.start, part.end))
|
|
|
|
result = extract_and_concat(sections)
|
|
|
|
download_name = f'{project.name}.pdf'
|
|
|
|
response = FileResponse(result, content_type="application/pdf")
|
|
response['Content-Disposition'] = f'inline; filename="{download_name}"'
|
|
return response
|
|
|
|
|
|
def get_queryset(self):
|
|
return super(PlaylistView, self).get_queryset().select_related('project', 'work')
|
|
|
|
def get_context_data(self, **kwargs):
|
|
data = super(PlaylistView, self).get_context_data(**kwargs)
|
|
data['instruments'] = INSTRUMENTS
|
|
data['instrument'] = self.request.session.get('instrument', 'Score')
|
|
data['part'] = self.request.session.get('part', '0')
|
|
return data
|
|
|
|
class PlaylistManageView(ProjectMixin, ListView):
|
|
template_name = "library/playlist_manage.html"
|
|
model = Playlist
|
|
|
|
def post(self, request, **kwargs):
|
|
self.request = request
|
|
self.kwargs = kwargs
|
|
|
|
data = json.loads(request.body)
|
|
|
|
q = self.get_queryset()
|
|
for pk, order in data.items():
|
|
i = q.filter(pk=pk).update(order=order)
|
|
|
|
return HttpResponse(status=204)
|
|
|
|
def get_queryset(self):
|
|
return super(PlaylistManageView, self).get_queryset().select_related('project', 'work')
|
|
|
|
class PlaylistAddView(ProjectMixin, UpdateView):
|
|
form_class = forms.PlaylistAddForm
|
|
template_name = "interface/default_form.html"
|
|
|
|
def get_success_url(self):
|
|
return resolve_url('playlist_manage', project=self.kwargs['project'])
|
|
|
|
def get_object(self):
|
|
return self.get_project()
|
|
|
|
class WorkListView(EnsembleMixin, ListView):
|
|
|
|
def get_queryset(self):
|
|
return Work.objects.filter(ensemble=self.request.ensemble_id).order_by('name')
|
|
|
|
class WorkAddView(EnsembleMixin, FormView):
|
|
template_name = "interface/default_form.html"
|
|
form_class = forms.WorkCreateForm
|
|
|
|
def form_valid(self, form):
|
|
obj = form.save(commit=False)
|
|
obj.ensemble_id = self.request.ensemble_id
|
|
try:
|
|
obj.save()
|
|
except IntegrityError:
|
|
form.add_error('name', 'Name must be unique')
|
|
return self.form_invalid(form)
|
|
|
|
# handle the files
|
|
uploads = self.request.FILES.getlist('uploads')
|
|
docs = []
|
|
for f in uploads:
|
|
docs.append(obj.docs.create(upload=f).pk)
|
|
|
|
if len(docs) == 1:
|
|
return redirect('document_annotate', docs[0])
|
|
else:
|
|
return redirect('work_detail', pk=obj.pk)
|
|
|
|
class WorkDetailView(EnsembleMixin, DetailView):
|
|
|
|
def get_queryset(self):
|
|
return Work.objects.filter(ensemble=self.request.ensemble_id)
|
|
|
|
|
|
class DocumentDetailView(EnsembleMixin, DetailView):
|
|
|
|
def get_queryset(self):
|
|
return Document.objects.filter(work__ensemble=self.request.ensemble_id).select_related('work')
|
|
|
|
class DocumentAddView(EnsembleMixin, CreateView):
|
|
template_name = "interface/default_form.html"
|
|
model = Document
|
|
fields = ['upload']
|
|
|
|
def form_valid(self, form):
|
|
self.object = form.save(commit=False)
|
|
self.object.work_id = self.kwargs['pk']
|
|
self.object.save()
|
|
return redirect('document_annotate', self.object.pk)
|
|
|
|
class DocumentDownloadView(EnsembleMixin, SingleObjectMixin, View):
|
|
|
|
def get(self, request, **args):
|
|
self.request = request
|
|
self.args = args
|
|
self.object = self.get_object()
|
|
|
|
#response = FileResponse(self.object.upload, content_type="application/pdf")
|
|
#return response
|
|
return redirect(self.object.upload.url)
|
|
|
|
def get_queryset(self):
|
|
return Document.objects.filter(work__ensemble=self.request.ensemble_id)
|
|
|
|
class DocumentAnnotateView(EnsembleMixin, DetailView):
|
|
template_name = 'library/document_annotate.html'
|
|
|
|
def post(self, request, **args):
|
|
self.request = request
|
|
self.args = args
|
|
self.object = self.get_object()
|
|
|
|
data = json.loads(request.body)
|
|
|
|
tags = {}
|
|
for page, tag in data.items():
|
|
tags.setdefault(tag, []).append(int(page))
|
|
try:
|
|
del(tags['None'])
|
|
except KeyError:
|
|
pass
|
|
|
|
self.object.parts.all().delete()
|
|
for tag, pages in tags.items():
|
|
pages.sort()
|
|
end = pages[-1] if len(pages) > 1 else None
|
|
o = self.object.parts.create(tag=tag, start=pages[0], end=end)
|
|
|
|
return HttpResponse(status=204)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
data = super(DocumentAnnotateView, self).get_context_data(**kwargs)
|
|
|
|
pages = {}
|
|
for part in data['document'].parts.all():
|
|
for i in range(part.start, (part.end or part.start)+1):
|
|
pages[i] = part.tag
|
|
|
|
data['json_data'] = {'pageTags': pages, 'instruments': data['document'].work.instruments}
|
|
return data
|
|
|
|
def get_queryset(self):
|
|
return Document.objects.filter(work__ensemble=self.request.ensemble_id).select_related('work')
|
|
|
|
class PartDownloadView(EnsembleMixin, SingleObjectMixin, View):
|
|
|
|
def get(self, request, **args):
|
|
self.request = request
|
|
self.args = args
|
|
self.object = self.get_object()
|
|
|
|
result = extract_pages(self.object.doc.upload.path, self.object.doc.work.name, self.object.start, self.object.end)
|
|
|
|
download_name = f'{self.object.doc.work.name}_{self.object.instrument}.pdf'
|
|
|
|
response = FileResponse(result, content_type="application/pdf")
|
|
response['Content-Disposition'] = f'inline; filename="foo.pdf"'
|
|
return response
|
|
|
|
def get_queryset(self):
|
|
return Part.objects.filter(doc__work__ensemble=self.request.ensemble_id).select_related('doc', 'doc__work') |