350 lines
12 KiB
Python
350 lines
12 KiB
Python
import io
|
|
import os
|
|
import zipfile
|
|
|
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
|
from django.core.files import File
|
|
from django.db.models import Q
|
|
from django.http import Http404
|
|
from django.shortcuts import HttpResponse, get_object_or_404, redirect, render
|
|
from django.urls import reverse_lazy
|
|
from django.utils.safestring import mark_safe
|
|
from django.utils.text import slugify
|
|
from django.utils.translation import gettext_lazy as _
|
|
from django.views.generic import (CreateView, DeleteView, ListView,
|
|
TemplateView, UpdateView)
|
|
|
|
from gestion.mixins import ChefMuRequiredMixin
|
|
from gestion.models import Photo
|
|
from partitions.forms import UploadFileForm, UploadMorceauForm
|
|
from partitions.models import Category, Partition, PartitionSet, SetList
|
|
|
|
from .forms import ChefEditMorceauForm
|
|
|
|
|
|
def download_musecores(request):
|
|
|
|
p = Partition.objects.filter(
|
|
Q(part__contains=".mscz")
|
|
& Q(
|
|
Q(morceau__category__name="Partitions actives")
|
|
| Q(morceau__category__name="Partitions optionnelles")
|
|
)
|
|
)
|
|
|
|
zip_subdir = "Ernestophone_musescores"
|
|
zip_filename = "%s.zip" % zip_subdir
|
|
|
|
# Open StringIO to grab in-memory ZIP contents
|
|
s = io.BytesIO()
|
|
|
|
# The zip compressor
|
|
zf = zipfile.ZipFile(s, "w")
|
|
|
|
for part in p:
|
|
fpath = part.part.path
|
|
|
|
typ = ".mscz"
|
|
# Calculate path for file in zip
|
|
fdir, fname = os.path.split(fpath)
|
|
zip_path = os.path.join(
|
|
zip_subdir,
|
|
"%s_%s_%s.%s"
|
|
% (
|
|
slugify(part.morceau.nom),
|
|
slugify(part.morceau.auteur),
|
|
slugify(part.nom),
|
|
typ,
|
|
),
|
|
)
|
|
|
|
# Add file, at correct path
|
|
zf.write(fpath, zip_path)
|
|
|
|
# Must close zip for all contents to be written
|
|
zf.close()
|
|
# Grab ZIP file from in-memory, make response with correct MIME-type
|
|
resp = HttpResponse(s.getvalue())
|
|
# ..and correct content-disposition
|
|
resp["Content-Disposition"] = "attachment; filename=%s" % zip_filename
|
|
|
|
return resp
|
|
|
|
|
|
from datetime import date, timedelta
|
|
|
|
|
|
class Repertoire(TemplateView):
|
|
template_name = "partitions/repertoire.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["setlists"] = (
|
|
SetList.objects.filter(
|
|
is_current="y", date__gt=(date.today() - timedelta(days=7))
|
|
)
|
|
.order_by("date")
|
|
.prefetch_related("morceaux")
|
|
)
|
|
context["categories"] = Category.objects.prefetch_related(
|
|
"partitionset_set"
|
|
).order_by("order")
|
|
context["photo"] = Photo.objects.filter(cat="part").order_by("?").first()
|
|
return context
|
|
|
|
|
|
class Morceau(LoginRequiredMixin, TemplateView):
|
|
template_name = "partitions/part.html"
|
|
form_class = ChefEditMorceauForm
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super(Morceau, self).get_context_data(**kwargs)
|
|
p = get_object_or_404(
|
|
PartitionSet, nom=self.kwargs["nom"], auteur=self.kwargs["auteur"]
|
|
)
|
|
part = p.partition_set.all().order_by("nom")
|
|
form = self.form_class(instance=p)
|
|
infos = mark_safe(p.infos)
|
|
infos_en = mark_safe(p.infos_en)
|
|
context["p"] = p
|
|
context["infos"] = infos
|
|
context["infos_en"] = infos_en
|
|
context["form"] = form
|
|
context["part"] = part
|
|
context["nom"] = self.kwargs["nom"]
|
|
context["auteur"] = self.kwargs["auteur"]
|
|
|
|
return context
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
p = get_object_or_404(
|
|
PartitionSet, nom=self.kwargs["nom"], auteur=self.kwargs["auteur"]
|
|
)
|
|
if request.user.profile.is_chef:
|
|
form = self.form_class(request.POST, instance=p)
|
|
if form.is_valid():
|
|
form.save()
|
|
context = self.get_context_data()
|
|
return render(request, self.template_name, context)
|
|
|
|
|
|
class Upload(ChefMuRequiredMixin, TemplateView):
|
|
form_class = UploadFileForm
|
|
template_name = "partitions/upload.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super(Upload, self).get_context_data(**kwargs)
|
|
form = self.form_class()
|
|
|
|
context["nom"] = self.kwargs["nom"]
|
|
context["auteur"] = self.kwargs["auteur"]
|
|
context["form"] = form
|
|
return context
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
form = UploadFileForm(request.POST, request.FILES)
|
|
error = False
|
|
sauvegarde = False
|
|
if form.is_valid():
|
|
partition = Partition()
|
|
partition.part = form.cleaned_data["file"]
|
|
partition.nom = form.cleaned_data["title"]
|
|
if "/" in partition.nom:
|
|
error = _("Le caractère / n'est pas autorisé dans le nom")
|
|
context = self.get_context_data()
|
|
context["error"] = error
|
|
return render(request, self.template_name, context)
|
|
mor = get_object_or_404(
|
|
PartitionSet, nom=self.kwargs["nom"], auteur=self.kwargs["auteur"]
|
|
)
|
|
partition.morceau = mor
|
|
try:
|
|
mor.partition_set.get(nom=partition.nom)
|
|
error = _("Un morceau du même nom existe déjà")
|
|
except Partition.DoesNotExist:
|
|
partition.save()
|
|
sauvegarde = True
|
|
|
|
context = self.get_context_data()
|
|
context["form"] = form
|
|
context["error"] = error
|
|
context["sauvegarde"] = sauvegarde
|
|
return render(request, self.template_name, context)
|
|
|
|
|
|
def see(request, nom, auteur, partition_id):
|
|
partition = get_object_or_404(Partition, id=partition_id)
|
|
_, extension = os.path.splitext(partition.part.path)
|
|
download_unlogged = partition.morceau.download_unlogged
|
|
if download_unlogged == "o" or request.user.is_authenticated:
|
|
if ".pdf" == extension:
|
|
with open(partition.part.path, "rb") as f:
|
|
myfile = File(f)
|
|
response = HttpResponse(content=myfile.read())
|
|
response["Content-Type"] = "application/pdf"
|
|
response["Content-Disposition"] = "inline; filename=%s_%s_%s.pdf" % (
|
|
slugify(nom),
|
|
slugify(auteur),
|
|
slugify(partition.nom),
|
|
)
|
|
return response
|
|
elif ".mp3" == extension:
|
|
with open(partition.part.path, "rb") as f:
|
|
myfile = File(f)
|
|
response = HttpResponse()
|
|
response.write(myfile.read())
|
|
response["Content-Type"] = "audio/mp3"
|
|
response["Content-Length"] = myfile.size
|
|
return response
|
|
else:
|
|
p = get_object_or_404(PartitionSet, nom=nom, auteur=auteur)
|
|
part = p.partition_set.all()
|
|
return render(
|
|
request,
|
|
"partitions/part.html",
|
|
{"p": p, "part": part, "nom": nom, "auteur": auteur},
|
|
)
|
|
else:
|
|
return redirect("login")
|
|
|
|
|
|
class DeletePart(ChefMuRequiredMixin, TemplateView):
|
|
model = PartitionSet
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
p = get_object_or_404(
|
|
self.model, nom=self.kwargs["nom"], auteur=self.kwargs["auteur"]
|
|
)
|
|
try:
|
|
part = p.partition_set.get(id=self.kwargs["id"])
|
|
except Partition.DoesNotExist:
|
|
raise Http404
|
|
part.delete()
|
|
return redirect(
|
|
"partitions:listepart", nom=self.kwargs["nom"], auteur=self.kwargs["auteur"]
|
|
)
|
|
|
|
|
|
class CreateMorc(ChefMuRequiredMixin, TemplateView):
|
|
form_class = UploadMorceauForm
|
|
template_name = "partitions/new.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super(CreateMorc, self).get_context_data(**kwargs)
|
|
context["form"] = self.form_class()
|
|
return context
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
form = self.form_class(request.POST)
|
|
sauvegarde = False
|
|
error = False
|
|
if form.is_valid():
|
|
partitionset = PartitionSet()
|
|
partitionset.nom = form.cleaned_data["titre"]
|
|
partitionset.auteur = form.cleaned_data["auteur"]
|
|
if "/" in partitionset.auteur or "/" in partitionset.nom:
|
|
error = _("Le caractère / n'est pas autorisé")
|
|
context = self.get_context_data()
|
|
context["error"] = error
|
|
return render(request, self.template_name, context)
|
|
try:
|
|
PartitionSet.objects.get(
|
|
nom=partitionset.nom, auteur=partitionset.auteur
|
|
)
|
|
error = _("Un morceau du même nom existe déjà")
|
|
except PartitionSet.DoesNotExist:
|
|
# XXX. Hideous
|
|
cat = Category.objects.first()
|
|
try:
|
|
cat = Category.objects.get(name="Partitions à venir")
|
|
except Category.DoesNotExist:
|
|
pass
|
|
partitionset.category = cat
|
|
partitionset.save()
|
|
sauvegarde = True
|
|
return redirect("partitions:liste")
|
|
context = self.get_context_data()
|
|
context["sauvegarde"] = sauvegarde
|
|
context["error"] = error
|
|
context["form"] = form
|
|
return render(request, self.template_name, context)
|
|
|
|
|
|
class ConfDelete(ChefMuRequiredMixin, TemplateView):
|
|
template_name = "partitions/conf_delete.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["nom"] = self.kwargs.get("nom")
|
|
context["auteur"] = self.kwargs.get("auteur")
|
|
context["id"] = self.kwargs.get("id")
|
|
return context
|
|
|
|
|
|
class DeleteMorc(ChefMuRequiredMixin, TemplateView):
|
|
model = PartitionSet
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
p = get_object_or_404(
|
|
self.model, nom=self.kwargs["nom"], auteur=self.kwargs["auteur"]
|
|
)
|
|
part = p.partition_set.all()
|
|
for pa in part:
|
|
pa.delete()
|
|
p.delete()
|
|
return redirect("partitions:liste")
|
|
|
|
|
|
class ConfDeleteMorc(ChefMuRequiredMixin, TemplateView):
|
|
template_name = "partitions/conf_delete_morc.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["nom"] = self.kwargs.get("nom")
|
|
context["auteur"] = self.kwargs.get("auteur")
|
|
return context
|
|
|
|
|
|
def download(request, nom, auteur, partition_id):
|
|
|
|
partition = get_object_or_404(Partition, id=partition_id)
|
|
download_unlogged = partition.morceau.download_unlogged
|
|
if download_unlogged == "o" or request.user.is_authenticated:
|
|
with open(partition.part.path, "rb") as f:
|
|
myfile = File(f)
|
|
response = HttpResponse(content=myfile.read())
|
|
typ = os.path.splitext(myfile.name)[1][1:]
|
|
response["Content-Type"] = "application/%s" % (typ,)
|
|
response["Content-Disposition"] = "attachment; filename=%s_%s_%s.%s" % (
|
|
slugify(nom),
|
|
slugify(auteur),
|
|
slugify(partition.nom),
|
|
typ,
|
|
)
|
|
return response
|
|
else:
|
|
return redirect("login")
|
|
|
|
|
|
class SetListListView(ChefMuRequiredMixin, ListView):
|
|
model = SetList
|
|
|
|
def get_queryset(self):
|
|
return SetList.objects.all().order_by("-date")
|
|
|
|
|
|
class SetListCreate(ChefMuRequiredMixin, CreateView):
|
|
model = SetList
|
|
fields = ["date", "morceaux", "is_current"]
|
|
success_url = reverse_lazy("partitions:list_setlist")
|
|
|
|
|
|
class SetListUpdate(ChefMuRequiredMixin, UpdateView):
|
|
model = SetList
|
|
fields = ["date", "morceaux", "is_current"]
|
|
success_url = reverse_lazy("partitions:list_setlist")
|
|
|
|
|
|
class SetListDelete(ChefMuRequiredMixin, DeleteView):
|
|
model = SetList
|
|
success_url = reverse_lazy("partitions:list_setlist")
|