import os import json import datetime from django.db.models import Count from django.views.generic.base import View, TemplateResponseMixin from django.contrib.auth.mixins import LoginRequiredMixin from django.http import HttpResponse, Http404 from django.shortcuts import render from django.utils.translation import ugettext as _, ugettext_lazy from django.utils import timezone as tz import aircox.models as models import aircox.settings as settings class Stations: stations = models.Station.objects.all() update_timeout = None fetch_timeout = None def fetch(self): if self.fetch_timeout and self.fetch_timeout > tz.now(): return self.fetch_timeout = tz.now() + tz.timedelta(seconds = 5) for station in self.stations: station.streamer.fetch() stations = Stations() def on_air(request): try: import aircox_cms.models as cms except: cms = None station = request.GET.get('station'); if station: station = stations.stations.filter(name = station) if not station.count(): return HttpResponse('') else: station = stations.stations station = station.first() on_air = station.on_air(count = 10).select_related('track','diffusion') if not on_air.count(): return HttpResponse('') last = on_air.first() if last.track: last = { 'type': 'track', 'artist': last.related.artist, 'title': last.related.title, 'date': last.date, } else: try: diff = last.diffusion publication = None if cms: publication = \ cms.DiffusionPage.objects.filter( diffusion = diff.initial or diff).first() or \ cms.ProgramPage.objects.filter( program = last.program).first() except: pass last = { 'type': 'diffusion', 'title': diff.program.name, 'date': diff.start, 'url': publication.specific.url if publication else None, } last['date'] = str(last['date']) return HttpResponse(json.dumps(last)) # TODO: # - login url class Monitor(View,TemplateResponseMixin,LoginRequiredMixin): template_name = 'aircox/controllers/monitor.html' def get_context_data(self, **kwargs): stations.fetch() return { 'stations': stations.stations } def get(self, request = None, **kwargs): if not request.user.is_active: return Http404() self.request = request context = self.get_context_data(**kwargs) return render(request, self.template_name, context) def post(self, request = None, **kwargs): if not request.user.is_active: return Http404() if not ('action' or 'station') in request.POST: return HttpResponse('') POST = request.POST controller = POST.get('controller') action = POST.get('action') station = stations.stations.filter(name = POST.get('station')) \ .first() if not station: return Http404() source = None if 'source' in POST: source = [ s for s in station.sources if s.name == POST['source'] ] source = source[0] if not source: return Http404 station.streamer.fetch() source = source or station.streamer.current_source if action == 'skip': self.actionSkip(request, station, source) if action == 'restart': self.actionRestart(request, station, source) return HttpResponse('') def actionSkip(self, request, station, source): source.skip() def actionRestart(self, request, station, source): source.restart() class StatisticsView(View,TemplateResponseMixin,LoginRequiredMixin): """ View for statistics. """ # we cannot manipulate queryset, since we have to be able to read from archives template_name = 'aircox/controllers/stats.html' class Item: date = None end = None name = None related = None tracks = None tags = None col = None def __init__(self, **kwargs): self.__dict__.update(kwargs) class Stats: station = None date = None items = None """ Log or Diffusion object that has been diffused by date. These objects have extra fields: - tags: [ (tag_name, tag_count), ...] - tracks_count: total count of tracks """ count = 0 #rows = None def __init__(self, **kwargs): self.items = [] # self.rows = [] self.__dict__.update(kwargs) # Note: one row contains a column for diffusions and one for streams #def append(self, log): # if log.col == 0: # self.rows.append((log, [])) # return # # if self.rows: # row = self.rows[len(self.rows)-1] # last = row[0] or row[1][len(row[1])-1] # if last.date < log.date < last.end: # row[1].append(log) # return # # # all other cases: new row # self.rows.append((None, [log])) def get_stats(self, station, date): """ Return statistics for the given station and date. """ stats = self.Stats(station = station, date = date, items = [], tags = {}) qs = station.raw_on_air(date = date) \ .prefetch_related('diffusion', 'sound', 'track', 'track__tags') if not qs.exists(): qs = models.Log.objects.load_archive(station, date) sound_log = None for log in qs: rel = None item = None if log.diffusion: rel = log.diffusion item = self.Item( name = rel.program.name, type = _('Diffusion'), col = 0, tracks = models.Track.objects.get_for(object = rel) .prefetch_related('tags'), ) sound_log = None elif log.sound: rel = log.sound item = self.Item( name = rel.program.name + ': ' + os.path.basename(rel.path), type = _('Stream'), col = 1, tracks = [], ) sound_log = item elif log.track: # append to last sound log if not sound_log: # TODO: create item ? should never happen continue sound_log.tracks.append(log.track) sound_log.end = log.end sound_log continue item.date = log.date item.end = log.end item.related = rel # stats.append(item) stats.items.append(item) return stats def get_context_data(self, **kwargs): context = {} date = datetime.date.today() try: GET = self.request.GET year = int(GET["year"]) if 'year' in GET else date.year month = int(GET["month"]) if 'month' in GET else date.month day = int(GET["day"]) if 'day' in GET else date.day date = datetime.date(year, month, day) except: pass context["statistics"] = [ self.get_stats(station, date) for station in models.Station.objects.all() ] return context def get(self, request = None, **kwargs): if not request.user.is_active: return Http404() self.request = request context = self.get_context_data(**kwargs) return render(request, self.template_name, context)