add a rerun field to diffusion; fix minor bug that can happen on new year's eve
This commit is contained in:
		@ -5,7 +5,6 @@ from django.contrib import admin
 | 
			
		||||
from django.db import models
 | 
			
		||||
 | 
			
		||||
from suit.admin import SortableTabularInline, SortableModelAdmin
 | 
			
		||||
from autocomplete_light.contrib.taggit_field import TaggitWidget, TaggitField
 | 
			
		||||
 | 
			
		||||
from aircox_programs.forms import *
 | 
			
		||||
from aircox_programs.models import *
 | 
			
		||||
@ -73,7 +72,7 @@ class StationAdmin (NameableAdmin):
 | 
			
		||||
 | 
			
		||||
@admin.register(Program)
 | 
			
		||||
class ProgramAdmin (NameableAdmin):
 | 
			
		||||
    fields = NameableAdmin.fields + [ 'stations', 'active' ]
 | 
			
		||||
    fields = NameableAdmin.fields + [ 'station', 'active' ]
 | 
			
		||||
    inlines = [ ScheduleInline, StreamInline ]
 | 
			
		||||
 | 
			
		||||
    def get_form (self, request, obj=None, **kwargs):
 | 
			
		||||
@ -101,13 +100,14 @@ class DiffusionAdmin (admin.ModelAdmin):
 | 
			
		||||
                        if sound.type == Sound.Type['archive'] )
 | 
			
		||||
        return ', '.join(sounds) if sounds else ''
 | 
			
		||||
 | 
			
		||||
    list_display = ('id', 'type', 'date', 'archives', 'episode', 'program')
 | 
			
		||||
    list_display = ('id', 'type', 'date', 'archives', 'episode', 'program', 'rerun')
 | 
			
		||||
    list_filter = ('type', 'date', 'program')
 | 
			
		||||
    list_editable = ('type', 'date')
 | 
			
		||||
 | 
			
		||||
    def get_queryset(self, request):
 | 
			
		||||
        qs = super(DiffusionAdmin, self).get_queryset(request)
 | 
			
		||||
        if 'type__exact' in request.GET and \
 | 
			
		||||
        if '_changelist_filters' in request.GET or \
 | 
			
		||||
            'type__exact' in request.GET and \
 | 
			
		||||
                str(Diffusion.Type['unconfirmed']) in request.GET['type__exact']:
 | 
			
		||||
            return qs
 | 
			
		||||
        return qs.exclude(type = Diffusion.Type['unconfirmed'])
 | 
			
		||||
 | 
			
		||||
@ -23,16 +23,20 @@ from aircox_programs.models import *
 | 
			
		||||
class Actions:
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def update (date):
 | 
			
		||||
        items = []
 | 
			
		||||
        for schedule in Schedule.objects.filter(program__active = True):
 | 
			
		||||
            items += schedule.diffusions_of_month(date, exclude_saved = True)
 | 
			
		||||
        count = 0
 | 
			
		||||
        for schedule in Schedule.objects.filter(program__active = True) \
 | 
			
		||||
                .order_by('rerun'):
 | 
			
		||||
            # in order to allow rerun links between diffusions, we save items
 | 
			
		||||
            # by schedule;
 | 
			
		||||
            items = schedule.diffusions_of_month(date, exclude_saved = True)
 | 
			
		||||
            count += len(items)
 | 
			
		||||
            Diffusion.objects.bulk_create(items)
 | 
			
		||||
            print('> {} new diffusions for schedule #{} ({})'.format(
 | 
			
		||||
                    len(items), schedule.id, str(schedule)
 | 
			
		||||
                 ))
 | 
			
		||||
 | 
			
		||||
        print('total of {} diffusions will be created. To be used, they need '
 | 
			
		||||
              'manual approval.'.format(len(items)))
 | 
			
		||||
        Diffusion.objects.bulk_create(items)
 | 
			
		||||
        print('total of {} diffusions have been created. They need a '
 | 
			
		||||
              'manual approval.'.format(count))
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def clean (date):
 | 
			
		||||
 | 
			
		||||
@ -30,6 +30,10 @@ class Nameable (models.Model):
 | 
			
		||||
        max_length = 128,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def slug (self):
 | 
			
		||||
        return self.get_slug_name()
 | 
			
		||||
 | 
			
		||||
    def get_slug_name (self):
 | 
			
		||||
        return slugify(self.name).replace('-', '_')
 | 
			
		||||
 | 
			
		||||
