quick fix on bugs due to Django 1.10
This commit is contained in:
		@ -25,7 +25,7 @@ Python modules:
 | 
			
		||||
* `django-honeypot`: `aircox.cms`
 | 
			
		||||
* `bleach`: 'aircox.cms` (comments sanitization)
 | 
			
		||||
* `dateutils`: `aircox.programs` (used for tests)
 | 
			
		||||
* `Pillow`: `aircox.cms`
 | 
			
		||||
* `Pillow`: `aircox.cms` (needed by `wagtail`)
 | 
			
		||||
 | 
			
		||||
Applications:
 | 
			
		||||
* `liquidsoap`: `aircox.controllers` (generation of the audio streams)
 | 
			
		||||
 | 
			
		||||
@ -170,7 +170,9 @@ class Station(programs.Nameable):
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def __mix_logs_and_diff(diffs, logs, count = 0):
 | 
			
		||||
        """
 | 
			
		||||
        Mix together logs and diffusion items ordering by their date.
 | 
			
		||||
        Mix together logs and diffusion items of the same day,
 | 
			
		||||
        ordered by their date.
 | 
			
		||||
 | 
			
		||||
        Diffs and Logs are assumed to be ordered by -date, and so is
 | 
			
		||||
        the resulting list
 | 
			
		||||
        """
 | 
			
		||||
@ -189,10 +191,15 @@ class Station(programs.Nameable):
 | 
			
		||||
            if count and len(items) >= count:
 | 
			
		||||
                break
 | 
			
		||||
 | 
			
		||||
        if diff_ and (not count or len(items) <= count):
 | 
			
		||||
            logs_ = logs.filter(date__lt = diff_.end)
 | 
			
		||||
            items.extend(logs_)
 | 
			
		||||
        if diff_:
 | 
			
		||||
            if count and len(items) >= count:
 | 
			
		||||
                return items[:count]
 | 
			
		||||
 | 
			
		||||
            logs_ = logs.filter(date__lt = diff_.end)
 | 
			
		||||
        else:
 | 
			
		||||
            logs_ = logs.all()
 | 
			
		||||
 | 
			
		||||
        items.extend(logs_)
 | 
			
		||||
        return items[:count] if count else items
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -305,7 +312,8 @@ class Source(programs.Nameable):
 | 
			
		||||
    program = models.ForeignKey(
 | 
			
		||||
        programs.Program,
 | 
			
		||||
        verbose_name = _('related program'),
 | 
			
		||||
        blank = True, null = True
 | 
			
		||||
        blank = True, null = True,
 | 
			
		||||
        limit_choices_to = { 'stream__isnull': False },
 | 
			
		||||
    )
 | 
			
		||||
    url = models.TextField(
 | 
			
		||||
        _('url'),
 | 
			
		||||
@ -355,7 +363,7 @@ class Source(programs.Nameable):
 | 
			
		||||
            self.controller.playlist = [ sound.path for sound in
 | 
			
		||||
                programs.Sound.objects.filter(
 | 
			
		||||
                    type = programs.Sound.Type.archive,
 | 
			
		||||
                    path__startswith = program.path
 | 
			
		||||
                    program = program,
 | 
			
		||||
                )
 | 
			
		||||
            ]
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,14 @@ class Monitor:
 | 
			
		||||
    Time in seconds before a diffusion that have archives is cancelled
 | 
			
		||||
    because it has not been played.
 | 
			
		||||
    """
 | 
			
		||||
    sync_timeout = 60*10
 | 
			
		||||
    """
 | 
			
		||||
    Time in minuts before all stream playlists are checked and updated
 | 
			
		||||
    """
 | 
			
		||||
    sync_next = None
 | 
			
		||||
    """
 | 
			
		||||
    Datetime of the next sync
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, station, **kwargs):
 | 
			
		||||
        self.station = station
 | 
			
		||||
