views.py 6.69 KB
Newer Older
fred's avatar
fred committed
1
import csv
fred's avatar
fred committed
2
import datetime
fred's avatar
fred committed
3
from cStringIO import StringIO
fred's avatar
fred committed
4
import os
fred's avatar
fred committed
5

fred's avatar
fred committed
6 7 8
import mutagen

from django.core.files.storage import default_storage
fred's avatar
fred committed
9
from django.core.urlresolvers import reverse
fred's avatar
fred committed
10
from django.contrib import messages
fred's avatar
fred committed
11
from django.http import HttpResponse
fred's avatar
fred committed
12
from django.utils.translation import ugettext_lazy as _
fred's avatar
fred committed
13
from django.views.generic.base import RedirectView, TemplateView
fred's avatar
fred committed
14
from django.views.generic.dates import DayArchiveView
fred's avatar
fred committed
15
from django.views.generic.detail import DetailView
fred's avatar
fred committed
16
from django.views.generic.edit import FormView
fred's avatar
fred committed
17
from django.views.generic.list import ListView
fred's avatar
fred committed
18

fred's avatar
fred committed
19 20
from .forms import UploadTracksForm
from .models import SomaLogLine, Track, Artist, NonstopFile
fred's avatar
fred committed
21
from emissions.models import Nonstop
fred's avatar
fred committed
22 23 24 25 26 27

class SomaDayArchiveView(DayArchiveView):
    queryset = SomaLogLine.objects.all()
    date_field = "play_timestamp"
    make_object_list = True
    allow_future = False
fred's avatar
fred committed
28 29 30
    month_format = '%m'


fred's avatar
fred committed
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
class SomaDayArchiveCsvView(SomaDayArchiveView):
    def render_to_response(self, context, **response_kwargs):
        out = StringIO()
        writer = csv.writer(out)
        for line in context['object_list']:
            if line.filepath.track:
                writer.writerow([line.play_timestamp.strftime('%Y-%m-%d %H:%M'),
                    line.filepath.short.encode('utf-8', 'replace'),
                    line.filepath.track.title.encode('utf-8', 'replace'),
                    line.filepath.track.artist.name.encode('utf-8', 'replace'),
                    line.filepath.track.language,
                    line.filepath.track.instru and 'instru' or '',
                    line.filepath.track.cfwb and 'cfwb' or ''])
            else:
                writer.writerow([line.play_timestamp.strftime('%Y-%m-%d %H:%M'),
                                line.filepath.short.encode('utf-8', 'replace')])
47
        return HttpResponse(out.getvalue(), content_type='text/csv; charset=utf-8')
fred's avatar
fred committed
48 49


fred's avatar
fred committed
50 51 52 53 54 55 56
class RedirectTodayView(RedirectView):
    def get_redirect_url(self, *args, **kwargs):
        today = datetime.datetime.today()
        return reverse('archive_day', kwargs={
                        'year': today.year,
                        'month': today.month,
                        'day': today.day})
fred's avatar
fred committed
57 58 59 60


class TrackDetailView(DetailView):
    model = Track
fred's avatar
fred committed
61 62 63 64


class ArtistDetailView(DetailView):
    model = Artist
fred's avatar
fred committed
65 66 67 68


class ArtistListView(ListView):
    model = Artist
fred's avatar
fred committed
69 70 71


class ZoneStats(object):
72
    def __init__(self, zone, from_date=None, until_date=None, **kwargs):
fred's avatar
fred committed
73
        self.zone = zone
74 75 76 77 78 79 80
        self.qs = Track.objects.filter(nonstop_zones=self.zone, **kwargs)
        self.from_date = from_date
        if from_date:
            self.qs = self.qs.filter(nonstopfile__somalogline__play_timestamp__gte=from_date)
        if until_date:
            self.qs = self.qs.filter(nonstopfile__somalogline__play_timestamp__lte=until_date)
        self.qs = self.qs.distinct()
fred's avatar
fred committed
81 82

    def count(self, **kwargs):
83
        return self.qs.filter(**kwargs).count()
