fix stuffs, documentation
This commit is contained in:
parent
4b5f908b3d
commit
dae9545e27
|
@ -1,3 +1,20 @@
|
||||||
|
"""
|
||||||
|
Manage diffusions using schedules, to update, clean up or check diffusions.
|
||||||
|
A diffusion generated using this utility is considered has type "unconfirmed",
|
||||||
|
and is not considered as ready for diffusion; To do so, users must confirm the
|
||||||
|
diffusion case by changing it's type to "default".
|
||||||
|
|
||||||
|
Different actions are available:
|
||||||
|
- "update" is the process that is used to generated them using programs
|
||||||
|
schedules for the (given) month.
|
||||||
|
|
||||||
|
- "clean" will remove all diffusions that are still unconfirmed and have been
|
||||||
|
planified before the (given) month.
|
||||||
|
|
||||||
|
- "check" will remove all diffusions that are unconfirmed and have been planified
|
||||||
|
from the (given) month and later.
|
||||||
|
"""
|
||||||
|
from argparse import RawTextHelpFormatter
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
from django.utils import timezone as tz
|
from django.utils import timezone as tz
|
||||||
from programs.models import *
|
from programs.models import *
|
||||||
|
@ -44,9 +61,11 @@ class Actions:
|
||||||
|
|
||||||
|
|
||||||
class Command (BaseCommand):
|
class Command (BaseCommand):
|
||||||
help= 'Monitor diffusions'
|
help= __doc__
|
||||||
|
|
||||||
def add_arguments (self, parser):
|
def add_arguments (self, parser):
|
||||||
|
parser.formatter_class=RawTextHelpFormatter
|
||||||
|
|
||||||
now = tz.datetime.today()
|
now = tz.datetime.today()
|
||||||
|
|
||||||
group = parser.add_argument_group('action')
|
group = parser.add_argument_group('action')
|
||||||
|
@ -66,9 +85,7 @@ class Command (BaseCommand):
|
||||||
'schedule')
|
'schedule')
|
||||||
|
|
||||||
group = parser.add_argument_group(
|
group = parser.add_argument_group(
|
||||||
'date',
|
'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,
|
group.add_argument('--year', type=int, default=now.year,
|
||||||
help='used by update, default is today\'s year')
|
help='used by update, default is today\'s year')
|
||||||
group.add_argument('--month', type=int, default=now.month,
|
group.add_argument('--month', type=int, default=now.month,
|
||||||
|
|
|
@ -1,5 +1,22 @@
|
||||||
|
"""
|
||||||
|
Check over programs' sound files, scan them, and add them to the
|
||||||
|
database if they are not there yet.
|
||||||
|
|
||||||
|
It tries to parse the file name to get the date of the diffusion of an
|
||||||
|
episode and associate the file with it; We use 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);
|
||||||
|
'title' the title of the sound;
|
||||||
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
from argparse import RawTextHelpFormatter
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
@ -8,8 +25,7 @@ import programs.settings as settings
|
||||||
|
|
||||||
|
|
||||||
class Command (BaseCommand):
|
class Command (BaseCommand):
|
||||||
help= "Take a look at the programs directory to check on new podcasts"
|
help= __doc__
|
||||||
|
|
||||||
|
|
||||||
def report (self, program = None, component = None, *content):
|
def report (self, program = None, component = None, *content):
|
||||||
if not component:
|
if not component:
|
||||||
|
@ -17,82 +33,71 @@ class Command (BaseCommand):
|
||||||
else:
|
else:
|
||||||
print('{}, {}: '.format(program, component), *content)
|
print('{}, {}: '.format(program, component), *content)
|
||||||
|
|
||||||
|
def add_arguments (self, parser):
|
||||||
|
parser.formatter_class=RawTextHelpFormatter
|
||||||
|
|
||||||
def handle (self, *args, **options):
|
def handle (self, *args, **options):
|
||||||
programs = Program.objects.filter()
|
programs = Program.objects.filter()
|
||||||
|
|
||||||
for program in programs:
|
for program in programs:
|
||||||
self.scan_dir(program, program.path + '/public', public = True)
|
self.check(program, program.path + '/public', public = True)
|
||||||
self.scan_dir(program, program.path + '/podcasts', embed = True)
|
self.check(program, program.path + '/podcasts', embed = True)
|
||||||
self.scan_dir(program, program.path + '/private')
|
self.check(program, program.path + '/private')
|
||||||
|
|
||||||
|
def get_sound_info (self, path):
|
||||||
def ensure_episode (self, program, sound):
|
|
||||||
"""
|
"""
|
||||||
For a given program, check if there is an episode to associate to.
|
Parse file name to get info on the assumption it has the correct
|
||||||
This makes the assumption that the name of the file has the following
|
format (given in Command.help)
|
||||||
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})'
|
r = re.search('^(?P<year>[0-9]{4})'
|
||||||
'(?P<month>[0-9]{2})'
|
'(?P<month>[0-9]{2})'
|
||||||
'(?P<day>[0-9]{2})'
|
'(?P<day>[0-9]{2})'
|
||||||
'(_(?P<n>[0-9]+))?'
|
'(_(?P<n>[0-9]+))?'
|
||||||
'_?(?P<name>.*)\.\w+$'
|
'_?(?P<name>.*)\.\w+$',
|
||||||
, path)
|
os.path.basename(path))
|
||||||
|
|
||||||
if not r:
|
if not (r and r.groupdict()):
|
||||||
return
|
self.report(program, path, "file path is not correct, use defaults")
|
||||||
r = r.groupdict()
|
r = {
|
||||||
|
'name': os.path.splitext(path)
|
||||||
|
}
|
||||||
|
r['path'] = path
|
||||||
|
return r
|
||||||
|
|
||||||
|
def ensure_sound (self, sound_info):
|
||||||
|
"""
|
||||||
|
Return the Sound for the given sound_info; If not found, create it
|
||||||
|
without saving it.
|
||||||
|
"""
|
||||||
|
sound = Sound.objects.filter(path = path)
|
||||||
|
if sound:
|
||||||
|
sound = sound[0]
|
||||||
|
else:
|
||||||
|
sound = Sound(path = path, title = sound_info['name'])
|
||||||
|
|
||||||
|
def find_episode (self, program, sound_info):
|
||||||
|
"""
|
||||||
|
For a given program, and sound path check if there is an episode to
|
||||||
|
associate to, using the diffusion's date.
|
||||||
|
|
||||||
|
If there is no matching episode, return None.
|
||||||
|
"""
|
||||||
# check on episodes
|
# check on episodes
|
||||||
diffusion = Diffusion.objects.filter( program = program
|
diffusion = Diffusion.objects.filter(
|
||||||
, date__year = int(r['year'])
|
program = program,
|
||||||
, date__month = int(r['month'])
|
date__year = int(sound_info['year']),
|
||||||
, date__day = int(r['day'])
|
date__month = int(sound_info['month']),
|
||||||
|
date__day = int(sound_info['day'])
|
||||||
)
|
)
|
||||||
|
|
||||||
if not diffusion.count():
|
if not diffusion.count():
|
||||||
self.report(program, path, 'no diffusion found for the given date')
|
self.report(program, path, 'no diffusion found for the given date')
|
||||||
return
|
return
|
||||||
|
|
||||||
diffusion = diffusion[0]
|
diffusion = diffusion[0]
|
||||||
if diffusion.episode:
|
return diffusion.episode or None
|
||||||
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):
|
def check (self, program, dir_path, public = False, embed = False):
|
||||||
"""
|
"""
|
||||||
Scan a given directory that is associated to the given program, and
|
Scan a given directory that is associated to the given program, and
|
||||||
update sounds information
|
update sounds information
|
||||||
|
@ -110,27 +115,22 @@ class Command (BaseCommand):
|
||||||
|
|
||||||
paths.append(path)
|
paths.append(path)
|
||||||
|
|
||||||
# check for new sound files or update
|
sound_info = self.get_sound_info(path)
|
||||||
sound = Sound.objects.filter(path = path)
|
sound = self.ensure_sound(sound_info)
|
||||||
if sound.count():
|
|
||||||
sound = sound[0]
|
|
||||||
else:
|
|
||||||
sound = Sound(path = path)
|
|
||||||
|
|
||||||
# check for the corresponding episode:
|
sound.public = public
|
||||||
episode = self.ensure_episode(program, sound)
|
|
||||||
if not episode:
|
|
||||||
continue
|
|
||||||
|
|
||||||
sound.save()
|
|
||||||
|
|
||||||
|
# episode and relation
|
||||||
|
if 'year' in sound_info:
|
||||||
|
episode = self.find_episode(program, sound_info)
|
||||||
|
if episode:
|
||||||
for sound_ in episode.sounds.get_queryset():
|
for sound_ in episode.sounds.get_queryset():
|
||||||
if sound_.path == sound.path:
|
if sound_.path == sound.path:
|
||||||
continue
|
break
|
||||||
|
else:
|
||||||
self.report(program, path, 'associate sound to episode '
|
self.report(program, path, 'associate sound to episode ',
|
||||||
, episode.id)
|
episode.id)
|
||||||
episode.sounds.add(sound)
|
episode.sounds.add(sound)
|
||||||
|
|
||||||
return paths
|
return paths
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user