@ -44,6 +52,7 @@ class Monitor:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        self.trace()
 | 
			
		||||
        self.sync_playlists()
 | 
			
		||||
        self.handle()
 | 
			
		||||
 | 
			
		||||
    def log(self, **kwargs):
 | 
			
		||||
@ -112,6 +121,22 @@ class Monitor:
 | 
			
		||||
                    related = track
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
    def sync_playlists(self):
 | 
			
		||||
        """
 | 
			
		||||
        Synchronize updated playlists
 | 
			
		||||
        """
 | 
			
		||||
        now = tz.now()
 | 
			
		||||
        if self.sync_next and self.sync_next < now:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        self.sync_next = now + tz.timedelta(seconds = self.sync_timeout)
 | 
			
		||||
 | 
			
		||||
        for source in self.station.stream_sources:
 | 
			
		||||
            playlist = [ sound.path for sound in
 | 
			
		||||
                            source.program.sound_set.all().order_by('path') ]
 | 
			
		||||
            if playlist != source.controller.playlist:
 | 
			
		||||
                source.controller.playlist = playlist
 | 
			
		||||
 | 
			
		||||
    def trace_canceled(self):
 | 
			
		||||
        """
 | 
			
		||||
        Check diffusions that should have been played but did not start,
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,8 @@ A stream is a source that:
 | 
			
		||||
- is interactive
 | 
			
		||||
{% endcomment %}
 | 
			
		||||
def stream (id, file) =
 | 
			
		||||
    s = playlist(id = '#{id}_playlist', mode = "random", file)
 | 
			
		||||
    s = playlist(id = '#{id}_playlist', mode = "random", reload_mode='watch',
 | 
			
		||||
                 file)
 | 
			
		||||
    interactive_source(id, s)
 | 
			
		||||
end
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										34
									
								
								notes.md
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								notes.md
									
									
									
									
									
								
							@ -10,35 +10,6 @@ This file is used as a reminder, can be used as crappy documentation too.
 | 
			
		||||
* icons: cropped to 32x32
 | 
			
		||||
* cover in list items: cropped 64x64
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# TODO:
 | 
			
		||||
- general:
 | 
			
		||||
    - timezone shit
 | 
			
		||||
    - translation
 | 
			
		||||
 | 
			
		||||
- programs:
 | 
			
		||||
    - schedule changes -> update later diffusions according to the new schedule
 | 
			
		||||
    - users
 | 
			
		||||
    - tests:
 | 
			
		||||
        - sound_monitor
 | 
			
		||||
        - import_playlist
 | 
			
		||||
 | 
			
		||||
- controllers :
 | 
			
		||||
    - models to template -> note
 | 
			
		||||
    - input stream
 | 
			
		||||
    - streamed program disable -> remote control on liquidsoap
 | 
			
		||||
    - tests:
 | 
			
		||||
        - monitor
 | 
			
		||||
        - config generation and sound diffusion
 | 
			
		||||
 | 
			
		||||
- cms:
 | 
			
		||||
    - player:
 | 
			
		||||
        - mixcloud
 | 
			
		||||
        - remove from playing playlist -> stop
 | 
			
		||||
    - filter choices on DiffusionPage and ProgramPage related objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Long term TODO
 | 
			
		||||
- debug/prod configuration
 | 
			
		||||
 | 
			
		||||
@ -46,9 +17,8 @@ programs:
 | 
			
		||||
    - sounds monitor: max_size of path, take in account
 | 
			
		||||
 | 
			
		||||
controllers:
 | 
			
		||||
    - automatic cancel of passed diffusion based on logs?
 | 
			
		||||
        - archives can be set afterwards for rerun, so check must be done
 | 
			
		||||
            at the same time we monitor
 | 
			
		||||
    - archives can be set afterwards for rerun, so check must be done
 | 
			
		||||
        at the same time we monitor
 | 
			
		||||
    - logs: archive functionnality
 | 
			
		||||
    - tools:
 | 
			
		||||
        - track stats for diffusions
 | 
			
		||||
 | 
			
		||||
@ -37,14 +37,6 @@ class DiffusionInline(admin.StackedInline):
 | 
			
		||||
    extra = 0
 | 
			
		||||
    fields = ['type', 'start', 'end']
 | 
			
		||||
 | 
			
		||||
# from suit.admin import SortableTabularInline, SortableModelAdmin
 | 
			
		||||
#class TrackInline(SortableTabularInline):
 | 
			
		||||
#    fields = ['artist', 'name', 'tags', 'position']
 | 
			
		||||
#    form = TrackForm
 | 
			
		||||
#    model = Track
 | 
			
		||||
#    sortable = 'position'
 | 
			
		||||
#    extra = 10
 | 
			
		||||
 | 
			
		||||
class NameableAdmin(admin.ModelAdmin):
 | 
			
		||||
    fields = [ 'name' ]
 | 
			
		||||
 | 
			
		||||
@ -58,7 +50,7 @@ class TrackInline(GenericTabularInline):
 | 
			
		||||
    ct_fk_field = 'related_id'
 | 
			
		||||
    model = Track
 | 
			
		||||
    extra = 0
 | 
			
		||||
    fields = ('artist', 'title', 'tags', 'info', 'position')
 | 
			
		||||
    fields = ('artist', 'title', 'info', 'position')
 | 
			
		||||
    readonly_fields = ('position',)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -68,7 +60,8 @@ class SoundAdmin(NameableAdmin):
 | 
			
		||||
    list_display = ['id', 'name', 'duration', 'type', 'mtime',
 | 
			
		||||
                    'public', 'good_quality']
 | 
			
		||||
    fieldsets = [
 | 
			
		||||
        (None, { 'fields': NameableAdmin.fields + ['path', 'type', 'diffusion'] } ),
 | 
			
		||||
        (None, { 'fields': NameableAdmin.fields +
 | 
			
		||||
                           ['path', 'type', 'program', 'diffusion'] } ),
 | 
			
		||||
        (None, { 'fields': ['embed', 'duration', 'public', 'mtime'] }),
 | 
			
		||||
        (None, { 'fields': ['good_quality' ] } )
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
@ -291,6 +291,8 @@ class Command(BaseCommand):
 | 
			
		||||
        if not program.ensure_dir(subdir):
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        sound_kwargs['program'] = program
 | 
			
		||||
 | 
			
		||||
        subdir = os.path.join(program.path, subdir)
 | 
			
		||||
        sounds = []
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -123,11 +123,17 @@ class Sound(Nameable):
 | 
			
		||||
        excerpt = 0x02,
 | 
			
		||||
        removed = 0x03,
 | 
			
		||||
 | 
			
		||||
    program = models.ForeignKey(
 | 
			
		||||
        'Program',
 | 
			
		||||
        verbose_name = _('program'),
 | 
			
		||||
        blank = True, null = True,
 | 
			
		||||
        help_text = _('program related to it'),
 | 
			
		||||
    )
 | 
			
		||||
    diffusion = models.ForeignKey(
 | 
			
		||||
        'Diffusion',
 | 
			
		||||
        verbose_name = _('diffusion'),
 | 
			
		||||
        blank = True, null = True,
 | 
			
		||||
        help_text = _('this is set for scheduled programs')
 | 
			
		||||
        help_text = _('initial diffusion related it')
 | 
			
		||||
    )
 | 
			
		||||
    type = models.SmallIntegerField(
 | 
			
		||||
        verbose_name = _('type'),
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,9 @@
 | 
			
		||||
Django>=1.9a1
 | 
			
		||||
django-taggit>=0.12.1
 | 
			
		||||
django-taggit>=0.18.3
 | 
			
		||||
watchdog>=0.8.3
 | 
			
		||||
wagtail>=1.5.3
 | 
			
		||||
Pillow>=3.3.0
 | 
			
		||||
django-honeypot>=0.5.0
 | 
			
		||||
dateutils>=0.6.6
 | 
			
		||||
bleach>=1.4.3
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user