Compare commits
19 Commits
1aababe2ae
...
07f3881dde
Author | SHA1 | Date | |
---|---|---|---|
07f3881dde | |||
6469913f8a | |||
75f1973d41 | |||
b96cf59780 | |||
63c7fadd3f | |||
c9ddd38b9b | |||
72cd24083a | |||
fd3411ed38 | |||
fddaaee169 | |||
42ae35a6ae | |||
1bfbdb304f | |||
27b0bec870 | |||
5986d86da3 | |||
b4539481e6 | |||
25f6d91903 | |||
8b3d3a2483 | |||
c8b0d1c5fb | |||
1674266890 | |||
dd71f984ed |
|
@ -1,7 +1,12 @@
|
|||
from django import forms
|
||||
from django.forms import ModelForm
|
||||
from django.forms import ModelForm, ImageField, FileField
|
||||
|
||||
from .models import Comment
|
||||
from ckeditor.fields import RichTextField
|
||||
from filer.models.imagemodels import Image
|
||||
from filer.models.filemodels import File
|
||||
|
||||
from aircox.models import Comment, Episode, Program
|
||||
from aircox.controllers.sound_file import SoundFile
|
||||
|
||||
|
||||
class CommentForm(ModelForm):
|
||||
|
@ -16,3 +21,38 @@ class CommentForm(ModelForm):
|
|||
class Meta:
|
||||
model = Comment
|
||||
fields = ["nickname", "email", "content"]
|
||||
|
||||
|
||||
class ProgramForm(ModelForm):
|
||||
content = RichTextField()
|
||||
new_cover = ImageField(required=False)
|
||||
|
||||
class Meta:
|
||||
model = Program
|
||||
fields = ["content"]
|
||||
|
||||
def save(self, commit=True):
|
||||
file_obj = self.cleaned_data["new_cover"]
|
||||
if file_obj:
|
||||
obj, _ = Image.objects.get_or_create(original_filename=file_obj.name, file=file_obj)
|
||||
self.instance.cover = obj
|
||||
super().save(commit=commit)
|
||||
|
||||
|
||||
class EpisodeForm(ModelForm):
|
||||
content = RichTextField()
|
||||
new_podcast = FileField(required=False)
|
||||
|
||||
class Meta:
|
||||
model = Episode
|
||||
fields = ["content"]
|
||||
|
||||
def save(self, commit=True):
|
||||
file_obj = self.cleaned_data["new_podcast"]
|
||||
if file_obj:
|
||||
obj, _ = File.objects.get_or_create(original_filename=file_obj.name, file=file_obj)
|
||||
sound_file = SoundFile(obj.path)
|
||||
sound_file.sync(
|
||||
program=self.instance.program, episode=self.instance, type=0, is_public=True, is_downloadable=True
|
||||
)
|
||||
super().save(commit=commit)
|
||||
|
|
|
@ -125,6 +125,7 @@ class Program(Page):
|
|||
editors, created = Group.objects.get_or_create(name=self.editors_group_name)
|
||||
if created:
|
||||
self.editors = editors
|
||||
super().save()
|
||||
permission, _ = Permission.objects.get_or_create(
|
||||
name=f"change program {self.title}",
|
||||
codename=self.change_permission_codename,
|
||||
|
@ -159,7 +160,6 @@ class Program(Page):
|
|||
Sound.objects.filter(path__startswith=path_).update(file=Concat("file", Substr(F("file"), len(path_))))
|
||||
|
||||
self.set_group_ownership()
|
||||
super().save(*kargs, **kwargs)
|
||||
|
||||
|
||||
class ProgramChildQuerySet(PageQuerySet):
|
||||
|
|
|
@ -59,8 +59,6 @@ def do_get_tracks(obj):
|
|||
@register.simple_tag(name="has_perm", takes_context=True)
|
||||
def do_has_perm(context, obj, perm, user=None, simple=False):
|
||||
"""Return True if ``user.has_perm('[APP].[perm]_[MODEL]')``"""
|
||||
if not obj:
|
||||
return
|
||||
if user is None:
|
||||
user = context["request"].user
|
||||
if simple:
|
||||
|
@ -104,8 +102,6 @@ def do_player_live_attr(context):
|
|||
@register.simple_tag(name="nav_items", takes_context=True)
|
||||
def do_nav_items(context, menu, **kwargs):
|
||||
"""Render navigation items for the provided menu name."""
|
||||
if not getattr(context["request"], "station"):
|
||||
return []
|
||||
station, request = context["station"], context["request"]
|
||||
return [(item, item.render(request, **kwargs)) for item in station.navitem_set.filter(menu=menu)]
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from datetime import time, timedelta
|
||||
import itertools
|
||||
import logging
|
||||
import os
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
|
@ -162,3 +163,10 @@ def tracks(episode, sound):
|
|||
@pytest.fixture
|
||||
def user():
|
||||
return User.objects.create_user(username="user1", password="bar")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def png_content():
|
||||
image_file = "{}/image.png".format(os.path.dirname(__file__))
|
||||
with open(image_file, "rb") as fh:
|
||||
return fh.read()
|
||||
|
|
BIN
aircox/tests/image.png
Normal file
BIN
aircox/tests/image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 69 B |
|
@ -7,12 +7,6 @@ from django.core.files.uploadedfile import SimpleUploadedFile
|
|||
from aircox.models import Program
|
||||
|
||||
|
||||
png_content = (
|
||||
b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90wS\xde"
|
||||
+ b"\x00\x00\x00\x0cIDATx\x9cc`\xf8\xcf\x00\x00\x02\x02\x01\x00{\t\x81x\x00\x00\x00\x00IEND\xaeB`\x82"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.django_db()
|
||||
def test_edit_program(user, client, program):
|
||||
client.force_login(user)
|
||||
|
@ -29,7 +23,7 @@ def test_edit_program(user, client, program):
|
|||
|
||||
|
||||
@pytest.mark.django_db()
|
||||
def test_add_cover(user, client, program):
|
||||
def test_add_cover(user, client, program, png_content):
|
||||
assert program.cover is None
|
||||
user.groups.add(program.editors)
|
||||
client.force_login(user)
|
||||
|
@ -58,16 +52,16 @@ def test_edit_tracklist(user, client, program, episode, tracks):
|
|||
tracklist = [t.id for t in episode.track_set.all().order_by("position")]
|
||||
tracklist_details_reversed = [(t.id, t.artist, t.title) for t in episode.track_set.all().order_by("-position")]
|
||||
tracklist_details_reversed = list(chain(*tracklist_details_reversed))
|
||||
data = """{"website": [""], "content": ["foobar"], "new_podcast": [""], "form-TOTAL_FORMS": ["3"],
|
||||
data = """{{"website": [""], "content": ["foobar"], "new_podcast": [""], "form-TOTAL_FORMS": ["3"],
|
||||
"form-INITIAL_FORMS": ["3"], "form-MIN_NUM_FORMS": ["0"], "form-MAX_NUM_FORMS": ["1000"], "form-0-position": ["0"],
|
||||
"form-0-id": ["%s"], "form-0-": ["", "", "", "", "", ""], "form-0-artist": ["%s"], "form-0-title": ["%s"],
|
||||
"form-0-tags": [""], "form-0-album": [""], "form-0-year": [""], "form-1-position": ["1"], "form-1-id": ["%s"],
|
||||
"form-1-": ["", "", "", "", "", ""], "form-1-artist": ["%s"], "form-1-title": ["%s"], "form-1-tags": [""],
|
||||
"form-1-album": [""], "form-1-year": [""], "form-2-position": ["2"], "form-2-id": ["%s"], "form-2-": ["", "", "",
|
||||
"", "", ""], "form-2-artist": ["%s"], "form-2-title": ["%s"], "form-2-tags": [""], "form-2-album": [""],
|
||||
"form-2-year": [""]}""" % tuple(
|
||||
tracklist_details_reversed
|
||||
"form-0-id": ["{}"], "form-0-": ["", "", "", "", "", ""], "form-0-artist": ["{}"], "form-0-title": ["{}"],
|
||||
"form-0-tags": [""], "form-0-album": [""], "form-0-year": [""], "form-1-position": ["1"], "form-1-id": ["{}"],
|
||||
"form-1-": ["", "", "", "", "", ""], "form-1-artist": ["{}"], "form-1-title": ["{}"], "form-1-tags": [""],
|
||||
"form-1-album": [""], "form-1-year": [""], "form-2-position": ["2"], "form-2-id": ["{}"], "form-2-": ["", "", "",
|
||||
"", "", ""], "form-2-artist": ["{}"], "form-2-title": ["{}"], "form-2-tags": [""], "form-2-album": [""],
|
||||
"form-2-year": [""]}}""".format(
|
||||
*tracklist_details_reversed
|
||||
)
|
||||
r = client.post(reverse("episode-edit", kwargs={"pk": episode.pk}), json.loads(data), follow=True)
|
||||
assert r.status_code == 200
|
||||
assert [t.id for t in episode.track_set.all().order_by("position")] == list(reversed(tracklist))
|
||||
assert set(episode.track_set.all().values_list("id", flat=True)) == set(tracklist)
|
||||
|
|
|
@ -132,6 +132,6 @@ urls = [
|
|||
views.errors.NoStationErrorView.as_view(),
|
||||
name="errors-no-station",
|
||||
),
|
||||
path("gestion/", views.profile, name="profile"),
|
||||
path("accounts/profile/", views.profile, name="profile"),
|
||||
path("gestion/", views.ProfileView.as_view(), name="profile"),
|
||||
path("accounts/profile/", views.ProfileView.as_view(), name="profile"),
|
||||
]
|
||||
|
|
|
@ -11,7 +11,7 @@ from .page import (
|
|||
PageDetailView,
|
||||
PageListView,
|
||||
)
|
||||
from .profile import profile
|
||||
from .profile import ProfileView
|
||||
from .program import (
|
||||
ProgramDetailView,
|
||||
ProgramListView,
|
||||
|
@ -40,7 +40,7 @@ __all__ = (
|
|||
"BasePageListView",
|
||||
"PageDetailView",
|
||||
"PageListView",
|
||||
"profile",
|
||||
"ProfileView",
|
||||
"ProgramDetailView",
|
||||
"ProgramListView",
|
||||
"ProgramPageDetailView",
|
||||
|
|
|
@ -1,16 +1,10 @@
|
|||
from django.contrib.auth.mixins import UserPassesTestMixin
|
||||
from django.forms import ModelForm, FileField
|
||||
from django.forms.models import modelformset_factory
|
||||
from django.urls import reverse
|
||||
|
||||
from ckeditor.fields import RichTextField
|
||||
from filer.models.filemodels import File
|
||||
|
||||
from aircox.controllers.sound_file import SoundFile
|
||||
from aircox.models import Track
|
||||
|
||||
from aircox.forms import EpisodeForm
|
||||
from aircox.models import Episode, Program, StaticPage, Track
|
||||
from ..filters import EpisodeFilters
|
||||
from ..models import Episode, Program, StaticPage
|
||||
from .page import PageListView
|
||||
from .program import ProgramPageDetailView, BaseProgramMixin
|
||||
from .page import PageUpdateView
|
||||
|
@ -53,25 +47,6 @@ class PodcastListView(EpisodeListView):
|
|||
queryset = Episode.objects.published().with_podcasts().order_by("-pub_date")
|
||||
|
||||
|
||||
class EpisodeForm(ModelForm):
|
||||
content = RichTextField()
|
||||
new_podcast = FileField(required=False)
|
||||
|
||||
class Meta:
|
||||
model = Episode
|
||||
fields = ["content"]
|
||||
|
||||
def save(self, commit=True):
|
||||
file_obj = self.cleaned_data["new_podcast"]
|
||||
if file_obj:
|
||||
obj, _ = File.objects.get_or_create(original_filename=file_obj.name, file=file_obj)
|
||||
sound_file = SoundFile(obj.path)
|
||||
sound_file.sync(
|
||||
program=self.instance.program, episode=self.instance, type=0, is_public=True, is_downloadable=True
|
||||
)
|
||||
super().save(commit=commit)
|
||||
|
||||
|
||||
class EpisodeUpdateView(UserPassesTestMixin, BaseProgramMixin, PageUpdateView):
|
||||
model = Episode
|
||||
form_class = EpisodeForm
|
||||
|
|
|
@ -16,6 +16,7 @@ __all__ = [
|
|||
"BasePageDetailView",
|
||||
"PageDetailView",
|
||||
"PageListView",
|
||||
"PageUpdateView",
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
from django.contrib.auth.decorators import login_required
|
||||
from django.template.response import TemplateResponse
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.views.generic.base import TemplateView
|
||||
|
||||
from aircox.models import Program
|
||||
from aircox.views import BaseView
|
||||
|
||||
|
||||
@login_required
|
||||
def profile(request):
|
||||
programs = []
|
||||
ugroups = request.user.groups.all()
|
||||
for p in Program.objects.all():
|
||||
if p.editors in ugroups:
|
||||
programs.append(p)
|
||||
context = {"user": request.user, "programs": programs}
|
||||
return TemplateResponse(request, "accounts/profile.html", context)
|
||||
class ProfileView(LoginRequiredMixin, BaseView, TemplateView):
|
||||
template_name = "accounts/profile.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
groups = self.request.user.groups.all()
|
||||
programs = Program.objects.filter(editors__in=groups)
|
||||
kwargs.update({"user": self.request.user, "programs": programs})
|
||||
return super().get_context_data(**kwargs)
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
import random
|
||||
|
||||
from django.contrib.auth.mixins import UserPassesTestMixin
|
||||
from django.forms import ModelForm, ImageField
|
||||
from django.urls import reverse
|
||||
|
||||
from ckeditor.fields import RichTextField
|
||||
from filer.models.imagemodels import Image
|
||||
|
||||
|
||||
from ..models import Article, Episode, Page, Program, StaticPage
|
||||
from aircox.forms import ProgramForm
|
||||
from aircox.models import Article, Episode, Page, Program, StaticPage
|
||||
from .mixins import ParentMixin
|
||||
from .page import PageDetailView, PageListView, PageUpdateView
|
||||
|
||||
|
@ -56,22 +52,6 @@ class ProgramDetailView(BaseProgramMixin, PageDetailView):
|
|||
return super().get_template_names() + ["aircox/program_detail.html"]
|
||||
|
||||
|
||||
class ProgramForm(ModelForm):
|
||||
content = RichTextField()
|
||||
new_cover = ImageField(required=False)
|
||||
|
||||
class Meta:
|
||||
model = Program
|
||||
fields = ["content"]
|
||||
|
||||
def save(self, commit=True):
|
||||
file_obj = self.cleaned_data["new_cover"]
|
||||
if file_obj:
|
||||
obj, _ = Image.objects.get_or_create(original_filename=file_obj.name, file=file_obj)
|
||||
self.instance.cover = obj
|
||||
super().save(commit=commit)
|
||||
|
||||
|
||||
class ProgramUpdateView(UserPassesTestMixin, BaseProgramMixin, PageUpdateView):
|
||||
model = Program
|
||||
form_class = ProgramForm
|
||||
|
|
Loading…
Reference in New Issue
Block a user