fred's avatar
fred committed
84 85 86 87 88

    def percentage(self, **kwargs):
        total = self.count()
        if total == 0:
            return '-'
fred's avatar
fred committed
89
        return '%.2f%%' % (100. * self.count(**kwargs) / total)
fred's avatar
fred committed
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108

    def instru(self):
        return self.count(instru=True)

    def instru_percentage(self):
        return self.percentage(instru=True)

    def sabam(self):
        return self.count(sabam=True)

    def sabam_percentage(self):
        return self.percentage(sabam=True)

    def cfwb(self):
        return self.count(cfwb=True)

    def cfwb_percentage(self):
        return self.percentage(cfwb=True)

fred's avatar
fred committed
109 110 111 112 113 114 115
    def french(self):
        return self.count(language='fr')

    def french_percentage(self):
        considered_tracks = self.count() - self.instru()
        if considered_tracks == 0:
            return '-'
fred's avatar
fred committed
116
        return '%.2f%%' % (100. * self.french() / considered_tracks)
fred's avatar
fred committed
117

118 119 120 121 122 123 124 125 126 127 128 129
    def new_files(self):
        return self.count(nonstopfile__creation_timestamp__gte=self.from_date)

    def percent_new_files(self):
        return self.percentage(nonstopfile__creation_timestamp__gte=self.from_date)


def parse_date(date):
    if date.endswith('d'):
        return datetime.datetime.today() + datetime.timedelta(int(date.rstrip('d')))
    return datetime.datetime.strptime(date, '%Y-%m-%d').date()

fred's avatar
fred committed
130 131 132 133 134 135
class StatisticsView(TemplateView):
    template_name = 'nonstop/statistics.html'

    def get_context_data(self, **kwargs):
        context = super(StatisticsView, self).get_context_data(**kwargs)
        context['zones'] = Nonstop.objects.all().order_by('start')
136 137 138 139 140 141 142 143
        kwargs = {}
        if 'from' in self.request.GET:
            kwargs['from_date'] = parse_date(self.request.GET['from'])
            context['from_date'] = kwargs['from_date']
        if 'until' in self.request.GET:
            kwargs['until_date'] = parse_date(self.request.GET['until'])
        if 'onair' in self.request.GET:
            kwargs['nonstopfile__somalogline__on_air'] = True
fred's avatar
fred committed
144
        for zone in context['zones']:
145
            zone.stats = ZoneStats(zone, **kwargs)
fred's avatar
fred committed
146
        return context
fred's avatar
fred committed
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189


class UploadTracksView(FormView):
    form_class = UploadTracksForm
    template_name = 'nonstop/upload.html'
    success_url = '.'

    def post(self, request, *args, **kwargs):
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        tracks = request.FILES.getlist('tracks')
        if not form.is_valid():
            return self.form_invalid(form)
        missing_metadata = []
        metadatas = {}
        for f in tracks:
            metadata = mutagen.File(f, easy=True)
            f.seek(0)
            if not metadata or not metadata.get('artist') or not metadata.get('title'):
                missing_metadata.append(f.name)
            else:
                metadatas[f.name] = metadata
        if missing_metadata:
            form.add_error('tracks', _('Missing metadata in: ') + ', '.join(missing_metadata))
            return self.form_invalid(form)

        for f in tracks:
            monthdir = datetime.datetime.today().strftime('%Y-%m')
            filepath = '%s/%s' % (monthdir, f.name)
            default_storage.save(os.path.join('nonstop', 'tracks', filepath), content=f)
            nonstop_file = NonstopFile()
            nonstop_file.set_track_filepath(filepath)
            metadata = metadatas[f.name]
            artist, created = Artist.objects.get_or_create(name=metadata.get('artist')[0])
            track, created = Track.objects.get_or_create(title=metadata.get('title')[0], artist=artist)
            nonstop_file.track = track
            nonstop_file.save()
            if request.POST.get('nonstop_zone'):
                track.nonstop_zones.add(
                        Nonstop.objects.get(id=request.POST.get('nonstop_zone')))

        messages.info(self.request, '%d new track(s)' % len(tracks))
        return self.form_valid(form)