monitor matching is based on diffusion
This commit is contained in:
parent
7806b945fa
commit
2ebf4a416d
|
@ -13,8 +13,8 @@ from programs.models import *
|
||||||
# Inlines
|
# Inlines
|
||||||
#
|
#
|
||||||
# TODO: inherits from the corresponding admin view
|
# TODO: inherits from the corresponding admin view
|
||||||
class SoundFileInline (admin.TabularInline):
|
class SoundInline (admin.TabularInline):
|
||||||
model = SoundFile
|
model = Sound
|
||||||
raw_id_fields=('parent',)
|
raw_id_fields=('parent',)
|
||||||
fields = ('title', 'private', 'tags', 'file', 'duration', 'fragment')
|
fields = ('title', 'private', 'tags', 'file', 'duration', 'fragment')
|
||||||
extra = 1
|
extra = 1
|
||||||
|
@ -80,9 +80,9 @@ class PublicationAdmin (MetadataAdmin):
|
||||||
#
|
#
|
||||||
# ModelAdmin list
|
# ModelAdmin list
|
||||||
#
|
#
|
||||||
class SoundFileAdmin (MetadataAdmin):
|
class SoundAdmin (MetadataAdmin):
|
||||||
fieldsets = [
|
fieldsets = [
|
||||||
(None, { 'fields': ['title', 'tags', 'file' ] } ),
|
(None, { 'fields': ['title', 'tags', 'path' ] } ),
|
||||||
(None, { 'fields': ['duration', 'date', 'fragment' ] } )
|
(None, { 'fields': ['duration', 'date', 'fragment' ] } )
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ class ProgramAdmin (PublicationAdmin):
|
||||||
|
|
||||||
class EpisodeAdmin (PublicationAdmin):
|
class EpisodeAdmin (PublicationAdmin):
|
||||||
fieldsets = copy.deepcopy(PublicationAdmin.fieldsets)
|
fieldsets = copy.deepcopy(PublicationAdmin.fieldsets)
|
||||||
#inlines = [ SoundFileInline ]
|
#inlines = [ SoundInline ]
|
||||||
list_filter = ['parent'] + PublicationAdmin.list_filter
|
list_filter = ['parent'] + PublicationAdmin.list_filter
|
||||||
|
|
||||||
# FIXME later: when we have thousands of tracks
|
# FIXME later: when we have thousands of tracks
|
||||||
|
@ -114,7 +114,7 @@ class EpisodeAdmin (PublicationAdmin):
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Track)
|
admin.site.register(Track)
|
||||||
admin.site.register(SoundFile, SoundFileAdmin)
|
admin.site.register(Sound, SoundAdmin)
|
||||||
admin.site.register(Schedule)
|
admin.site.register(Schedule)
|
||||||
admin.site.register(Article, ArticleAdmin)
|
admin.site.register(Article, ArticleAdmin)
|
||||||
admin.site.register(Program, ProgramAdmin)
|
admin.site.register(Program, ProgramAdmin)
|
||||||
|
|
|
@ -4,7 +4,7 @@ from programs.models import *
|
||||||
|
|
||||||
class SoundAutocomplete(al.AutocompleteModelBase):
|
class SoundAutocomplete(al.AutocompleteModelBase):
|
||||||
search_fields = ['title', 'file']
|
search_fields = ['title', 'file']
|
||||||
model = SoundFile
|
model = Sound
|
||||||
|
|
||||||
al.register(SoundAutocomplete)
|
al.register(SoundAutocomplete)
|
||||||
|
|
||||||
|
|
|
@ -175,7 +175,7 @@ models = {
|
||||||
, 'frequency': int }
|
, 'frequency': int }
|
||||||
, { 'rerun': int } # FIXME: redo
|
, { 'rerun': int } # FIXME: redo
|
||||||
)
|
)
|
||||||
, 'soundfile': Model( models.SoundFile
|
, 'sound': Model( models.Sound
|
||||||
, { 'parent_id': int, 'date': DateTime, 'file': str
|
, { 'parent_id': int, 'date': DateTime, 'file': str
|
||||||
, 'duration': Time}
|
, 'duration': Time}
|
||||||
, { 'fragment': bool, 'embed': str, 'removed': bool }
|
, { 'fragment': bool, 'embed': str, 'removed': bool }
|
||||||
|
|
|
@ -156,9 +156,7 @@ class Publication (Metadata):
|
||||||
, help_text = _('comments are enabled on this publication')
|
, help_text = _('comments are enabled on this publication')
|
||||||
)
|
)
|
||||||
|
|
||||||
#
|
|
||||||
# Class methods
|
|
||||||
#
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _exclude_args (allow_unpublished = False, prefix = ''):
|
def _exclude_args (allow_unpublished = False, prefix = ''):
|
||||||
if allow_unpublished:
|
if allow_unpublished:
|
||||||
|
@ -188,9 +186,6 @@ class Publication (Metadata):
|
||||||
return e or None
|
return e or None
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Instance's methods
|
|
||||||
#
|
|
||||||
def get_parents (self, order_by = "desc", include_fields = None):
|
def get_parents (self, order_by = "desc", include_fields = None):
|
||||||
"""
|
"""
|
||||||
Return an array of the parents of the item.
|
Return an array of the parents of the item.
|
||||||
|
@ -250,7 +245,20 @@ class Track (Model):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SoundFile (Metadata):
|
class Sound (Metadata):
|
||||||
|
"""
|
||||||
|
A Sound is the representation of a sound, that can be:
|
||||||
|
- An episode podcast/complete record
|
||||||
|
- An episode partial podcast
|
||||||
|
- An episode is a part of the episode but not usable for direct podcast
|
||||||
|
|
||||||
|
We can manage this using the "public" and "fragment" fields. If a Sound is
|
||||||
|
public, then we can podcast it. If a Sound is a fragment, then it is not
|
||||||
|
usable for diffusion.
|
||||||
|
|
||||||
|
Each sound file can be associated to a filesystem's file or an embedded
|
||||||
|
code (for external podcasts).
|
||||||
|
"""
|
||||||
def get_upload_path (self, filename):
|
def get_upload_path (self, filename):
|
||||||
if self.parent and self.parent.parent:
|
if self.parent and self.parent.parent:
|
||||||
path = self.parent.parent.path
|
path = self.parent.parent.path
|
||||||
|
@ -259,9 +267,12 @@ class SoundFile (Metadata):
|
||||||
return os.path.join(path, filename)
|
return os.path.join(path, filename)
|
||||||
|
|
||||||
|
|
||||||
file = models.FileField( #FIXME: filefield
|
path = models.FilePathField( #FIXME: filefield
|
||||||
_('file')
|
_('file')
|
||||||
, upload_to = get_upload_path
|
, path = settings.AIRCOX_PROGRAMS_DIR
|
||||||
|
, match = '*(' \
|
||||||
|
+ '|'.join(settings.AIRCOX_SOUNDFILE_EXT) + ')$'
|
||||||
|
, recursive = True
|
||||||
, blank = True
|
, blank = True
|
||||||
, null = True
|
, null = True
|
||||||
)
|
)
|
||||||
|
@ -291,7 +302,7 @@ class SoundFile (Metadata):
|
||||||
"""
|
"""
|
||||||
Get the last modification date from file
|
Get the last modification date from file
|
||||||
"""
|
"""
|
||||||
mtime = os.stat(self.file.path).st_mtime
|
mtime = os.stat(self.path).st_mtime
|
||||||
mtime = timezone.datetime.fromtimestamp(mtime)
|
mtime = timezone.datetime.fromtimestamp(mtime)
|
||||||
return timezone.make_aware(mtime, timezone.get_current_timezone())
|
return timezone.make_aware(mtime, timezone.get_current_timezone())
|
||||||
|
|
||||||
|
@ -299,11 +310,11 @@ class SoundFile (Metadata):
|
||||||
def save (self, *args, **kwargs):
|
def save (self, *args, **kwargs):
|
||||||
if not self.pk:
|
if not self.pk:
|
||||||
self.date = self.get_mtime()
|
self.date = self.get_mtime()
|
||||||
super(SoundFile, self).save(*args, **kwargs)
|
super(Sound, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def __str__ (self):
|
def __str__ (self):
|
||||||
return str(self.id) + ': ' + self.file.name
|
return str(self.id) + ': ' + self.path
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -474,8 +485,6 @@ class Schedule (Model):
|
||||||
return diffusions
|
return diffusions
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def __str__ (self):
|
def __str__ (self):
|
||||||
frequency = [ x for x,y in Frequency.items() if y == self.frequency ]
|
frequency = [ x for x,y in Frequency.items() if y == self.frequency ]
|
||||||
return self.parent.title + ': ' + frequency[0]
|
return self.parent.title + ': ' + frequency[0]
|
||||||
|
@ -543,6 +552,7 @@ class Program (Publication):
|
||||||
"""
|
"""
|
||||||
Return the first schedule that matches a given date
|
Return the first schedule that matches a given date
|
||||||
"""
|
"""
|
||||||
|
print(self)
|
||||||
schedules = Schedule.objects.filter(parent = self)
|
schedules = Schedule.objects.filter(parent = self)
|
||||||
for schedule in schedules:
|
for schedule in schedules:
|
||||||
if schedule.match(date):
|
if schedule.match(date):
|
||||||
|
@ -570,12 +580,13 @@ class Episode (Publication):
|
||||||
, help_text = _('parent program')
|
, help_text = _('parent program')
|
||||||
)
|
)
|
||||||
tracks = SortedManyToManyField(
|
tracks = SortedManyToManyField(
|
||||||
#tracks = models.ManyToManyField(
|
|
||||||
Track
|
Track
|
||||||
|
, blank = True
|
||||||
, verbose_name = _('tracks')
|
, verbose_name = _('tracks')
|
||||||
)
|
)
|
||||||
sounds = SortedManyToManyField(
|
sounds = SortedManyToManyField(
|
||||||
SoundFile
|
Sound
|
||||||
|
, blank = True
|
||||||
, verbose_name = _('sounds')
|
, verbose_name = _('sounds')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -593,7 +604,7 @@ class Diffusion (Model):
|
||||||
- scheduled: when it has been generated following programs' Schedule
|
- scheduled: when it has been generated following programs' Schedule
|
||||||
- planified: when it has been generated manually/ponctually or scheduled
|
- planified: when it has been generated manually/ponctually or scheduled
|
||||||
"""
|
"""
|
||||||
parent = models.ForeignKey (
|
episode = models.ForeignKey (
|
||||||
Episode
|
Episode
|
||||||
, blank = True
|
, blank = True
|
||||||
, null = True
|
, null = True
|
||||||
|
@ -620,8 +631,8 @@ class Diffusion (Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
def save (self, *args, **kwargs):
|
def save (self, *args, **kwargs):
|
||||||
if self.parent:
|
if self.episode:
|
||||||
self.program = self.parent.parent
|
self.program = self.episode.parent
|
||||||
super(Diffusion, self).save(*args, **kwargs)
|
super(Diffusion, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,13 +10,13 @@ def ensure (key, default):
|
||||||
ensure('AIRCOX_PROGRAMS_DIR',
|
ensure('AIRCOX_PROGRAMS_DIR',
|
||||||
os.path.join(settings.MEDIA_ROOT, 'programs'))
|
os.path.join(settings.MEDIA_ROOT, 'programs'))
|
||||||
|
|
||||||
# Default directory for the soundfiles
|
# Default directory for the sounds
|
||||||
ensure('AIRCOX_SOUNDFILE_DEFAULT_DIR',
|
ensure('AIRCOX_SOUNDFILE_DEFAULT_DIR',
|
||||||
os.path.join(AIRCOX_PROGRAMS_DIR + 'default'))
|
os.path.join(AIRCOX_PROGRAMS_DIR + 'default'))
|
||||||
|
|
||||||
# Extension of sound files
|
# Extension of sound files
|
||||||
ensure('AIRCOX_SOUNDFILE_EXT',
|
ensure('AIRCOX_SOUNDFILE_EXT',
|
||||||
('ogg','flac','wav','mp3','opus'))
|
('.ogg','.flac','.wav','.mp3','.opus'))
|
||||||
|
|
||||||
# Stream for the scheduled diffusions
|
# Stream for the scheduled diffusions
|
||||||
ensure('AIRCOX_SCHEDULED_STREAM', 0)
|
ensure('AIRCOX_SCHEDULED_STREAM', 0)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user