Got library working again

This commit is contained in:
Tris Forster
2023-02-16 17:22:18 +11:00
parent b85440d25c
commit 13f466228b
17 changed files with 427 additions and 140 deletions
+52 -41
View File
@@ -1,10 +1,11 @@
from django.shortcuts import render, redirect, resolve_url
from django.shortcuts import get_object_or_404, redirect, resolve_url
from django.views.generic.detail import DetailView, SingleObjectMixin, View
from django.views.generic.list import ListView, MultipleObjectMixin
from django.views.generic.edit import CreateView, FormView, UpdateView, DeleteView
from django.http import FileResponse, HttpResponse, JsonResponse
from django.db import IntegrityError
from django.db.models import Q, Count, Sum
from django.db import transaction
from django.utils.timezone import now
from django.urls import reverse
from django.template.loader import render_to_string
@@ -119,40 +120,41 @@ class ProjectItemAddView(ProjectMixin, UpdateView):
class CollectionMixin(AuthorizedResourceMixin):
def is_authorized(self):
super().is_authorized()
try:
self.collection = self.get_collection()
collection_id = self.kwargs['collection']
self.collection = get_object_or_404(models.Collection, pk=collection_id)
if super().is_authorized():
return True
except (models.Collection.DoesNotExist, KeyError):
return False
if self.collection.has_admininistrator(self.request.user):
self.request.is_admin = True
return True
return False
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
if self.collection:
data['collection'] = self.collection
return data
def get_queryset(self):
return super().get_queryset().filter(collection=self.collection)
def get_collection(self):
collection = self.get_collection_queryset().get(pk=self.kwargs['collection'])
self.request.is_admin = collection.has_administrator(self.request.user)
return collection
class CollectionListView(ListView):
paginate_by = 20
def get_collection_queryset(self):
def get_queryset(self):
collections = models.Collection.objects.all()
if self.request.user.is_anonymous:
return models.Collection.objects.none()
if self.request.is_admin:
if self.request.user.is_staff:
return collections
return collections.filter(Q(administrators=self.request.user) | Q(allowed_ensembles__ensemble__admins=self.request.user))
class CollectionListView(CollectionMixin, ListView):
paginate_by = 20
def is_authorized(self):
return True
def get_queryset(self):
return self.get_collection_queryset()
class WorkListView(CollectionMixin, ListView):
paginate_by = 20
@@ -178,7 +180,7 @@ class WorkListView(CollectionMixin, ListView):
else:
works = works.filter(Q(name__contains=q) | Q(composer__contains=q) | Q(meta_info__value__contains=q))
return works
return works.order_by('name', 'pk')
class CollectionWorkListView(WorkListView):
@@ -237,7 +239,7 @@ class WorkUpdateView(CollectionMixin, WorkMixin, UpdateView):
class WorkAddToProject(EnsembleMixin, FormView):
class WorkAddToProject(ProjectMixin, FormView):
admin_required = True
form_class = forms.ProjectSelectForm
template_name = "interface/default_form.html"
@@ -295,7 +297,7 @@ class WorkPartSetView(EnsembleMixin, DetailView):
works = works.filter(collection__allowed_ensembles__ensemble=self.request.ensemble_id)
return works
class WorkAddDocumentView(EnsembleMixin, CreateView):
class WorkAddDocumentView(CollectionMixin, CreateView):
template_name = "interface/default_form.html"
model = Document
fields = ['upload']
@@ -333,22 +335,28 @@ class WorkAddDocumentView(EnsembleMixin, CreateView):
return JsonResponse({
"message": "created",
"id": doc.pk,
"entry": render_to_string('library/document_entry.html', {'doc': doc, 'request': self.request})
"entry": render_to_string('library/document_entry.html',
{'collection': self.collection, 'doc': doc, 'request': self.request}
)
}, status=201)
return redirect('document_annotate', doc.pk)
return redirect('document_annotate', self.collection.pk, doc.pk)
class DocumentMixin(object):
class DocumentMixin(CollectionMixin):
model = models.Document
def get_queryset(self):
if self.request.is_admin:
return Document.objects.select_related('work')
return Document.objects.filter(work__ensemble=self.request.ensemble_id).select_related('work')
return models.Document.objects.filter(work__collection=self.collection)
class DocumentDetailView(EnsembleMixin, DocumentMixin, DetailView):
# def get_queryset(self):
# if self.request.is_admin:
# return Document.objects.select_related('work')
# return Document.objects.filter(work__ensemble=self.request.ensemble_id).select_related('work')
class DocumentDetailView(DocumentMixin, DetailView):
pass
class DocumentDownloadView(EnsembleMixin, DocumentMixin, SingleObjectMixin, View):
class DocumentDownloadView(DocumentMixin, SingleObjectMixin, View):
def get(self, request, **args):
self.request = request
@@ -359,7 +367,7 @@ class DocumentDownloadView(EnsembleMixin, DocumentMixin, SingleObjectMixin, View
#return response
return redirect(self.object.upload.url)
class DocumentAnnotateView(EnsembleMixin, DocumentMixin, DetailView):
class DocumentAnnotateView(DocumentMixin, DetailView):
template_name = 'library/document_annotate.html'
def post(self, request, **args):
@@ -369,11 +377,12 @@ class DocumentAnnotateView(EnsembleMixin, DocumentMixin, DetailView):
data = json.loads(request.body)
self.object.sections.all().delete()
for tag, start, end in data:
#pages.sort()
#end = pages[-1] if len(pages) > 1 else None
o = self.object.sections.create(tag=tag, start=start, end=end)
with transaction.atomic():
self.object.sections.all().delete()
for tag, start, end in data:
#pages.sort()
#end = pages[-1] if len(pages) > 1 else None
o = self.object.sections.create(tag=tag, type=models.Section.TYPE_INSTRUMENT, start=start, end=end)
return HttpResponse(status=204)
@@ -387,15 +396,17 @@ class DocumentAnnotateView(EnsembleMixin, DocumentMixin, DetailView):
data['json_data'] = {'pageTags': pages, 'instruments': dict(INSTRUMENTS)}
return data
class DocumentDeleteView(EnsembleMixin, DocumentMixin, DeleteView):
class DocumentDeleteView(DocumentMixin, DeleteView):
#def get_template_names(self):
# return ["interface/default_form.html"]
def get_success_url(self):
return resolve_url('work_detail', self.object.work.pk)
return resolve_url('work_detail', self.collection.pk, self.object.work_id)
class PartDownloadView(EnsembleMixin, SingleObjectMixin, View):
class PartDownloadView(CollectionMixin, SingleObjectMixin, View):
pk_url_kwarg = 'section'
def get(self, request, **args):
self.request = request
+33 -1
View File
@@ -37,7 +37,7 @@ from interface.views import EnsembleMixin
from rest_framework import routers, serializers, viewsets
from library.models import Collection, Work, Document, Section
from library.models import Collection, Work, Document, Section, WorkMeta
import requests
@@ -48,6 +48,17 @@ import shutil
from django.db import transaction
from django.core.files.uploadedfile import TemporaryUploadedFile
class WorkMetaSerializer(serializers.ModelSerializer):
class Meta:
model = WorkMeta
exclude = ['id', 'work']
def to_representation(self, instance):
return f"{instance.name}:{instance.value}"
def to_internal_value(self, data):
name, _, value = data.partition(':')
return super().to_internal_value({'name': name, 'value': value})
class SectionSerializer(serializers.ModelSerializer):
class Meta:
@@ -111,6 +122,7 @@ class DocumentSerializer(serializers.ModelSerializer):
class WorkSerializer(serializers.ModelSerializer):
docs = DocumentSerializer(many=True)
meta_info = WorkMetaSerializer(many=True)
class Meta:
model = Work
@@ -119,6 +131,7 @@ class WorkSerializer(serializers.ModelSerializer):
def create(self, validated):
with transaction.atomic():
docs = validated.pop('docs', [])
meta = validated.pop('meta_info', [])
work = Work.objects.create(**validated)
for d in docs:
@@ -134,11 +147,25 @@ class WorkSerializer(serializers.ModelSerializer):
for s in sections:
Section.objects.create(doc_id=doc.pk, **s)
for m in meta:
WorkMeta.objects.create(work_id=work.pk, **m)
return work
class CollectionSerializer(serializers.Serializer):
works = WorkSerializer(many=True)
def create(self, validated):
s = WorkSerializer()
print(validated)
collection = validated['collection_id']
with transaction.atomic():
for work in validated['works']:
work['collection_id'] = collection
s.create(work)
return Collection.objects.get(pk=collection)
from rest_framework import generics
class CollectionExportView(generics.RetrieveAPIView):
@@ -159,3 +186,8 @@ class WorkImportView(generics.CreateAPIView):
def perform_create(self, serializer):
serializer.save(collection_id=self.kwargs['pk'])
class CollectionImportView(generics.CreateAPIView):
serializer_class = CollectionSerializer
def perform_create(self, serializer):
serializer.save(collection_id=self.kwargs['pk'])