Finally got authentication to somewhere I'm happy
This commit is contained in:
@@ -64,7 +64,7 @@ class ProjectItem(models.Model):
|
||||
approved_by = models.ForeignKey('auth.User', on_delete=models.CASCADE)
|
||||
order = models.SmallIntegerField(default=0)
|
||||
section = models.CharField(max_length=100, blank=True)
|
||||
#version = models.CharField(max_length=30, blank=True, help_text="Limited to specific version tag")
|
||||
|
||||
|
||||
class Meta:
|
||||
ordering = ['order', 'work']
|
||||
@@ -101,6 +101,12 @@ class Collection(models.Model):
|
||||
def genres(self):
|
||||
return self.meta('genre')
|
||||
|
||||
def has_administrator(self, user):
|
||||
if not user.is_authenticated:
|
||||
return False
|
||||
if user.is_superuser:
|
||||
return True
|
||||
return user.pk in self.administrators.values_list('pk', flat=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
<div class="column is-half">
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<a class="" href="{% url 'collection_work_list' pk=collection.id %}">
|
||||
<a class="" href="{% url 'collection_work_list' collection=collection.id %}">
|
||||
<p class="card-header-title">{{ collection.name }}</p>
|
||||
</a>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<p>
|
||||
{% if collection.location %}{{ collection.location }},{% endif %}
|
||||
{{ collection.works.count }} items.
|
||||
{{ collection.works.count }} item{{ collection.works.count|pluralize }}.
|
||||
</p>
|
||||
<p>
|
||||
{% for tag in collection.tags %}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
{% if project %}
|
||||
<li><a href="{% url 'item_list' project=project.pk %}">My Music</a></li>
|
||||
{% endif %}
|
||||
{% if request.is_admin %}
|
||||
{% if request.user.is_authenticated %}
|
||||
<li><a href="{% url 'work_list' %}">Library</a></li>
|
||||
<li><a href="{% url 'collection_list' %}">Collections</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
@@ -29,8 +29,8 @@
|
||||
<th>Work</th>
|
||||
<th>Composer</th>
|
||||
<th class="is-hidden-mobile">Edition</th>
|
||||
{% if request.is_admin %}
|
||||
<th class="is-hidden-touch">Collection</th>
|
||||
{% if request.is_admin %}
|
||||
<th class="is-hidden-mobile">Copies</th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
@@ -38,11 +38,11 @@
|
||||
<tbody>
|
||||
{% for work in object_list %}
|
||||
<tr>
|
||||
<td><a href="{% url 'work_detail' pk=work.pk %}">{{ work.name }}</a></td>
|
||||
<td><a href="{% url 'work_detail' collection=work.collection.pk pk=work.pk %}">{{ work.name }}</a></td>
|
||||
<td title="{{ work.composer }}">{{ work.composer|truncatewords:3 }}</td>
|
||||
<td class="is-hidden-mobile" title="{{ work.edition }}">{{ work.edition|truncatewords:2 }}</td>
|
||||
{% if request.is_admin %}
|
||||
<td class="is-hidden-touch">{{ work.collection.name }}</td>
|
||||
{% if request.is_admin %}
|
||||
<td class="is-hidden-mobile {{ work.is_available|yesno:'has-text-success,has-text-danger' }}">{{ work.available }}</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
|
||||
+15
-14
@@ -15,22 +15,23 @@ urlpatterns = [
|
||||
path('projects/<int:project>/items', views.ProjectItemListView.as_view(), name="item_list"),
|
||||
path('projects/<int:project>/items/manage', views.ProjectItemManageView.as_view(), name="item_list_manage"),
|
||||
path('projects/<int:project>/items/append', views.ProjectItemAddView.as_view(), name="item_list_append"),
|
||||
|
||||
path('library/collections', views.CollectionListView.as_view(), name="collection_list"),
|
||||
path('library/collections/<int:pk>', views.CollectionWorkListView.as_view(), name="collection_work_list"),
|
||||
path('library/collections/<int:pk>/create', views.WorkAddView.as_view(), name="work_add"),
|
||||
|
||||
path('library/works', views.WorkListView.as_view(), name="work_list"),
|
||||
path('library/works/<int:pk>', views.WorkDetailView.as_view(), name="work_detail"),
|
||||
path('library/works/<int:pk>/edit', views.WorkUpdateView.as_view(), name="work_edit"),
|
||||
path('library/works/<int:pk>/partset', views.WorkPartSetView.as_view(), name="work_partset"),
|
||||
path('library/works/<int:pk>/add_to_project', views.WorkAddToProject.as_view(), name="work_add_to_project"),
|
||||
path('library/works/<int:pk>/upload', views.WorkAddDocumentView.as_view(), name="document_add"),
|
||||
path('library', views.WorkListView.as_view(), name="work_list"),
|
||||
|
||||
path('library/documents/<int:pk>/delete', views.DocumentDeleteView.as_view(), name="document_delete"),
|
||||
path('library/documents/<int:pk>/download', views.DocumentDownloadView.as_view(), name="document_download"),
|
||||
path('library/documents/<int:pk>/annotate', views.DocumentAnnotateView.as_view(), name="document_annotate"),
|
||||
path('library/parts/<int:pk>/<str:filename>', views.PartDownloadView.as_view(), name="part_download"),
|
||||
path('collections', views.CollectionListView.as_view(), name="collection_list"),
|
||||
path('collections/<int:collection>', views.CollectionWorkListView.as_view(), name="collection_work_list"),
|
||||
path('collections/<int:collection>/add', views.WorkAddView.as_view(), name="work_add"),
|
||||
|
||||
path('collections/<int:collection>/works/<int:pk>', views.WorkDetailView.as_view(), name="work_detail"),
|
||||
path('collections/<int:collection>/works/<int:pk>/edit', views.WorkUpdateView.as_view(), name="work_edit"),
|
||||
path('collections/<int:collection>/works/<int:pk>/partset', views.WorkPartSetView.as_view(), name="work_partset"),
|
||||
path('collections/<int:collection>/works/<int:pk>/add_to_project', views.WorkAddToProject.as_view(), name="work_add_to_project"),
|
||||
path('collections/<int:collection>/works/<int:pk>/upload', views.WorkAddDocumentView.as_view(), name="document_add"),
|
||||
|
||||
path('collections/<int:collection>/docs/<int:pk>/delete', views.DocumentDeleteView.as_view(), name="document_delete"),
|
||||
path('collections/<int:collection>/docs/<int:pk>/download', views.DocumentDownloadView.as_view(), name="document_download"),
|
||||
path('collections/<int:collection>/docs/<int:pk>/annotate', views.DocumentAnnotateView.as_view(), name="document_annotate"),
|
||||
path('collections/<int:collection>/docs/<int:pk>/<str:filename>', views.PartDownloadView.as_view(), name="part_download"),
|
||||
|
||||
#path('api/', include(router.urls))
|
||||
path('api/library/collections/<int:pk>/export', api.CollectionExportView.as_view(), name="collection_export"),
|
||||
|
||||
@@ -13,13 +13,18 @@ import json
|
||||
import os.path
|
||||
import re
|
||||
|
||||
from interface.views import EnsembleMixin, ProjectMixin
|
||||
from interface.views import EnsembleMixin, ProjectMixin, AuthorizedResourceMixin
|
||||
from interface.models import Project
|
||||
from library.models import Collection, Work, Document, Section
|
||||
from library.imslp import INSTRUMENT_TAGS, INSTRUMENTS
|
||||
from library import forms, models
|
||||
from library.pdf_utils import extract_pages, extract_and_concat
|
||||
|
||||
"""
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class ProjectItemListView(ProjectMixin, ListView):
|
||||
template_name = "library/item_list.html"
|
||||
model = models.ProjectItem
|
||||
@@ -76,6 +81,7 @@ class ProjectItemListView(ProjectMixin, ListView):
|
||||
# data['running_time'] = "-:--"
|
||||
return data
|
||||
|
||||
|
||||
class ProjectItemManageView(ProjectMixin, ListView):
|
||||
template_name = "library/item_list_manage.html"
|
||||
model = models.ProjectItem
|
||||
@@ -109,25 +115,60 @@ class ProjectItemAddView(ProjectMixin, UpdateView):
|
||||
def get_object(self):
|
||||
return self.get_project()
|
||||
|
||||
class CollectionListView(EnsembleMixin, ListView):
|
||||
""" COLLECTION VIEWS """
|
||||
|
||||
class CollectionMixin(AuthorizedResourceMixin):
|
||||
def is_authorized(self):
|
||||
super().is_authorized()
|
||||
try:
|
||||
self.collection = self.get_collection()
|
||||
return True
|
||||
except (models.Collection.DoesNotExist, KeyError):
|
||||
return False
|
||||
|
||||
def get_queryset(self):
|
||||
return Collection.objects.filter(administrators=self.request.user)
|
||||
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 WorkListView(EnsembleMixin, ListView):
|
||||
def get_collection_queryset(self):
|
||||
collections = models.Collection.objects.all()
|
||||
|
||||
if self.request.user.is_anonymous:
|
||||
return models.Collection.objects.none()
|
||||
|
||||
if self.request.is_admin:
|
||||
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
|
||||
|
||||
def get_works(self):
|
||||
return Work.objects.filter(collection__allowed_ensembles__ensemble=self.request.ensemble_id).order_by('name').distinct().select_related('collection')
|
||||
collections = CollectionMixin.get_queryset(self)
|
||||
return Work.objects.filter(collection__in=collections).order_by('name').distinct().select_related('collection')
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
data = super(WorkListView, self).get_context_data(*args, **kwargs)
|
||||
data['title'] = f'Music available to {self.ensemble.name}'
|
||||
#data['title'] = f'Music available to {self.ensemble.name}'
|
||||
data['title'] = "My Library"
|
||||
return data
|
||||
|
||||
def get_queryset(self):
|
||||
works = self.get_works().order_by('name')
|
||||
works = self.get_works()
|
||||
|
||||
q = self.request.GET.get('filter')
|
||||
if q:
|
||||
@@ -142,7 +183,7 @@ class WorkListView(EnsembleMixin, ListView):
|
||||
class CollectionWorkListView(WorkListView):
|
||||
|
||||
def get_works(self):
|
||||
works = Work.objects.filter(collection=self.kwargs['pk']).distinct()
|
||||
works = Work.objects.filter(collection=self.kwargs['collection']).distinct()
|
||||
|
||||
loan_count = Count('project_items', Q(project_items__checkout__lte=now(), project_items__returned=None))
|
||||
works = works.annotate(loan_count=loan_count)
|
||||
@@ -150,11 +191,10 @@ class CollectionWorkListView(WorkListView):
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
data = super(CollectionWorkListView, self).get_context_data(*args, **kwargs)
|
||||
data['title'] = Collection.objects.get(pk=self.kwargs['pk']).name
|
||||
data['collection_id'] = self.kwargs['pk']
|
||||
data['title'] = self.collection.name
|
||||
return data
|
||||
|
||||
class WorkAddView(EnsembleMixin, FormView):
|
||||
class WorkAddView(CollectionMixin, FormView):
|
||||
template_name = "interface/default_form.html"
|
||||
form_class = forms.WorkCreateForm
|
||||
|
||||
@@ -185,10 +225,10 @@ class WorkMixin(object):
|
||||
|
||||
return Work.objects.filter(collection__allowed_ensembles__ensemble=self.request.ensemble_id)
|
||||
|
||||
class WorkDetailView(EnsembleMixin, WorkMixin, DetailView):
|
||||
class WorkDetailView(CollectionMixin, WorkMixin, DetailView):
|
||||
pass
|
||||
|
||||
class WorkUpdateView(EnsembleMixin, WorkMixin, UpdateView):
|
||||
class WorkUpdateView(CollectionMixin, WorkMixin, UpdateView):
|
||||
fields = ['name', 'composer', 'edition', 'code', 'licence', 'max_projects', 'running_time', 'notes']
|
||||
template_name = 'interface/default_form.html'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user