diff --git a/programs/admin.py b/programs/admin.py index 441924b..1a24de2 100755 --- a/programs/admin.py +++ b/programs/admin.py @@ -54,15 +54,15 @@ class MetadataAdmin (admin.ModelAdmin): class PublicationAdmin (MetadataAdmin): fieldsets = copy.deepcopy(MetadataAdmin.fieldsets) - list_display = ('id', 'title', 'date', 'status') - list_filter = ['date', 'status'] + list_display = ('id', 'title', 'date', 'public') + list_filter = ['date', 'public'] search_fields = ['title', 'content'] def __init__ (self, *args, **kwargs): self.fieldsets[0][1]['fields'].insert(1, 'subtitle') self.fieldsets[0][1]['fields'] += [ 'img', 'content' ] - self.fieldsets[1][1]['fields'] += [ 'parent', 'status', 'enable_comments', 'meta' ], + self.fieldsets[1][1]['fields'] += [ 'parent', 'public', 'can_comment', 'meta' ], return super(PublicationAdmin, self).__init__(*args, **kwargs) diff --git a/programs/management/commands/monitor.py b/programs/management/commands/monitor.py index 5ea6464..60ed99c 100644 --- a/programs/management/commands/monitor.py +++ b/programs/management/commands/monitor.py @@ -4,13 +4,12 @@ from django.core.management.base import BaseCommand, CommandError import programs.models as models import programs.settings -class Command(BaseCommand): + +class Command (BaseCommand): help= "Take a look at the programs directory to check on new podcasts" - - - def handle(self, *args, **options): + def handle (self, *args, **options): programs = models.Program.objects.filter(schedule__isnull = True) for program in programs: @@ -24,6 +23,10 @@ class Command(BaseCommand): for filename in os.listdir(path): long_filename = path + '/' + filename + # check for new sound files + # stat the sound files + # match sound files against episodes - if not found, create it + # upload public podcasts to mixcloud if required except: pass diff --git a/programs/management/commands/schedule.py b/programs/management/commands/schedule.py new file mode 100644 index 0000000..81f374a --- /dev/null +++ b/programs/management/commands/schedule.py @@ -0,0 +1,72 @@ +import datetime + +from django.core.management.base import BaseCommand, CommandError +from django.utils import timezone, dateformat + +import programs.models as models +import programs.settings + + +class Diffusion: + ref = None + date_start = None + date_end = None + + def __init__ (self, ref, date_start, date_end): + self.ref = ref + self.date_start = date_start + self.date_end = date_end + + def __lt__ (self, d): + return self.date_start < d.date_start and \ + self.date_end < d.date_end + + + +class Command (BaseCommand): + help= "check sounds to diffuse" + + diffusions = set() + + def handle(self, *args, **options): + self.get_next_events() + self.get_next_episodes() + + for diffusion in self.diffusions: + print( diffusion.ref.__str__() + , diffusion.date_start + , diffusion.date_end) + + + + def get_next_episodes (self): + schedules = models.Schedule.objects.filter() + for schedule in schedules: + date = schedule.next_date() + if not date: + continue + + dt = datetime.timedelta( hours = schedule.duration.hour + , minutes = schedule.duration.minute + , seconds = schedule.duration.second ) + + ref = models.Episode.objects.filter(date = date)[:1] + if not ref: + ref = ( schedule.parent, ) + + diffusion = Diffusion(ref[0], date, date + dt) + self.diffusions.add(diffusion) + + + def get_next_events (self): + events = models.Event.objects.filter(date_end__gt = timezone.now(), + canceled = False) \ + .extra(order_by = ['date'])[:10] + for event in events: + diffusion = Diffusion(event, event.date, event.date_end) + self.diffusions.add(diffusion) + + + + + diff --git a/programs/models.py b/programs/models.py index 1f0cab4..1667854 100755 --- a/programs/models.py +++ b/programs/models.py @@ -25,17 +25,6 @@ import programs.settings as settings -AStatus = { - 'private': 0, - 'public': 1, - # 'canceled': 2, - # 'finished': 3, -} - -Status = [ (y, ugettext_lazy(x)) for x,y in AStatus.items() ] -RStatus = { y: x for x,y in AStatus.items() } - - AFrequency = { 'ponctual': 0x000000, 'every week': 0b001111, @@ -105,24 +94,34 @@ class Metadata (Model): """ meta is used to extend a model for future needs """ - author = models.ForeignKey ( - User, - verbose_name = _('author'), - blank = True, - null = True ) - date = models.DateTimeField( - _('date'), - default = datetime.datetime.now ) - title = models.CharField( - _('title'), - max_length = 128 ) - meta = models.TextField( - _('meta'), - blank = True, - null = True ) - tags = TaggableManager( - _('tags'), - blank = True ) + author = models.ForeignKey ( + User + , verbose_name = _('author') + , blank = True + , null = True + ) + title = models.CharField( + _('title') + , max_length = 128 + ) + date = models.DateTimeField( + _('date') + , default = datetime.datetime.now + ) + public = models.BooleanField( + _('public') + , default = False + , help_text = _('publication is accessible to the public') + ) + meta = models.TextField( + _('meta') + , blank = True + , null = True + ) + tags = TaggableManager( + _('tags') + , blank = True + ) class Meta: abstract = True @@ -136,38 +135,36 @@ class Publication (Metadata): def __str__ (self): return self.title + ' (' + str(self.id) + ')' - subtitle = models.CharField( - _('subtitle'), - max_length = 128, - blank = True ) - img = models.ImageField( - _('image'), - upload_to = "images", - blank = True ) - content = models.TextField( - _('content'), - blank = True ) - status = models.SmallIntegerField( - _('status'), - choices = Status, - default = AStatus['public'] ) - enable_comments = models.BooleanField( - _('enable comments'), - default = True, - help_text = 'select to enable comments') - + subtitle = models.CharField( + _('subtitle') + , max_length = 128 + , blank = True + ) + img = models.ImageField( + _('image') + , upload_to = "images" + , blank = True + ) + content = models.TextField( + _('content') + , blank = True + ) + can_comment = models.BooleanField( + _('enable comments') + , default = True + , help_text = _('comments are enabled on this publication') + ) # # Class methods # - @staticmethod def _exclude_args (allow_unpublished = False, prefix = ''): if allow_unpublished: return {} res = {} - res[prefix + 'status'] = AStatus['private'] + res[prefix + 'public'] = False res[prefix + 'date__gt'] = timezone.now() return res @@ -180,7 +177,7 @@ class Publication (Metadata): Otherwise, return None """ - kwargs['status'] = AStatus['public'] + kwargs['public'] = True kwargs['date__lte'] = timezone.now() e = cl.objects.filter(**kwargs) @@ -193,10 +190,6 @@ class Publication (Metadata): # # Instance's methods # - def is_private (self): - return self.status == AStatus['private'] - - def get_parent (self, raise_404 = False ): if not parent and raise_404: raise Http404 @@ -230,23 +223,25 @@ class Publication (Metadata): # -# Final models +# Usable models # - class Track (Model): - artist = models.CharField( - _('artist'), - max_length = 128, - blank = True) - title = models.CharField( - _('title'), - max_length = 128 ) - version = models.CharField( - _('version'), - max_length = 128, - blank = True, - help_text = _('additional informations on that track')) - tags = TaggableManager( blank = True ) + artist = models.CharField( + _('artist') + , max_length = 128 + , blank = True + ) + title = models.CharField( + _('title') + , max_length = 128 + ) + version = models.CharField( + _('version') + , max_length = 128 + , blank = True + , help_text = _('additional informations on that track') + ) + tags = TaggableManager( blank = True ) def __str__(self): @@ -261,33 +256,33 @@ class Track (Model): class SoundFile (Metadata): - parent = models.ForeignKey( - 'Episode', - verbose_name = _('episode'), - blank = True, - null = True ) - file = models.FileField( - _('file'), - upload_to = "data/tracks", - blank = True ) - duration = models.TimeField( - _('duration'), - blank = True, - null = True ) - podcastable = models.BooleanField( - _('podcastable'), - default = False, - help_text = _('if checked, the file can be podcasted from this server')) - fragment = models.BooleanField( - _('incomplete sound'), - default = False, - help_text = _("the file has been cut")) - embed = models.TextField ( - _('embed HTML code from external website'), - blank = True, - null = True, - help_text = _('if set, consider the sound podcastable from there') - ) + parent = models.ForeignKey( + 'Episode' + , verbose_name = _('episode') + , blank = True + , null = True + ) + file = models.FileField( + _('file') + , upload_to = "data/tracks" + , blank = True + ) + duration = models.TimeField( + _('duration') + , blank = True + , null = True + ) + fragment = models.BooleanField( + _('incomplete sound') + , default = False + , help_text = _("the file has been cut") + ) + embed = models.TextField ( + _('embed HTML code from external website') + , blank = True + , null = True + , help_text = _('if set, consider the sound podcastable from there') + ) def __str__ (self): @@ -300,13 +295,12 @@ class SoundFile (Metadata): - class Schedule (Model): - parent = models.ForeignKey( 'Program', blank = True, null = True ) - date = models.DateTimeField(_('schedule')) - frequency = models.SmallIntegerField(_('frequency'), choices = Frequency) - duration = models.TimeField(_('duration')) - rerun = models.BooleanField(_('rerun'), default = False) + parent = models.ForeignKey( 'Program', blank = True, null = True ) + date = models.DateTimeField(_('start')) + duration = models.TimeField(_('duration')) + frequency = models.SmallIntegerField(_('frequency'), choices = Frequency) + rerun = models.BooleanField(_('rerun'), default = False) def match_week (self, at = datetime.date.today()): @@ -337,7 +331,6 @@ class Schedule (Model): if self.frequency == AFrequency['ponctual']: return None - print('#####') # first day of the week date = at - datetime.timedelta( days = at.weekday() ) @@ -393,18 +386,21 @@ class Schedule (Model): class Article (Publication): - parent = models.ForeignKey( - 'self', - verbose_name = _('parent'), - blank = True, - null = True ) - static_page = models.BooleanField( - _('static page'), - default = False ) - focus = models.BooleanField( - _('article is focus'), - blank = True, - default = False ) + parent = models.ForeignKey( + 'self' + , verbose_name = _('parent') + , blank = True + , null = True + ) + static_page = models.BooleanField( + _('static page') + , default = False + ) + focus = models.BooleanField( + _('article is focus') + , blank = True + , default = False + ) class Meta: @@ -414,28 +410,28 @@ class Article (Publication): class Program (Publication): - parent = models.ForeignKey( - Article - , verbose_name = _('parent') - , blank = True - , null = True - ) - email = models.EmailField( - _('email') - , max_length = 128 - , null = True - , blank = True - ) - url = models.URLField( - _('website') - , blank = True - , null = True - ) - tag = models.CharField( - _('tag') - , max_length = 64 - , help_text = _('used in articles to refer to it') - ) + parent = models.ForeignKey( + Article + , verbose_name = _('parent') + , blank = True + , null = True + ) + email = models.EmailField( + _('email') + , max_length = 128 + , null = True + , blank = True + ) + url = models.URLField( + _('website') + , blank = True + , null = True + ) + tag = models.CharField( + _('tag') + , max_length = 64 + , help_text = _('used in articles to refer to it') + ) @property def path(self): @@ -456,15 +452,17 @@ class Episode (Publication): # minimum of values. # Duration can be retrieved from the sound file if there is one. # - parent = models.ForeignKey( - Program, - verbose_name = _('parent'), - blank = True, - null = True ) - tracks = models.ManyToManyField( - Track, - verbose_name = _('playlist'), - blank = True ) + parent = models.ForeignKey( + Program + , verbose_name = _('parent') + , blank = True + , null = True + ) + tracks = models.ManyToManyField( + Track + , verbose_name = _('playlist') + , blank = True + ) class Meta: @@ -476,27 +474,29 @@ class Episode (Publication): class Event (Model): """ """ - parent = models.ForeignKey ( - Episode, - verbose_name = _('episode'), - blank = True, - null = True ) - - meta = models.TextField ( - _('meta'), - blank = True, - null = True ) - date = models.DateTimeField( _('date') ) - duration = models.TimeField( - _('duration'), - blank = True, - null = True, - help_text = _('this is just indicative')) - status = models.SmallIntegerField( - _('status'), - choices = Status, - default = AStatus['public'] ) - canceled = models.BooleanField( _('canceled'), default = False ) + parent = models.ForeignKey ( + Episode + , verbose_name = _('episode') + , blank = True + , null = True + ) + date = models.DateTimeField( _('date of start') ) + date_end = models.DateTimeField( + _('date of end') + , blank = True + , null = True + ) + public = models.BooleanField( + _('public') + , default = False + , help_text = _('publication is accessible to the public') + ) + meta = models.TextField ( + _('meta') + , blank = True + , null = True + ) + canceled = models.BooleanField( _('canceled'), default = False ) def testify (self):