lot of fixes and updates, add diffusion monitor and so on

This commit is contained in:
bkfox 2015-09-15 15:59:35 +02:00
parent c10f7a6635
commit b3663b50b2
2 changed files with 227 additions and 0 deletions

View File

@ -0,0 +1,91 @@
from django.core.management.base import BaseCommand, CommandError
from django.utils import timezone as tz
from programs.models import *
class Actions:
@staticmethod
def update (date):
items = []
for schedule in Schedule.objects.filter(parent__active = True):
items += schedule.diffusions_of_month(date, exclude_saved = True)
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)))
print(Diffusion.objects.bulk_create(items))
@staticmethod
def clean (date):
qs = Diffusion.objects.filter(type = Diffusion.Type['unconfirmed'],
date__lt = date)
print('{} diffusions will be removed'.format(qs.count()))
qs.delete()
@staticmethod
def check (date):
qs = Diffusion.objects.filter(type = Diffusion.Type['unconfirmed'],
date__gt = date)
items = []
for diffusion in qs:
schedules = Schedule.objects.filter(parent = diffusion.program)
for schedule in schedules:
if schedule.match(diffusion.date):
break
else:
print('> #{}: {}'.format(diffusion.date, str(diffusion)))
items.append(diffusion.id)
print('{} diffusions will be removed'.format(len(items)))
if len(items):
Diffusion.objects.filter(id__in = items).delete()
class Command (BaseCommand):
help= 'Monitor diffusions'
def add_arguments (self, parser):
now = tz.datetime.today()
group = parser.add_argument_group('action')
group.add_argument(
'--update', action='store_true',
help = 'generate (unconfirmed) diffusions for the given month. '
'These diffusions must be confirmed manually by changing '
'their type to "normal"')
group.add_argument(
'--clean', action='store_true',
help = 'remove unconfirmed diffusions older than the given month')
group.add_argument(
'--check', action='store_true',
help = 'check future unconfirmed diffusions from the given date '
'agains\'t schedules and remove it if that do not match any '
'schedule')
group = parser.add_argument_group(
'date',
'this information is used by the action, starting at the first (!) '
'of the given month')
group.add_argument('--year', type=int, default=now.year,
help='used by update, default is today\'s year')
group.add_argument('--month', type=int, default=now.month,
help='used by update, default is today\'s month')
def handle (self, *args, **options):
date = tz.datetime(year = options.get('year'),
month = options.get('month'),
day = 1)
date = tz.make_aware(date)
if options.get('update'):
Actions.update(date)
elif options.get('clean'):
Actions.clean(date)
elif options.get('check'):
Actions.check(date)
else:
raise CommandError('no action has been given')

View File

@ -0,0 +1,136 @@
import os
import re
from django.core.management.base import BaseCommand, CommandError
from django.utils import timezone
from programs.models import *
import programs.settings as settings
class Command (BaseCommand):
help= "Take a look at the programs directory to check on new podcasts"
def report (self, program = None, component = None, *content):
if not component:
print('{}: '.format(program), *content)
else:
print('{}, {}: '.format(program, component), *content)
def handle (self, *args, **options):
programs = Program.objects.filter()
for program in programs:
self.scan_dir(program, program.path + '/public', public = True)
self.scan_dir(program, program.path + '/podcasts', embed = True)
self.scan_dir(program, program.path + '/private')
def ensure_episode (self, program, sound):
"""
For a given program, check if there is an episode to associate to.
This makes the assumption that the name of the file has the following
format:
yyyymmdd[_n][_][title]
Where:
yyyy: is the year of the episode's diffusion
mm: is the month of the episode's diffusion
dd: is the day of the episode's diffusion
n: is the number of the episode (if multiple episodes)
We check against the diffusion rather than the episode's date, because
this is the diffusion that defines when the sound will be podcasted for
the first time.
We create the episode if it does not exists only if there is a diffusion
matching the date of the sound, in order to respect the hierarchy of
episode creation.
We dont create episode if it does not exists, because only episodes must
be created through diffusions
TODO: multiple diffusions at the same date
"""
path = os.path.basename(sound.path)
r = re.search('^(?P<year>[0-9]{4})'
'(?P<month>[0-9]{2})'
'(?P<day>[0-9]{2})'
'(_(?P<n>[0-9]+))?'
'_?(?P<name>.*)\.\w+$'
, path)
if not r:
return
r = r.groupdict()
# check on episodes
diffusion = Diffusion.objects.filter( program = program
, date__year = int(r['year'])
, date__month = int(r['month'])
, date__day = int(r['day'])
)
if not diffusion.count():
self.report(program, path, 'no diffusion found for the given date')
return
diffusion = diffusion[0]
if diffusion.episode:
return diffusion.episode
episode = Episode( parent = program
, title = r.get('name') \
.replace('_', ' ') \
.capitalize()
, date = diffusion.date
)
episode.save()
if program.tags.all():
episode.tags.add(program.tags.all())
self.report(program, path, 'episode does not exist, create')
return episode
def scan_dir (self, program, dir_path, public = False, embed = False):
"""
Scan a given directory that is associated to the given program, and
update sounds information
Return a list of scanned sounds
"""
if not os.path.exists(dir_path):
return
paths = []
for path in os.listdir(dir_path):
path = dir_path + '/' + path
if not path.endswith(settings.AIRCOX_SOUNDFILE_EXT):
continue
paths.append(path)
# check for new sound files or update
sound = Sound.objects.filter(path = path)
if sound.count():
sound = sound[0]
else:
sound = Sound(path = path)
# check for the corresponding episode:
episode = self.ensure_episode(program, sound)
if not episode:
continue
sound.save()
for sound_ in episode.sounds.get_queryset():
if sound_.path == sound.path:
continue
self.report(program, path, 'associate sound to episode '
, episode.id)
episode.sounds.add(sound)
return paths