@ -305,8 +309,8 @@ class Schedule (models.Model):
 | 
			
		||||
        Return a list with all matching dates of date.month (=today)
 | 
			
		||||
        """
 | 
			
		||||
        date = date_or_default(date, True).replace(day=1)
 | 
			
		||||
        wday = self.date.weekday()
 | 
			
		||||
        fwday = date.weekday()
 | 
			
		||||
        wday = self.date.weekday()
 | 
			
		||||
 | 
			
		||||
        # move date to the date weekday of the schedule
 | 
			
		||||
        # check on SO#3284452 for the formula
 | 
			
		||||
@ -322,8 +326,14 @@ class Schedule (models.Model):
 | 
			
		||||
            # if both week are the same, then the date week of the month
 | 
			
		||||
            # matches. Note: wday % 2 + fwday % 2 => (wday + fwday) % 2
 | 
			
		||||
            fweek = date.isocalendar()[1]
 | 
			
		||||
 | 
			
		||||
            if date.month == 1 and fweek >= 50:
 | 
			
		||||
                # isocalendar can think we are on the last week of the
 | 
			
		||||
                # previous year
 | 
			
		||||
                fweek = 0
 | 
			
		||||
            week = self.date.isocalendar()[1]
 | 
			
		||||
            weeks = 0b010101 if not (fweek + week) % 2 else 0b001010
 | 
			
		||||
            print(date, fweek, week, "{0:b}".format(weeks))
 | 
			
		||||
 | 
			
		||||
        dates = []
 | 
			
		||||
        for week in range(0,5):
 | 
			
		||||
@ -331,8 +341,10 @@ class Schedule (models.Model):
 | 
			
		||||
            if not weeks & (0b1 << week):
 | 
			
		||||
                continue
 | 
			
		||||
            wdate = date + tz.timedelta(days = week * 7)
 | 
			
		||||
            print(wdate, wdate.month == date.month)
 | 
			
		||||
            if wdate.month == date.month:
 | 
			
		||||
                dates.append(self.normalize(wdate))
 | 
			
		||||
        print(dates)
 | 
			
		||||
        return dates
 | 
			
		||||
 | 
			
		||||
    def diffusions_of_month (self, date, exclude_saved = False):
 | 
			
		||||
@ -363,15 +375,18 @@ class Schedule (models.Model):
 | 
			
		||||
            if self.rerun:
 | 
			
		||||
                first_date -= self.date - self.rerun.date
 | 
			
		||||
 | 
			
		||||
            diffusion = Diffusion.objects.filter(date = first_date,
 | 
			
		||||
                                                 program = self.program)
 | 
			
		||||
            episode = diffusion[0].episode if diffusion.count() else None
 | 
			
		||||
 | 
			
		||||
            first_diffusion = Diffusion.objects.filter(date = first_date,
 | 
			
		||||
                                                       program = self.program)
 | 
			
		||||
            first_diffusion = first_diffusion[0] if first_diffusion.count() \
 | 
			
		||||
                              else None
 | 
			
		||||
            episode = first_diffusion.episode if first_diffusion else None
 | 
			
		||||
            # print(self.rerun, episode, first_diffusion, first_date)
 | 
			
		||||
            diffusions.append(Diffusion(
 | 
			
		||||
                                 episode = episode,
 | 
			
		||||
                                 program = self.program,
 | 
			
		||||
                                 type = Diffusion.Type['unconfirmed'],
 | 
			
		||||
                                 date = date,
 | 
			
		||||
                                 rerun = first_diffusion if self.rerun else None
 | 
			
		||||
                             ))
 | 
			
		||||
        return diffusions
 | 
			
		||||
 | 
			
		||||
@ -422,10 +437,47 @@ class Diffusion (models.Model):
 | 
			
		||||
        choices = [ (y, x) for x,y in Type.items() ],
 | 
			
		||||
    )
 | 
			
		||||
    date = models.DateTimeField( _('start of the diffusion') )
 | 
			
		||||
    rerun = models.ForeignKey (
 | 
			
		||||
        'self',
 | 
			
		||||
        verbose_name = _('rerun'),
 | 
			
		||||
        blank = True, null = True,
 | 
			
		||||
        help_text = _('the diffusion is a rerun of this one. Remove this if '
 | 
			
		||||
                      'you want to change the concerned episode')
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_next (cl, station = None):
 | 
			
		||||
        """
 | 
			
		||||
        Return a queryset with the upcoming diffusions, ordered by
 | 
			
		||||
        +date
 | 
			
		||||
        """
 | 
			
		||||
        args = {
 | 
			
		||||
            'date__gte': tz.datetime.now()
 | 
			
		||||
        }
 | 
			
		||||
        if station:
 | 
			
		||||
            args['program__station'] = station
 | 
			
		||||
        return cl.objects.filter(**args).order_by('date')
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_prev (cl, station = None):
 | 
			
		||||
        """
 | 
			
		||||
        Return a queryset with the previous diffusion, ordered by
 | 
			
		||||
        -date
 | 
			
		||||
        """
 | 
			
		||||
        args = {
 | 
			
		||||
            'date__lt': tz.datetime.now()
 | 
			
		||||
        }
 | 
			
		||||
        if station:
 | 
			
		||||
            args['program__station'] = station
 | 
			
		||||
        return cl.objects.filter(**args).order_by('-date')
 | 
			
		||||
 | 
			
		||||
    def save (self, *args, **kwargs):
 | 
			
		||||
        if self.episode: # FIXME self.episode or kwargs['episode']
 | 
			
		||||
        if self.rerun:
 | 
			
		||||
            self.episode = self.rerun.episode
 | 
			
		||||
            self.program = self.episode.program
 | 
			
		||||
        elif self.episode:
 | 
			
		||||
            self.program = self.episode.program
 | 
			
		||||
 | 
			
		||||
        super(Diffusion, self).save(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def __str__ (self):
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user