utils.py 6.14 KB
Newer Older
fred's avatar
fred committed
1
from datetime import datetime, timedelta, time
fred's avatar
fred committed
2
import os
3
4
5
from PIL import Image

def maybe_resize(image_path):
fred's avatar
fred committed
6
7
    if not os.path.exists(image_path):
        return
8
9
10
11
12
13
14
15
16
17
    image = Image.open(image_path)
    if max(image.size) > 1000:
        # no sense storing images that large
        factor = 1000. / max(image.size)
        image = image.resize(
                (int(image.size[0]*factor), int(image.size[1]*factor)),
                Image.ANTIALIAS)
        image.save(image_path)


18
def whatsonair():
fred's avatar
fred committed
19
    from models import Diffusion, Schedule, Nonstop
20
21

    now = datetime.now()
22
23
    program = day_program(now)
    program = [x for x in program if not x.datetime > now]
24
25

    emission = None
26
    episode = None
fred's avatar
fred committed
27
    nonstop = None
28
29
30
31
32
33
34
35
    current_slot = None
    if program and program[-1].datetime + timedelta(minutes=program[-1].get_duration()) > now:
        current_slot = program[-1]
        if isinstance(current_slot, Schedule):
            emission = current_slot.emission
        elif isinstance(current_slot, Diffusion):
            episode = current_slot.episode
            emission = episode.emission
36
    else:
fred's avatar
fred committed
37
38
39
40
41
42
43
44
45
        for nonstop in Nonstop.objects.all():
            if (nonstop.start < nonstop.end and (
                    now.time() >= nonstop.start and now.time() < nonstop.end)) or \
               (nonstop.start > nonstop.end and (
                    now.time() >= nonstop.start or now.time() < nonstop.end)):
                current_slot = nonstop
                break
        else:
            nonstop = None
46
47

    return {'emission': emission,
48
            'episode': episode,
fred's avatar
fred committed
49
            'nonstop': nonstop,
50
            'current_slot': current_slot}
51
52


53
def period_program(date_start, date_end):
fred's avatar
fred committed
54
    from models import Diffusion, Schedule, Nonstop, WeekdayMixin
55

56
    diffusions = Diffusion.objects.select_related().filter(
57
58
59
60
            datetime__range=(date_start, date_end)).order_by('datetime')
    diffusions = [x for x in diffusions if x.datetime >= date_start and
                    x.datetime < date_end]

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    # the secondary sortkey puts schedules that happens everyweek after
    # specific ones, this will be useful later on, when multiple schedules
    # happen at the same time and we have to remove the least specific.
    period_schedules = Schedule.objects.select_related().order_by('datetime', 'weeks')

    program = []
    current_date = date_start
    while current_date < date_end:
        week_day = current_date.weekday()
        week_no = ((current_date.day-1) // 7)
        day_schedules = [x for x in period_schedules if x.get_weekday() == week_day and x.match_week(week_no)]
        for schedule in day_schedules:
            schedule.datetime = datetime(
                    current_date.year, current_date.month, current_date.day,
                    schedule.datetime.hour, schedule.datetime.minute) + \
                            timedelta(days=schedule.datetime.weekday()-current_date.weekday())
        program.extend(day_schedules)
        current_date += timedelta(days=1)
79
80
81
82

    for i, schedule in enumerate(program):
        if schedule is None:
            continue
83

84
        # look for a diffusion matching this schedule
85
        d = [x for x in diffusions if x.datetime.timetuple()[:5] == schedule.datetime.timetuple()[:5]]
86
87
88
        if d:
            program[i] = d[0]
            for j, other_schedule in enumerate(program[i+1:]):
89
                if other_schedule.datetime.timetuple()[:5] == schedule.datetime.timetuple()[:5]:
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
                    program[i+1+j] = None
                else:
                    break

    program = [x for x in program if x is not None]
    for i, slot in enumerate(program):
        if slot is None:
            continue

        slot_end = slot.datetime + timedelta(minutes=slot.get_duration())

        j = i+1
        while j < len(program)-1:
            if program[j]:
                if slot_end > program[j].datetime:
                    program[j] = None
            j += 1

fred's avatar
fred committed
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    program = [x for x in program if x is not None]

    # last step is adding nonstop zones between slots
    nonstops = Nonstop.objects.all()

    class NonstopSlot(WeekdayMixin):
        def __init__(self, start, end):
            self.datetime = None
            labels = []
            for nonstop in nonstops:
                nonstop_day_start = start.replace(hour=nonstop.start.hour, minute=nonstop.start.minute)
                nonstop_day_end = start.replace(hour=nonstop.end.hour, minute=nonstop.end.minute)
                if nonstop.end < nonstop.start:
                    if start.time() < nonstop.end:
                        nonstop_day_start -= timedelta(days=1)
                    else:
                        nonstop_day_end += timedelta(days=1)

                if nonstop_day_start < end and nonstop_day_end > start:
                    if self.datetime is None:
                        self.datetime = nonstop_day_end
                    labels.append(nonstop.title)
            self.label = u', '.join(labels)

        def __repr__(self):
            return repr(self.label)


    first_day_start = datetime(*date_start.replace(hour=6, minute=0).timetuple()[:5])
    last_day_end = datetime(*date_end.replace(hour=5, minute=0).timetuple()[:5])

    program.insert(0, NonstopSlot(first_day_start, program[0].datetime))

    i = 0
    while i < len(program)-1:
        slot = program[i]
        if not isinstance(slot, NonstopSlot):
            slot_end = slot.datetime + timedelta(minutes=slot.get_duration())
            next_slot = program[i+1]

            if slot_end < next_slot.datetime:
                next_day_start = next_slot.datetime.replace(hour=5, minute=0)
                if slot_end < next_day_start and next_slot.datetime > next_day_start:
                    program[i+1:i+1] = [NonstopSlot(slot_end, next_day_start),
                            NonstopSlot(next_day_start, next_slot.datetime)]
                else:
                    program[i+1:i+1] = [NonstopSlot(slot_end, next_slot.datetime)]

        i += 1

    program.append(NonstopSlot(program[-1].datetime, last_day_end))

    return program
161
162
163
164
165

def day_program(date):
    date_start = datetime(*date.timetuple()[:3])
    date_end = date_start + timedelta(days=1)
    return period_program(date_start, date_end)