corrections + class views
This commit is contained in:
parent
406f92098f
commit
6ba168d286
81 changed files with 2756 additions and 2736 deletions
|
@ -1,7 +1,6 @@
|
|||
from django.contrib import admin
|
||||
|
||||
|
||||
from .models import Category,PartitionSet
|
||||
from .models import Category, PartitionSet
|
||||
|
||||
admin.site.register(Category)
|
||||
admin.site.register(PartitionSet)
|
||||
|
|
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class PartitionsConfig(AppConfig):
|
||||
name = 'partitions'
|
||||
name = "partitions"
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
from django.contrib.auth.decorators import user_passes_test
|
||||
|
||||
|
||||
def is_chef(user):
|
||||
try:
|
||||
profile = user.profile
|
||||
return profile.is_chef
|
||||
except:
|
||||
return False
|
||||
|
||||
chef_required = user_passes_test(lambda u: is_chef(u))
|
|
@ -1,5 +1,7 @@
|
|||
from django import forms
|
||||
|
||||
from .models import PartitionSet
|
||||
|
||||
|
||||
class UploadFileForm(forms.Form):
|
||||
title = forms.CharField(max_length=50)
|
||||
|
@ -9,3 +11,9 @@ class UploadFileForm(forms.Form):
|
|||
class UploadMorceauForm(forms.Form):
|
||||
titre = forms.CharField(max_length=100)
|
||||
auteur = forms.CharField(max_length=100)
|
||||
|
||||
|
||||
class ChefEditMorceauForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = PartitionSet
|
||||
fields = ("category", "download_unlogged", "infos", "url", "infos_en")
|
||||
|
|
|
@ -6,31 +6,66 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Partition',
|
||||
name="Partition",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
|
||||
('nom', models.CharField(max_length=100)),
|
||||
('part', models.FileField(upload_to='partitions/')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
verbose_name="ID",
|
||||
serialize=False,
|
||||
),
|
||||
),
|
||||
("nom", models.CharField(max_length=100)),
|
||||
("part", models.FileField(upload_to="partitions/")),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PartitionSet',
|
||||
name="PartitionSet",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
|
||||
('nom', models.CharField(max_length=100)),
|
||||
('auteur', models.CharField(max_length=100)),
|
||||
('category', models.CharField(max_length=8, choices=[('active', 'Actif'), ('incoming', 'À venir'), ('old', 'Archive'), ('optional', 'Optionnel')], default='incoming', verbose_name='Types de partitions')),
|
||||
('infos', models.TextField(blank=True, verbose_name='Infos utiles', null=True)),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
verbose_name="ID",
|
||||
serialize=False,
|
||||
),
|
||||
),
|
||||
("nom", models.CharField(max_length=100)),
|
||||
("auteur", models.CharField(max_length=100)),
|
||||
(
|
||||
"category",
|
||||
models.CharField(
|
||||
max_length=8,
|
||||
choices=[
|
||||
("active", "Actif"),
|
||||
("incoming", "À venir"),
|
||||
("old", "Archive"),
|
||||
("optional", "Optionnel"),
|
||||
],
|
||||
default="incoming",
|
||||
verbose_name="Types de partitions",
|
||||
),
|
||||
),
|
||||
(
|
||||
"infos",
|
||||
models.TextField(
|
||||
blank=True, verbose_name="Infos utiles", null=True
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='partition',
|
||||
name='morceau',
|
||||
field=models.ForeignKey(to='partitions.PartitionSet', on_delete=models.CASCADE),
|
||||
model_name="partition",
|
||||
name="morceau",
|
||||
field=models.ForeignKey(
|
||||
to="partitions.PartitionSet", on_delete=models.CASCADE
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
def create_categories(apps, schema_editor):
|
||||
# Insert the previously hardcoded categories in the database
|
||||
Category = apps.get_model("partitions", "Category")
|
||||
Category.objects.bulk_create([
|
||||
Category(name="Partitions actives", order=1),
|
||||
Category(name="Partitions optionnelles", order=2),
|
||||
Category(name="Partitions à venir", order=3),
|
||||
Category(name="Archives", order=4)
|
||||
])
|
||||
Category.objects.bulk_create(
|
||||
[
|
||||
Category(name="Partitions actives", order=1),
|
||||
Category(name="Partitions optionnelles", order=2),
|
||||
Category(name="Partitions à venir", order=3),
|
||||
Category(name="Archives", order=4),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def set_new_categories(apps, schema_editor):
|
||||
|
@ -24,7 +26,7 @@ def set_new_categories(apps, schema_editor):
|
|||
"active": assoc_list[0],
|
||||
"incoming": assoc_list[2],
|
||||
"old": assoc_list[3],
|
||||
"optional": assoc_list[1]
|
||||
"optional": assoc_list[1],
|
||||
}
|
||||
for par_set in PartitionSet.objects.all():
|
||||
par_set.category = mapping[par_set.category_old]
|
||||
|
@ -39,7 +41,7 @@ def reset_old_categories(apps, schema_editor):
|
|||
assoc_list[0][1]: "active",
|
||||
assoc_list[2][1]: "incoming",
|
||||
assoc_list[3][1]: "old",
|
||||
assoc_list[1][1]: "optional"
|
||||
assoc_list[1][1]: "optional",
|
||||
}
|
||||
for par_set in PartitionSet.objects.all():
|
||||
par_set.category_old = mapping[par_set.category]
|
||||
|
@ -49,29 +51,39 @@ def reset_old_categories(apps, schema_editor):
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('partitions', '0001_initial'),
|
||||
("partitions", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Category',
|
||||
name="Category",
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)),
|
||||
('name', models.CharField(max_length=127)),
|
||||
('order', models.IntegerField(verbose_name='order')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
verbose_name="ID",
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
auto_created=True,
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=127)),
|
||||
("order", models.IntegerField(verbose_name="order")),
|
||||
],
|
||||
options={'verbose_name': 'catégorie', 'verbose_name_plural': 'catégories'},
|
||||
options={"verbose_name": "catégorie", "verbose_name_plural": "catégories"},
|
||||
),
|
||||
migrations.RunPython(create_categories, migrations.RunPython.noop),
|
||||
migrations.RenameField(model_name="partitionset", old_name="category", new_name="category_old"),
|
||||
migrations.RenameField(
|
||||
model_name="partitionset", old_name="category", new_name="category_old"
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='partitionset',
|
||||
name='category',
|
||||
model_name="partitionset",
|
||||
name="category",
|
||||
field=models.ForeignKey(
|
||||
verbose_name='Type de partition',
|
||||
to='partitions.Category',
|
||||
verbose_name="Type de partition",
|
||||
to="partitions.Category",
|
||||
on_delete=django.db.models.deletion.PROTECT,
|
||||
default=1 # Dummy, will be set by the RunPython operation
|
||||
default=1, # Dummy, will be set by the RunPython operation
|
||||
),
|
||||
preserve_default=False,
|
||||
),
|
||||
|
|
|
@ -1,47 +1,78 @@
|
|||
# Generated by Django 2.2.14 on 2020-07-16 17:49
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.expressions
|
||||
import django.db.models.functions.text
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('partitions', '0002_category'),
|
||||
("partitions", "0002_category"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='category',
|
||||
options={'ordering': ('order',), 'verbose_name': 'Categorie', 'verbose_name_plural': 'Categories'},
|
||||
name="category",
|
||||
options={
|
||||
"ordering": ("order",),
|
||||
"verbose_name": "Categorie",
|
||||
"verbose_name_plural": "Categories",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='partition',
|
||||
options={'ordering': (django.db.models.expressions.CombinedExpression(django.db.models.expressions.Value('-'), '+', django.db.models.functions.text.Lower('nom')),), 'verbose_name': 'Morceau', 'verbose_name_plural': 'Morceaux'},
|
||||
name="partition",
|
||||
options={
|
||||
"ordering": (
|
||||
django.db.models.expressions.CombinedExpression(
|
||||
django.db.models.expressions.Value("-"),
|
||||
"+",
|
||||
django.db.models.functions.text.Lower("nom"),
|
||||
),
|
||||
),
|
||||
"verbose_name": "Morceau",
|
||||
"verbose_name_plural": "Morceaux",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='partitionset',
|
||||
options={'ordering': (django.db.models.expressions.CombinedExpression(django.db.models.expressions.Value('-'), '+', django.db.models.functions.text.Lower('nom')),), 'verbose_name': 'Morceau', 'verbose_name_plural': 'Morceaux'},
|
||||
name="partitionset",
|
||||
options={
|
||||
"ordering": (
|
||||
django.db.models.expressions.CombinedExpression(
|
||||
django.db.models.expressions.Value("-"),
|
||||
"+",
|
||||
django.db.models.functions.text.Lower("nom"),
|
||||
),
|
||||
),
|
||||
"verbose_name": "Morceau",
|
||||
"verbose_name_plural": "Morceaux",
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='category',
|
||||
name='nom_en',
|
||||
model_name="category",
|
||||
name="nom_en",
|
||||
field=models.CharField(blank=True, max_length=100, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='partitionset',
|
||||
name='infos_en',
|
||||
field=models.TextField(blank=True, null=True, verbose_name='Infos utiles en anglais'),
|
||||
model_name="partitionset",
|
||||
name="infos_en",
|
||||
field=models.TextField(
|
||||
blank=True, null=True, verbose_name="Infos utiles en anglais"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='partitionset',
|
||||
name='url',
|
||||
field=models.URLField(blank=True, help_text='Dans Youtube cliquer sur partager puis importer pour récuperer la bonne adresse', null=True, verbose_name="Url d'une video youtube"),
|
||||
model_name="partitionset",
|
||||
name="url",
|
||||
field=models.URLField(
|
||||
blank=True,
|
||||
help_text="Dans Youtube cliquer sur partager puis importer pour récuperer la bonne adresse",
|
||||
null=True,
|
||||
verbose_name="Url d'une video youtube",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='category',
|
||||
name='order',
|
||||
field=models.IntegerField(verbose_name='ordre'),
|
||||
model_name="category",
|
||||
name="order",
|
||||
field=models.IntegerField(verbose_name="ordre"),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,37 +1,52 @@
|
|||
# Generated by Django 2.2.17 on 2021-03-31 13:50
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.functions.text
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('partitions', '0003_auto_20200716_1749'),
|
||||
("partitions", "0003_auto_20200716_1749"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='partition',
|
||||
options={'ordering': (django.db.models.functions.text.Lower('nom'),), 'verbose_name': 'Morceau', 'verbose_name_plural': 'Morceaux'},
|
||||
name="partition",
|
||||
options={
|
||||
"ordering": (django.db.models.functions.text.Lower("nom"),),
|
||||
"verbose_name": "Morceau",
|
||||
"verbose_name_plural": "Morceaux",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='partitionset',
|
||||
options={'ordering': (django.db.models.functions.text.Lower('nom'),), 'verbose_name': 'Morceau', 'verbose_name_plural': 'Morceaux'},
|
||||
name="partitionset",
|
||||
options={
|
||||
"ordering": (django.db.models.functions.text.Lower("nom"),),
|
||||
"verbose_name": "Morceau",
|
||||
"verbose_name_plural": "Morceaux",
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='partitionset',
|
||||
name='download_unlogged',
|
||||
field=models.CharField(choices=[('n', 'Non'), ('o', 'Oui')], default='n', max_length=1, verbose_name='Téléchargeable non connecté ?'),
|
||||
model_name="partitionset",
|
||||
name="download_unlogged",
|
||||
field=models.CharField(
|
||||
choices=[("n", "Non"), ("o", "Oui")],
|
||||
default="n",
|
||||
max_length=1,
|
||||
verbose_name="Téléchargeable non connecté ?",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='partitionset',
|
||||
name='infos',
|
||||
field=models.TextField(blank=True, default='', verbose_name='Infos utiles'),
|
||||
model_name="partitionset",
|
||||
name="infos",
|
||||
field=models.TextField(blank=True, default="", verbose_name="Infos utiles"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='partitionset',
|
||||
name='infos_en',
|
||||
field=models.TextField(blank=True, default='', verbose_name='Infos utiles en anglais'),
|
||||
model_name="partitionset",
|
||||
name="infos_en",
|
||||
field=models.TextField(
|
||||
blank=True, default="", verbose_name="Infos utiles en anglais"
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -2,29 +2,28 @@ import os
|
|||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from colorful.fields import RGBColorField
|
||||
from django.db.models.functions import Lower
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
|
||||
class Category(models.Model):
|
||||
name = models.CharField(max_length=127)
|
||||
order = models.IntegerField(verbose_name=_("ordre"))
|
||||
nom_en = models.CharField(max_length=100,null=True,blank=True)
|
||||
nom_en = models.CharField(max_length=100, null=True, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Categorie")
|
||||
verbose_name_plural = _("Categories")
|
||||
ordering = ('order',)
|
||||
ordering = ("order",)
|
||||
|
||||
|
||||
class Partition(models.Model):
|
||||
nom = models.CharField(max_length=100)
|
||||
part = models.FileField(upload_to="partitions/")
|
||||
morceau = models.ForeignKey('PartitionSet', on_delete=models.CASCADE)
|
||||
morceau = models.ForeignKey("PartitionSet", on_delete=models.CASCADE)
|
||||
|
||||
def __str__(self):
|
||||
return self.nom
|
||||
|
@ -34,26 +33,40 @@ class Partition(models.Model):
|
|||
super(Partition, self).delete(*args, **kwargs)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Morceau')
|
||||
verbose_name_plural = _('Morceaux')
|
||||
ordering = (Lower('nom'),)
|
||||
verbose_name = _("Morceau")
|
||||
verbose_name_plural = _("Morceaux")
|
||||
ordering = (Lower("nom"),)
|
||||
|
||||
|
||||
class PartitionSet(models.Model):
|
||||
nom = models.CharField(max_length=100)
|
||||
auteur = models.CharField(max_length=100)
|
||||
category = models.ForeignKey(
|
||||
Category,
|
||||
on_delete=models.PROTECT,
|
||||
verbose_name=_("Type de partition")
|
||||
Category, on_delete=models.PROTECT, verbose_name=_("Type de partition")
|
||||
)
|
||||
download_unlogged = models.CharField(_("Téléchargeable non connecté ?"),default='n',choices = [('n',_('Non')),('o',_('Oui'))],max_length=1)
|
||||
infos = models.TextField(_("Infos utiles"), null=False, blank=True,default="")
|
||||
infos_en = models.TextField("Infos utiles en anglais", null=False, blank=True,default="")
|
||||
url = models.URLField(_("Url d'une video youtube"),null=True,blank=True, help_text= _("Dans Youtube cliquer sur partager puis importer pour récuperer la bonne adresse"))
|
||||
download_unlogged = models.CharField(
|
||||
_("Téléchargeable non connecté ?"),
|
||||
default="n",
|
||||
choices=[("n", _("Non")), ("o", _("Oui"))],
|
||||
max_length=1,
|
||||
)
|
||||
infos = models.TextField(_("Infos utiles"), null=False, blank=True, default="")
|
||||
infos_en = models.TextField(
|
||||
"Infos utiles en anglais", null=False, blank=True, default=""
|
||||
)
|
||||
url = models.URLField(
|
||||
_("Url d'une video youtube"),
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text=_(
|
||||
"Dans Youtube cliquer sur partager puis importer pour récuperer la bonne adresse"
|
||||
),
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return("%s - %s [%s]" % (self.nom, self.auteur, self.category))
|
||||
return "%s - %s [%s]" % (self.nom, self.auteur, self.category)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Morceau')
|
||||
verbose_name_plural = _('Morceaux')
|
||||
ordering = (Lower('nom'),)
|
||||
verbose_name = _("Morceau")
|
||||
verbose_name_plural = _("Morceaux")
|
||||
ordering = (Lower("nom"),)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<div class="inner">
|
||||
|
||||
<h4>{% trans "Confirmation de suppression" %}</h4>
|
||||
<p>{% trans "Voulez-vous vraiment supprimer cette partition ?" %}"</p>
|
||||
<p>{% trans "Voulez-vous vraiment supprimer cette partition ?" %}</p>
|
||||
<p><a href="{% url "partitions:delete" nom auteur id %}" class="button " >{% trans "Oui" %}</a></p>
|
||||
<p><a href="{% url "partitions:listepart" nom auteur %}" class="button alt" >{% trans "Retour à la liste des partitions" %}</a></p>
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
<div class="box">{% autotranslate current_language infos infos_en %}</div>
|
||||
|
||||
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
</div>
|
||||
{% else %}
|
||||
<img src="{% static 'images/all_repertoire.jpg' %}" alt="" /> <div style="position:absolute;z-index:1;right:0;bottom:0">
|
||||
<div class="icon fa-copyright" style="color:#000000"> Lucas Gierzack</div>
|
||||
<div class="icon fa-copyright" style="color:#000000"> Lucas Gierzack</div></div>
|
||||
{% endif %}
|
||||
</div></span>
|
||||
</span>
|
||||
{% if user.profile.is_chef %}
|
||||
<a href="{% url "partitions:ajouter_morceau" %}" class="button alt big">{% trans "Ajouter un morceau" %}</a>   <a href="{% url "partitions:download_musecores" %}" class="button alt big">{% trans "Télécharger tous les musecores actifs" %}</a>
|
||||
{% elif user.is_authenticated %}
|
||||
|
|
|
@ -4,6 +4,7 @@ from django.template.defaultfilters import urlencode
|
|||
from django.test import Client, TestCase
|
||||
|
||||
from gestion.models import ErnestoUser
|
||||
|
||||
from ..models import Category, Partition, PartitionSet
|
||||
|
||||
User = get_user_model()
|
||||
|
@ -11,12 +12,7 @@ User = get_user_model()
|
|||
|
||||
def new_user(username, ernesto=False, chef=False):
|
||||
u = User.objects.create_user(username=username)
|
||||
ErnestoUser.objects.create(
|
||||
user=u,
|
||||
slug=username,
|
||||
is_chef=chef,
|
||||
is_ernesto=ernesto
|
||||
)
|
||||
ErnestoUser.objects.create(user=u, slug=username, is_chef=chef, is_ernesto=ernesto)
|
||||
return u
|
||||
|
||||
|
||||
|
@ -32,16 +28,10 @@ class TestViews(TestCase):
|
|||
ernesto = new_user("ernesto", ernesto=True)
|
||||
ernesto_c = Client()
|
||||
ernesto_c.force_login(ernesto)
|
||||
self.client_matrix = [
|
||||
(chef, chef_c),
|
||||
(ernesto, ernesto_c),
|
||||
(None, Client())
|
||||
]
|
||||
self.client_matrix = [(chef, chef_c), (ernesto, ernesto_c), (None, Client())]
|
||||
# A Partition set with 1 partition
|
||||
self.pset = PartitionSet.objects.create(
|
||||
category=Category.objects.first(),
|
||||
nom="My PSet",
|
||||
auteur="PSet author"
|
||||
category=Category.objects.first(), nom="My PSet", auteur="PSet author"
|
||||
)
|
||||
file = File(open("partitions/tests/test_file.txt"), "test file")
|
||||
Partition.objects.create(nom="part1", part=file, morceau=self.pset)
|
||||
|
@ -90,9 +80,7 @@ class TestViews(TestCase):
|
|||
def test_download(self):
|
||||
"""Only ernesto members can download partitions"""
|
||||
part = self.pset.partition_set.first()
|
||||
url = "/partitions/{}/{}/{}".format(
|
||||
self.pset.nom, self.pset.auteur, part.id
|
||||
)
|
||||
url = "/partitions/{}/{}/{}".format(self.pset.nom, self.pset.auteur, part.id)
|
||||
self._get_restricted_page(url)
|
||||
|
||||
def test_new(self):
|
||||
|
|
|
@ -2,17 +2,26 @@ from django.urls import path
|
|||
|
||||
from . import views
|
||||
|
||||
app_name = 'partitions'
|
||||
app_name = "partitions"
|
||||
urlpatterns = [
|
||||
path('', views.liste, name='liste'),
|
||||
path('download', views.download_musecores, name='download_musecores'),
|
||||
path("<str:nom>/<str:auteur>/upload", views.upload, name="upload"),
|
||||
path("<str:nom>/<str:auteur>", views.listepart, name="listepart"),
|
||||
path("<str:nom>/<str:auteur>/see/<int:partition_id>", views.see, name="see"),
|
||||
path("<str:nom>/<str:auteur>/<int:partition_id>", views.download, name="download"),
|
||||
path("<str:nom>/<str:auteur>/<int:id>/conf", views.conf_delete, name="conf_delete"),
|
||||
path("<str:nom>/<str:auteur>/<int:id>/delete", views.delete, name="delete"),
|
||||
path("<str:nom>/<str:auteur>/delete", views.delete_morc, name="delete_morc"),
|
||||
path("<str:nom>/<str:auteur>/conf", views.conf_delete_morc, name="conf_delete_morc"),
|
||||
path("new", views.ajouter_morceau, name="ajouter_morceau"),
|
||||
path("", views.Repertoire.as_view(), name="liste"),
|
||||
path("download", views.download_musecores, name="download_musecores"),
|
||||
path("<str:nom>/<str:auteur>/upload", views.Upload.as_view(),
|
||||
name="upload"),
|
||||
path("<str:nom>/<str:auteur>", views.Morceau.as_view(), name="listepart"),
|
||||
path("<str:nom>/<str:auteur>/see/<int:partition_id>", views.see,
|
||||
name="see"),
|
||||
path("<str:nom>/<str:auteur>/<int:partition_id>", views.download,
|
||||
name="download"),
|
||||
path("<str:nom>/<str:auteur>/<int:id>/conf", views.ConfDelete.as_view(),
|
||||
name="conf_delete"),
|
||||
path("<str:nom>/<str:auteur>/<int:id>/delete", views.DeletePart.as_view(),
|
||||
name="delete"),
|
||||
path("<str:nom>/<str:auteur>/delete", views.DeleteMorc.as_view(),
|
||||
name="delete_morc"),
|
||||
path(
|
||||
"<str:nom>/<str:auteur>/conf", views.ConfDeleteMorc.as_view(),
|
||||
name="conf_delete_morc"
|
||||
),
|
||||
path("new", views.CreateMorc.as_view(), name="ajouter_morceau"),
|
||||
]
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
from django.shortcuts import render, HttpResponse, get_object_or_404, redirect, reverse
|
||||
from partitions.models import Category, Partition, PartitionSet
|
||||
from gestion.models import Photo
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from partitions.forms import UploadFileForm, UploadMorceauForm
|
||||
from django.forms.models import modelform_factory
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.text import slugify
|
||||
from django.core.files import File
|
||||
from django.utils.encoding import smart_str
|
||||
from django.http import Http404
|
||||
from partitions.decorators import chef_required
|
||||
from django.conf import settings
|
||||
from django.db.models import Q
|
||||
import io
|
||||
import os
|
||||
import zipfile
|
||||
import io
|
||||
|
||||
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.utils.safestring import mark_safe
|
||||
from django.utils.text import slugify
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from gestion.models import Photo
|
||||
from partitions.forms import UploadFileForm, UploadMorceauForm
|
||||
from partitions.models import Category, Partition, PartitionSet
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
from .forms import ChefEditMorceauForm
|
||||
from gestion.mixins import ChefRequiredMixin
|
||||
|
||||
|
||||
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" )))
|
||||
|
||||
|
||||
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
|
||||
|
@ -32,14 +39,22 @@ def download_musecores(request):
|
|||
# The zip compressor
|
||||
zf = zipfile.ZipFile(s, "w")
|
||||
|
||||
for part in p :
|
||||
for part in p:
|
||||
fpath = part.part.path
|
||||
|
||||
typ=".mscz"
|
||||
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))
|
||||
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)
|
||||
|
@ -49,70 +64,117 @@ def download_musecores(request):
|
|||
# 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
|
||||
resp["Content-Disposition"] = "attachment; filename=%s" % zip_filename
|
||||
|
||||
return resp
|
||||
|
||||
def liste(request):
|
||||
categories = Category.objects.prefetch_related("partitionset_set").order_by("order")
|
||||
photo = Photo.objects.filter(cat='part').order_by('?').first()
|
||||
return render(request, 'partitions/repertoire.html', {"categories": categories,"photo":photo})
|
||||
|
||||
@login_required
|
||||
def listepart(request, nom, auteur):
|
||||
p = get_object_or_404(PartitionSet, nom=nom, auteur=auteur)
|
||||
part = p.partition_set.all().order_by('nom')
|
||||
ChefEditForm = modelform_factory(PartitionSet,
|
||||
fields=("category","download_unlogged", "infos","url","infos_en"))
|
||||
if request.method == "POST" and request.user.profile.is_chef:
|
||||
form = ChefEditForm(request.POST, instance=p)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
form = ChefEditForm(instance=p)
|
||||
infos = mark_safe(p.infos)
|
||||
infos_en = mark_safe(p.infos_en)
|
||||
return render(request, 'partitions/part.html', locals())
|
||||
class Repertoire(TemplateView):
|
||||
template_name = "partitions/repertoire.html"
|
||||
|
||||
@chef_required
|
||||
def upload(request, nom, auteur):
|
||||
if request.method == "POST":
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
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(ChefRequiredMixin, TemplateView):
|
||||
form_class = UploadFileForm
|
||||
sauvegarde = False
|
||||
error = False
|
||||
template_name = "partitions/upload.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(Upload, self).get_context_data(**kwargs)
|
||||
form = self.form_class()
|
||||
|
||||
context["sauvegarde"] = self.sauvegarde
|
||||
context["nom"] = self.kwargs['nom']
|
||||
context["auteur"] = self.kwargs['auteur']
|
||||
context["form"] = form
|
||||
context["error"] = self.error
|
||||
return context
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
form = UploadFileForm(request.POST, request.FILES)
|
||||
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")
|
||||
form = UploadFileForm()
|
||||
return render(request, "partitions/upload.html", locals())
|
||||
mor = get_object_or_404(PartitionSet, nom=nom, auteur=auteur)
|
||||
partition.part = form.cleaned_data["file"]
|
||||
partition.nom = form.cleaned_data["title"]
|
||||
if "/" in partition.nom:
|
||||
self.error = _("Le caractère / n'est pas autorisé dans le nom")
|
||||
context = self.get_context_data()
|
||||
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à")
|
||||
self.error = _("Un morceau du même nom existe déjà")
|
||||
except Partition.DoesNotExist:
|
||||
partition.save()
|
||||
sauvegarde = True
|
||||
else:
|
||||
form = UploadFileForm()
|
||||
return render(request, 'partitions/upload.html', locals())
|
||||
self.sauvegarde = True
|
||||
|
||||
context = self.get_context_data()
|
||||
context['form'] = form
|
||||
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 download_unlogged == "o" or request.user.is_authenticated:
|
||||
if ".pdf" == extension:
|
||||
with open(partition.part.path, 'rb') as f:
|
||||
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))
|
||||
slugify(nom),
|
||||
slugify(auteur),
|
||||
slugify(partition.nom),
|
||||
)
|
||||
return response
|
||||
elif ".mp3" == extension:
|
||||
with open(partition.part.path, 'rb') as f:
|
||||
with open(partition.part.path, "rb") as f:
|
||||
myfile = File(f)
|
||||
response = HttpResponse()
|
||||
response.write(myfile.read())
|
||||
|
@ -122,38 +184,56 @@ def see(request, nom, auteur, partition_id):
|
|||
else:
|
||||
p = get_object_or_404(PartitionSet, nom=nom, auteur=auteur)
|
||||
part = p.partition_set.all()
|
||||
return render(request, 'partitions/part.html', locals())
|
||||
else :
|
||||
return redirect('login')
|
||||
return render(
|
||||
request,
|
||||
"partitions/part.html",
|
||||
{"p": p, "part": part, "nom": nom, "auteur": auteur},
|
||||
)
|
||||
else:
|
||||
return redirect("login")
|
||||
|
||||
@chef_required
|
||||
def delete(request, nom, auteur, id):
|
||||
p = get_object_or_404(PartitionSet, nom=nom, auteur=auteur)
|
||||
try:
|
||||
part = p.partition_set.get(id=id)
|
||||
except Partition.DoesNotExist:
|
||||
raise Http404
|
||||
part.delete()
|
||||
suppression = _("Partition supprimée")
|
||||
p.refresh_from_db()
|
||||
part = p.partition_set.all()
|
||||
return redirect('partitions:listepart',nom=nom,auteur=auteur)
|
||||
|
||||
@chef_required
|
||||
def ajouter_morceau(request):
|
||||
if request.method == "POST":
|
||||
form = UploadMorceauForm(request.POST)
|
||||
class DeletePart(ChefRequiredMixin, 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(ChefRequiredMixin, 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:
|
||||
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é")
|
||||
form = UploadMorceauForm()
|
||||
return render(request, 'partitions/new.html', locals())
|
||||
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)
|
||||
PartitionSet.objects.get(
|
||||
nom=partitionset.nom, auteur=partitionset.auteur
|
||||
)
|
||||
error = _("Un morceau du même nom existe déjà")
|
||||
except PartitionSet.DoesNotExist:
|
||||
# XXX. Hideous
|
||||
|
@ -165,50 +245,64 @@ def ajouter_morceau(request):
|
|||
partitionset.category = cat
|
||||
partitionset.save()
|
||||
sauvegarde = True
|
||||
return redirect('partitions:liste')
|
||||
else:
|
||||
form = UploadMorceauForm()
|
||||
return render(request, 'partitions/new.html', locals())
|
||||
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(ChefRequiredMixin, 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
|
||||
|
||||
|
||||
@chef_required
|
||||
def conf_delete(request, nom, auteur, id):
|
||||
part = get_object_or_404(Partition, id=id)
|
||||
return render(request, 'partitions/conf_delete.html', locals())
|
||||
class DeleteMorc(ChefRequiredMixin, TemplateView):
|
||||
model = PartitionSet
|
||||
|
||||
@chef_required
|
||||
def delete_morc(request, nom, auteur):
|
||||
p = get_object_or_404(PartitionSet, nom=nom, auteur=auteur)
|
||||
part = p.partition_set.all()
|
||||
for pa in part:
|
||||
pa.delete()
|
||||
p.delete()
|
||||
partitions = PartitionSet.objects.all()
|
||||
categories = Category.objects.prefetch_related("partitionset_set")
|
||||
return redirect('partitions:liste')
|
||||
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")
|
||||
|
||||
|
||||
@chef_required
|
||||
def conf_delete_morc(request, nom, auteur):
|
||||
return render(request, 'partitions/conf_delete_morc.html', locals())
|
||||
|
||||
class ConfDeleteMorc(ChefRequiredMixin, 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:
|
||||
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)
|
||||
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')
|
||||
else:
|
||||
return redirect("login")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue