Source code for radioco.apps.programmes.admin
# Radioco - Broadcasting Radio Recording Scheduling system.
# Copyright (C) 2014 Iago Veloso Abalo
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# XXX this code was missed to review, assume there are several bugs. REVIEW!
# Delete me when done!
from dateutil.relativedelta import relativedelta
from django import forms
from django.contrib import admin
from django.forms import ValidationError
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from radioco.apps.programmes.models import Programme, Podcast, Episode, Role, Participant
from radioco.apps.schedules.models import Calendar
# PROGRAMME
from radioco.apps.schedules.utils import next_dates
[docs]class NonStaffRoleInlineForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
if 'instance' in kwargs:
self.instance = kwargs['instance']
if 'person_object' in kwargs:
self.person = kwargs.pop('person_object')
super(NonStaffRoleInlineForm, self).__init__(*args, **kwargs)
[docs] def clean(self):
'''
Check unique together: person, role, programme
'''
cleaned_data = super(NonStaffRoleInlineForm, self).clean()
if 'person' in cleaned_data:
person = cleaned_data['person']
else:
person = self.person
role = cleaned_data['role']
programme = cleaned_data['programme']
qs = Role.objects.filter(role=role, programme=programme, person=person)
if self.instance.id:
qs = qs.exclude(pk=self.instance.id)
if qs.count() > 0:
raise ValidationError(_('This user has already a role in this programme.'))
return cleaned_data
[docs]class NonStaffRoleInlineFormset(forms.models.BaseInlineFormSet):
def _construct_form(self, i, **kwargs):
kwargs['person_object'] = self.person
return super(NonStaffRoleInlineFormset, self)._construct_form(i, **kwargs)
[docs]class NonStaffRoleInline(admin.StackedInline):
model = Role
extra = 0
form = NonStaffRoleInlineForm
formset = NonStaffRoleInlineFormset
list_select_related = True
[docs] def get_formset(self, request, obj=None, **kwargs):
kwargs['fields'] = ['person', 'role', 'description']
if not request.user.has_perm('programmes.see_all_roles'):
self.exclude = ['person']
else:
self.exclude = []
formset = super(NonStaffRoleInline, self).get_formset(request, obj, **kwargs)
formset.person = request.user
return formset
[docs] def get_queryset(self, request):
qs = super(NonStaffRoleInline, self).get_queryset(request).select_related('programme', 'person')
if not request.user.has_perm('programmes.see_all_roles'):
qs = qs.filter(person=request.user)
return qs
[docs]class NonStaffProgrammeAdmin(admin.ModelAdmin):
list_display = ('name', '_runtime', 'current_season', 'category', 'start_date', 'end_date')
search_fields = ['name']
list_filter = ['_runtime', 'category']
inlines = [NonStaffRoleInline]
[docs] def get_prepopulated_fields(self, request, obj=None):
if request.user.has_perm('programmes.add_programme'):
self.prepopulated_fields = {"slug": ("name",)} # FIXME: DJANGO BUG?
return self.prepopulated_fields
return {}
[docs] def get_fieldsets(self, request, obj=None):
if request.user.has_perm('programmes.add_programme'):
return (
(None, {
'fields': ('name', 'slug', 'synopsis', 'category', 'current_season', 'photo', 'language', '_runtime')
}),
(_('Advanced options'), {
'fields': ('start_date', 'end_date'),
}),
)
else:
return (
(None, {
'fields': ('name', 'synopsis', 'category', 'current_season', 'photo', 'language')
}),
)
[docs] def save_formset(self, request, form, formset, change):
instances = formset.save(commit=False)
for instance in instances:
# if no person field is displayed
if not instance.pk and not request.user.has_perm('programmes.see_all_roles'):
instance.person = request.user
instance.save()
formset.save_m2m()
[docs] def get_queryset(self, request):
qs = super(NonStaffProgrammeAdmin, self).get_queryset(request)
if not request.user.has_perm('programmes.see_all_programmes'):
qs = qs.filter(announcers__in=[request.user]).distinct()
return qs
# EPISODE
[docs]class NonStaffParticipantInlineForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
if 'instance' in kwargs:
self.instance = kwargs['instance']
if 'person_object' in kwargs:
self.person = kwargs.pop('person_object')
super(NonStaffParticipantInlineForm, self).__init__(*args, **kwargs)
[docs] def clean(self):
if 'person' in self.cleaned_data:
person = self.cleaned_data['person']
else:
person = self.person
role = self.cleaned_data['role']
episode = self.cleaned_data['episode']
qs = Participant.objects.filter(role=role, episode=episode, person=person)
if self.instance.id:
qs = qs.exclude(pk=self.instance.id)
if qs.count() > 0:
raise ValidationError(_('This user has already a role in this episode.'))
return super(NonStaffParticipantInlineForm, self).clean()
[docs]class NonStaffParticipantInlineFormset(forms.models.BaseInlineFormSet):
def _construct_form(self, i, **kwargs):
kwargs['person_object'] = self.person
return super(NonStaffParticipantInlineFormset, self)._construct_form(i, **kwargs)
[docs]class NonStaffParticipantInline(admin.StackedInline):
model = Participant
extra = 0
form = NonStaffParticipantInlineForm
formset = NonStaffParticipantInlineFormset
[docs] def get_formset(self, request, obj=None, **kwargs):
kwargs['fields'] = ['person', 'role', 'description']
if not request.user.has_perm('programmes.see_all_participants'):
self.exclude = ['person']
else:
self.exclude = []
formset = super(NonStaffParticipantInline, self).get_formset(request, obj, **kwargs)
formset.person = request.user
return formset
[docs] def get_queryset(self, request):
qs = super(NonStaffParticipantInline, self).get_queryset(request).select_related('episode__programme', 'person')
if not request.user.has_perm('programmes.see_all_participants'):
qs = qs.filter(person=request.user)
return qs
[docs]class NonStaffEpisodeAdminForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(NonStaffEpisodeAdminForm, self).__init__(*args, **kwargs)
[docs] def clean_programme(self):
programme = self.cleaned_data['programme']
now = timezone.now()
if not self.instance.pk:
last_episode = Episode.objects.last(programme)
if last_episode:
if last_episode.issue_date:
after = last_episode.issue_date + programme.runtime
if after < now:
after = now
else:
raise forms.ValidationError(_('There are no available schedules.'))
else:
after = now
try:
next_dates(Calendar.get_active(), programme, after).next()
except StopIteration:
raise forms.ValidationError(_('There are no available schedules.'))
return programme
[docs]class OwnEpisodeProgrammeListFilter(admin.SimpleListFilter):
'''
Check people in programmes besides episodes, better performance
'''
title = _('programmes')
parameter_name = 'programme'
[docs] def lookups(self, request, model_admin):
if request.user.is_superuser:
return [(programme.id, programme.name) for programme in Programme.objects.all()]
return [(programme.id, programme.name) for programme in Programme.objects.filter(announcers__in=[request.user]).distinct()]
[docs] def queryset(self, request, queryset):
if self.value():
return queryset.filter(programme__id=self.value())
else:
return queryset
[docs]class OwnEpisodeIssueDateListFilter(admin.SimpleListFilter):
title = _('issue date')
parameter_name = 'date'
[docs] def lookups(self, request, model_admin):
return (
('next', _('Next episodes')),
('untilnow', _('Until now')),
('lastweek', _('Last week')),
('twoweeks', _('Since two weeks ago')),
)
[docs] def queryset(self, request, queryset):
now = timezone.now()
if self.value() == 'next':
return queryset.filter(issue_date__gte=now) | queryset.filter(issue_date__isnull=True)
elif self.value() == 'lastweek':
return queryset.filter(issue_date__gte=(now - relativedelta(days=7)), issue_date__lte=now)
elif self.value() == 'twoweeks':
return queryset.filter(issue_date__gte=(now - relativedelta(days=14)), issue_date__lte=now)
elif self.value() == 'untilnow':
return queryset.filter(issue_date__lte=now)
else:
return queryset
[docs]class PodcastInline(admin.StackedInline):
inline_classes = ('grp-collapse grp-open',)
extra = 0
model = Podcast
[docs]class NonStaffEpisodeAdmin(admin.ModelAdmin):
list_display = ('__unicode__', 'season', 'number_in_season', 'issue_date', 'programme')
list_select_related = True
ordering = ['-season', '-number_in_season']
list_filter = ['issue_date', OwnEpisodeProgrammeListFilter, OwnEpisodeIssueDateListFilter]
search_fields = ['programme__name']
inlines = [NonStaffParticipantInline, PodcastInline]
fields = ['programme', 'title', 'summary', 'issue_date', 'season', 'number_in_season']
form = NonStaffEpisodeAdminForm
[docs] def save_model(self, request, obj, form, change):
if not obj.pk:
programme = obj.programme
last_episode = Episode.objects.last(programme)
now = timezone.now()
if last_episode:
after = last_episode.issue_date + programme.runtime
if after < now:
after = now
else:
after = now
date = next_dates(Calendar.get_active(), programme, after).next()
Episode.objects.create_episode(
episode=obj, last_episode=last_episode,
date=date, programme=programme)
else:
obj.save()
[docs] def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
field = super(NonStaffEpisodeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
if db_field.name == 'programme':
if request and not request.user.has_perm('programmes.see_all_episodes'):
field.queryset = field.queryset.filter(announcers__in=[request.user]).distinct()
return field
[docs] def get_readonly_fields(self, request, obj=None):
if obj:
return ['programme', 'issue_date', 'season', 'number_in_season']
else:
return ['issue_date', 'season', 'number_in_season']
[docs] def save_formset(self, request, form, formset, change):
# if formset.model != InlineModel:
# return super(NonStaffProgrammeAdmin, self).save_formset(request, form, formset, change)
instances = formset.save(commit=False)
for instance in instances:
if not instance.pk and not request.user.has_perm('programmes.see_all_participants'):
instance.person = request.user
instance.save()
formset.save_m2m()
[docs] def get_queryset(self, request):
qs = super(NonStaffEpisodeAdmin, self).get_queryset(request)
if not request.user.has_perm('programmes.see_all_episodes'):
qs = qs.filter(people__in=[request.user]).distinct()
return qs
admin.site.register(Programme, NonStaffProgrammeAdmin)
admin.site.register(Episode, NonStaffEpisodeAdmin)