rename
This commit is contained in:
		
							
								
								
									
										0
									
								
								programs/__init__.py → aircox_cms/__init__.py
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										0
									
								
								programs/__init__.py → aircox_cms/__init__.py
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
								
								
									
										52
									
								
								aircox_cms/migrations/0001_initial.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								aircox_cms/migrations/0001_initial.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
			
		||||
# -*- coding: utf-8 -*-
 | 
			
		||||
from __future__ import unicode_literals
 | 
			
		||||
 | 
			
		||||
from django.db import models, migrations
 | 
			
		||||
import taggit.managers
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
import datetime
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('contenttypes', '0002_remove_content_type_name'),
 | 
			
		||||
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
 | 
			
		||||
        ('taggit', '0002_auto_20150616_2121'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='Article',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
 | 
			
		||||
                ('date', models.DateTimeField(default=datetime.datetime.now, verbose_name='date')),
 | 
			
		||||
                ('published', models.BooleanField(default=True, verbose_name='public')),
 | 
			
		||||
                ('title', models.CharField(verbose_name='titre', max_length=128)),
 | 
			
		||||
                ('content', models.TextField(null=True, blank=True, verbose_name='description')),
 | 
			
		||||
                ('image', models.ImageField(null=True, blank=True, upload_to='')),
 | 
			
		||||
                ('static_page', models.BooleanField(default=False, verbose_name='page statique')),
 | 
			
		||||
                ('focus', models.BooleanField(default=False, verbose_name="l'article est épinglé")),
 | 
			
		||||
                ('author', models.ForeignKey(to=settings.AUTH_USER_MODEL, null=True, blank=True, verbose_name='auteur')),
 | 
			
		||||
                ('tags', taggit.managers.TaggableManager(through='taggit.TaggedItem', to='taggit.Tag', blank=True, help_text='A comma-separated list of tags.', verbose_name='mots-clés')),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                'verbose_name': 'Article',
 | 
			
		||||
                'verbose_name_plural': 'Articles',
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='Thread',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
 | 
			
		||||
                ('post_id', models.PositiveIntegerField()),
 | 
			
		||||
                ('post_type', models.ForeignKey(to='contenttypes.ContentType')),
 | 
			
		||||
            ],
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='article',
 | 
			
		||||
            name='thread',
 | 
			
		||||
            field=models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, null=True, help_text='the publication is posted on this thread', blank=True, to='aircox_cms.Thread'),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
							
								
								
									
										10
									
								
								aircox_cms/static/aircox_cms/styles.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								aircox_cms/static/aircox_cms/styles.css
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
body { padding: 0; margin: 0; }
 | 
			
		||||
 | 
			
		||||
nav.menu_top {
 | 
			
		||||
    width: 100%
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    border-bottom: 1px grey solid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,14 @@
 | 
			
		||||
{% load staticfiles %}
 | 
			
		||||
 | 
			
		||||
<html>
 | 
			
		||||
    <head>
 | 
			
		||||
        {# FIXME: page tags #}
 | 
			
		||||
        <meta charset="utf-8">
 | 
			
		||||
        <meta name="application-name" content="aircox-cms">
 | 
			
		||||
        <meta name="description" content="{{ website.description }}">
 | 
			
		||||
        <meta name="keywords" content="{{ website.tags }}">
 | 
			
		||||
 | 
			
		||||
        <link rel="stylesheet" href="{% static "aircox_aircox_cms/styles.css" %}" type="text/css">
 | 
			
		||||
        <title>{{ website.name }} {% if title %}- {{ title }} {% endif %}</title>
 | 
			
		||||
    </head>
 | 
			
		||||
    <body>
 | 
			
		||||
@ -35,6 +44,10 @@
 | 
			
		||||
                    {% endblock %}
 | 
			
		||||
                </div>
 | 
			
		||||
            </main>
 | 
			
		||||
 | 
			
		||||
            {% if menus.right %}
 | 
			
		||||
                {{ menus.right|safe }}
 | 
			
		||||
            {% endif %}
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        {% block footer %}
 | 
			
		||||
@ -44,6 +57,10 @@
 | 
			
		||||
            </footer>
 | 
			
		||||
            {% endif %}
 | 
			
		||||
        {% endblock %}
 | 
			
		||||
 | 
			
		||||
        {% if menus.bottom %}
 | 
			
		||||
            {{ menus.bottom|safe }}
 | 
			
		||||
        {% endif %}
 | 
			
		||||
    </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
{% extends embed|yesno:"cms/base_content.html,cms/base_site.html" %}
 | 
			
		||||
{% extends embed|yesno:"aircox_cms/base_content.html,aircox_cms/base_site.html" %}
 | 
			
		||||
 | 
			
		||||
{% block title %}
 | 
			
		||||
{{ object.title }}
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
{% extends embed|yesno:"cms/base_content.html,cms/base_site.html" %}
 | 
			
		||||
{% extends embed|yesno:"aircox_cms/base_content.html,aircox_cms/base_site.html" %}
 | 
			
		||||
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
{% load thumbnail %}
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
{% extends "cms/section.html" %}
 | 
			
		||||
{% extends "aircox_cms/section.html" %}
 | 
			
		||||
 | 
			
		||||
{% load thumbnail %}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								aircox_cms/templates/aircox_cms/tags
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								aircox_cms/templates/aircox_cms/tags
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
!_TAG_FILE_FORMAT	2	/extended format; --format=1 will not append ;" to lines/
 | 
			
		||||
!_TAG_FILE_SORTED	1	/0=unsorted, 1=sorted, 2=foldcase/
 | 
			
		||||
!_TAG_PROGRAM_AUTHOR	Darren Hiebert	/dhiebert@users.sourceforge.net/
 | 
			
		||||
!_TAG_PROGRAM_NAME	Exuberant Ctags	//
 | 
			
		||||
!_TAG_PROGRAM_URL	http://ctags.sourceforge.net	/official site/
 | 
			
		||||
!_TAG_PROGRAM_VERSION	5.8	//
 | 
			
		||||
							
								
								
									
										0
									
								
								programs/tests.py → aircox_cms/tests.py
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										0
									
								
								programs/tests.py → aircox_cms/tests.py
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							@ -5,7 +5,7 @@ from django.views.generic.base import View, TemplateResponseMixin
 | 
			
		||||
from django.core import serializers
 | 
			
		||||
from django.utils.translation import ugettext as _, ugettext_lazy
 | 
			
		||||
 | 
			
		||||
import cms.routes as routes
 | 
			
		||||
import aircox_cms.routes as routes
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PostBaseView:
 | 
			
		||||
@ -67,7 +67,7 @@ class PostListView (PostBaseView, ListView):
 | 
			
		||||
                return
 | 
			
		||||
            self.__dict__.update(query)
 | 
			
		||||
 | 
			
		||||
    template_name = 'cms/list.html'
 | 
			
		||||
    template_name = 'aircox_cms/list.html'
 | 
			
		||||
    allow_empty = True
 | 
			
		||||
 | 
			
		||||
    route = None
 | 
			
		||||
@ -127,7 +127,7 @@ class PostDetailView (DetailView, PostBaseView):
 | 
			
		||||
    """
 | 
			
		||||
    Detail view for posts and children
 | 
			
		||||
    """
 | 
			
		||||
    template_name = 'cms/detail.html'
 | 
			
		||||
    template_name = 'aircox_cms/detail.html'
 | 
			
		||||
 | 
			
		||||
    sections = []
 | 
			
		||||
 | 
			
		||||
@ -135,9 +135,12 @@ class PostDetailView (DetailView, PostBaseView):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        self.sections = sections or []
 | 
			
		||||
 | 
			
		||||
    def get_queryset (self, **kwargs):
 | 
			
		||||
    def get_queryset (self):
 | 
			
		||||
        if self.request.GET.get('embed'):
 | 
			
		||||
            self.embed = True
 | 
			
		||||
 | 
			
		||||
        if self.model:
 | 
			
		||||
            return super().get_queryset(**kwargs).filter(published = True)
 | 
			
		||||
            return super().get_queryset().filter(published = True)
 | 
			
		||||
        return []
 | 
			
		||||
 | 
			
		||||
    def get_object (self, **kwargs):
 | 
			
		||||
@ -193,7 +196,7 @@ class ViewSet:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Menu (View):
 | 
			
		||||
    template_name = 'cms/menu.html'
 | 
			
		||||
    template_name = 'aircox_cms/menu.html'
 | 
			
		||||
 | 
			
		||||
    name = ''
 | 
			
		||||
    enabled = True
 | 
			
		||||
@ -227,7 +230,7 @@ class Section (View):
 | 
			
		||||
    Base class for sections. Sections are view that can be used in detail view
 | 
			
		||||
    in order to have extra content about a post.
 | 
			
		||||
    """
 | 
			
		||||
    template_name = 'cms/section.html'
 | 
			
		||||
    template_name = 'aircox_cms/section.html'
 | 
			
		||||
    require_object = False
 | 
			
		||||
    object = None
 | 
			
		||||
    classes = ''
 | 
			
		||||
@ -271,7 +274,7 @@ class ListSection (Section):
 | 
			
		||||
 | 
			
		||||
    use_icons = True
 | 
			
		||||
    icon_size = '32x32'
 | 
			
		||||
    template_name = 'cms/section_list.html'
 | 
			
		||||
    template_name = 'aircox_cms/section_list.html'
 | 
			
		||||
 | 
			
		||||
    def get_object_list (self):
 | 
			
		||||
        return []
 | 
			
		||||
@ -1,8 +1,11 @@
 | 
			
		||||
import cms.routes as routes
 | 
			
		||||
import aircox_cms.routes as routes
 | 
			
		||||
 | 
			
		||||
class Website:
 | 
			
		||||
    name = ''
 | 
			
		||||
    domain = ''
 | 
			
		||||
    description = 'An aircox website'   # public description (used in meta info)
 | 
			
		||||
    tags = 'aircox,radio,music'         # public keywords (used in meta info)
 | 
			
		||||
 | 
			
		||||
    logo = None
 | 
			
		||||
    menus = None
 | 
			
		||||
    router = None
 | 
			
		||||
							
								
								
									
										0
									
								
								programs/management/commands/__init__.py → aircox_programs/__init__.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								programs/management/commands/__init__.py → aircox_programs/__init__.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -7,8 +7,8 @@ from django.db import models
 | 
			
		||||
from suit.admin import SortableTabularInline, SortableModelAdmin
 | 
			
		||||
from autocomplete_light.contrib.taggit_field import TaggitWidget, TaggitField
 | 
			
		||||
 | 
			
		||||
from programs.forms import *
 | 
			
		||||
from programs.models import *
 | 
			
		||||
from aircox_programs.forms import *
 | 
			
		||||
from aircox_programs.models import *
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import autocomplete_light.shortcuts as al
 | 
			
		||||
from programs.models import *
 | 
			
		||||
from aircox_programs.models import *
 | 
			
		||||
 | 
			
		||||
from taggit.models import Tag
 | 
			
		||||
al.register(Tag)
 | 
			
		||||
@ -4,7 +4,7 @@ from django.contrib.admin import widgets
 | 
			
		||||
import autocomplete_light.shortcuts as al
 | 
			
		||||
from autocomplete_light.contrib.taggit_field import TaggitWidget
 | 
			
		||||
 | 
			
		||||
from programs.models import *
 | 
			
		||||
from aircox_programs.models import *
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TrackForm (forms.ModelForm):
 | 
			
		||||
							
								
								
									
										0
									
								
								aircox_programs/management/commands/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								aircox_programs/management/commands/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								aircox_programs/management/commands/_private.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								aircox_programs/management/commands/_private.py
									
									
									
									
									
										Normal file
									
								
							@ -17,7 +17,7 @@ from the (given) month and later.
 | 
			
		||||
from argparse                       import RawTextHelpFormatter
 | 
			
		||||
from django.core.management.base    import BaseCommand, CommandError
 | 
			
		||||
from django.utils                   import timezone as tz
 | 
			
		||||
from programs.models                import *
 | 
			
		||||
from aircox_programs.models                import *
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Actions:
 | 
			
		||||
@ -3,7 +3,7 @@ import json
 | 
			
		||||
 | 
			
		||||
from django.core.management.base    import BaseCommand, CommandError
 | 
			
		||||
from django.utils                   import timezone
 | 
			
		||||
import programs.models              as models
 | 
			
		||||
import aircox_programs.models              as models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Model:
 | 
			
		||||
@ -20,8 +20,8 @@ from argparse import RawTextHelpFormatter
 | 
			
		||||
 | 
			
		||||
from django.core.management.base    import BaseCommand, CommandError
 | 
			
		||||
from django.utils                   import timezone
 | 
			
		||||
from programs.models                import *
 | 
			
		||||
import programs.settings            as settings
 | 
			
		||||
from aircox_programs.models                import *
 | 
			
		||||
import aircox_programs.settings            as settings
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Command (BaseCommand):
 | 
			
		||||
							
								
								
									
										136
									
								
								aircox_programs/migrations/0001_initial.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								aircox_programs/migrations/0001_initial.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,136 @@
 | 
			
		||||
# -*- coding: utf-8 -*-
 | 
			
		||||
from __future__ import unicode_literals
 | 
			
		||||
 | 
			
		||||
from django.db import models, migrations
 | 
			
		||||
import taggit.managers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('taggit', '0002_auto_20150616_2121'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='Diffusion',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
 | 
			
		||||
                ('type', models.SmallIntegerField(choices=[(0, 'default'), (4, 'stop'), (1, 'unconfirmed'), (2, 'cancel')], verbose_name='type')),
 | 
			
		||||
                ('date', models.DateTimeField(verbose_name='start of the diffusion')),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                'verbose_name': 'Diffusion',
 | 
			
		||||
                'verbose_name_plural': 'Diffusions',
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='Episode',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
 | 
			
		||||
                ('name', models.CharField(verbose_name='nom', max_length=128)),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                'verbose_name': 'Épisode',
 | 
			
		||||
                'verbose_name_plural': 'Épisodes',
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='Program',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
 | 
			
		||||
                ('name', models.CharField(verbose_name='nom', max_length=128)),
 | 
			
		||||
                ('active', models.BooleanField(default=True, help_text='if not set this program is no longer active', verbose_name='inactive')),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                'abstract': False,
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='Schedule',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
 | 
			
		||||
                ('date', models.DateTimeField(verbose_name='date')),
 | 
			
		||||
                ('duration', models.TimeField(verbose_name='durée')),
 | 
			
		||||
                ('frequency', models.SmallIntegerField(choices=[(4, 'third'), (32, 'one on two'), (10, 'second and fourth'), (5, 'first and third'), (31, 'every'), (2, 'second'), (1, 'first'), (16, 'last'), (8, 'fourth')], verbose_name='fréquence')),
 | 
			
		||||
                ('program', models.ForeignKey(to='aircox_programs.Program', null=True, blank=True)),
 | 
			
		||||
                ('rerun', models.ForeignKey(to='aircox_programs.Schedule', null=True, help_text='Schedule of a rerun of this one', blank=True, verbose_name='rediffusion')),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                'verbose_name': 'Schedule',
 | 
			
		||||
                'verbose_name_plural': 'Schedules',
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='Sound',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
 | 
			
		||||
                ('name', models.CharField(verbose_name='nom', max_length=128)),
 | 
			
		||||
                ('path', models.FilePathField(recursive=True, match='*(.ogg|.flac|.wav|.mp3|.opus)$', path='/media/data/courants/code/aircox/static/media/programs', null=True, blank=True, verbose_name='fichier')),
 | 
			
		||||
                ('embed', models.TextField(null=True, blank=True, help_text='if set, consider the sound podcastable', verbose_name='embed HTML code from external website')),
 | 
			
		||||
                ('duration', models.TimeField(null=True, blank=True, verbose_name='durée')),
 | 
			
		||||
                ('public', models.BooleanField(default=False, help_text='the element is public', verbose_name='public')),
 | 
			
		||||
                ('fragment', models.BooleanField(default=False, help_text='the file is a cut', verbose_name='son incomplet')),
 | 
			
		||||
                ('removed', models.BooleanField(default=False, help_text='this sound has been removed from filesystem')),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                'verbose_name': 'Sound',
 | 
			
		||||
                'verbose_name_plural': 'Sounds',
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='Stream',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
 | 
			
		||||
                ('name', models.CharField(null=True, blank=True, verbose_name='nom', max_length=32)),
 | 
			
		||||
                ('public', models.BooleanField(default=True, help_text='program list is public', verbose_name='public')),
 | 
			
		||||
                ('type', models.SmallIntegerField(choices=[(1, 'schedule'), (0, 'random')], verbose_name='type')),
 | 
			
		||||
                ('priority', models.SmallIntegerField(default=0, help_text='priority of the stream', verbose_name='priority')),
 | 
			
		||||
            ],
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='Track',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
 | 
			
		||||
                ('name', models.CharField(verbose_name='nom', max_length=128)),
 | 
			
		||||
                ('artist', models.CharField(verbose_name='artiste', max_length=128)),
 | 
			
		||||
                ('position', models.SmallIntegerField(default=0, help_text='position in the playlist')),
 | 
			
		||||
                ('episode', models.ForeignKey(to='aircox_programs.Episode')),
 | 
			
		||||
                ('tags', taggit.managers.TaggableManager(through='taggit.TaggedItem', to='taggit.Tag', blank=True, help_text='A comma-separated list of tags.', verbose_name='mots-clés')),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                'verbose_name': 'Track',
 | 
			
		||||
                'verbose_name_plural': 'Tracks',
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='program',
 | 
			
		||||
            name='stream',
 | 
			
		||||
            field=models.ForeignKey(to='aircox_programs.Stream', verbose_name='stream'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='episode',
 | 
			
		||||
            name='program',
 | 
			
		||||
            field=models.ForeignKey(to='aircox_programs.Program', help_text='parent program', verbose_name='program'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='episode',
 | 
			
		||||
            name='sounds',
 | 
			
		||||
            field=models.ManyToManyField(to='aircox_programs.Sound', blank=True, verbose_name='sounds'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='diffusion',
 | 
			
		||||
            name='episode',
 | 
			
		||||
            field=models.ForeignKey(to='aircox_programs.Episode', null=True, blank=True, verbose_name='épisode'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='diffusion',
 | 
			
		||||
            name='program',
 | 
			
		||||
            field=models.ForeignKey(to='aircox_programs.Program', verbose_name='program'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='diffusion',
 | 
			
		||||
            name='stream',
 | 
			
		||||
            field=models.ForeignKey(default=0, help_text='stream id on which the diffusion happens', to='aircox_programs.Stream', verbose_name='stream'),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
							
								
								
									
										24
									
								
								aircox_programs/migrations/0002_auto_20151003_1248.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								aircox_programs/migrations/0002_auto_20151003_1248.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
# -*- coding: utf-8 -*-
 | 
			
		||||
from __future__ import unicode_literals
 | 
			
		||||
 | 
			
		||||
from django.db import models, migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('aircox_programs', '0001_initial'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name='diffusion',
 | 
			
		||||
            name='type',
 | 
			
		||||
            field=models.SmallIntegerField(choices=[(4, 'stop'), (2, 'cancel'), (1, 'unconfirmed'), (0, 'default')], verbose_name='type'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name='schedule',
 | 
			
		||||
            name='frequency',
 | 
			
		||||
            field=models.SmallIntegerField(choices=[(31, 'every'), (8, 'fourth'), (5, 'first and third'), (10, 'second and fourth'), (16, 'last'), (32, 'one on two'), (4, 'third'), (1, 'first'), (2, 'second')], verbose_name='fréquence'),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
							
								
								
									
										0
									
								
								aircox_programs/migrations/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								aircox_programs/migrations/__init__.py
									
									
									
									
									
										Normal file
									
								
							@ -8,7 +8,7 @@ from django.utils.html import strip_tags
 | 
			
		||||
 | 
			
		||||
from taggit.managers import TaggableManager
 | 
			
		||||
 | 
			
		||||
import programs.settings as settings
 | 
			
		||||
import aircox_programs.settings as settings
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def date_or_default (date, date_only = False):
 | 
			
		||||
							
								
								
									
										3
									
								
								aircox_programs/tests.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										3
									
								
								aircox_programs/tests.py
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
from django.test import TestCase
 | 
			
		||||
 | 
			
		||||
# Create your tests here.
 | 
			
		||||
							
								
								
									
										6
									
								
								aircox_programs/utils.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								aircox_programs/utils.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
 | 
			
		||||
def ensure_list (value):
 | 
			
		||||
    if type(value) in (list, set, tuple):
 | 
			
		||||
        return value
 | 
			
		||||
    return [value]
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										90
									
								
								aircox_programs/views.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										90
									
								
								aircox_programs/views.py
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,90 @@
 | 
			
		||||
from django.db                      import models
 | 
			
		||||
from django.shortcuts               import render
 | 
			
		||||
from django.core.serializers.json   import DjangoJSONEncoder
 | 
			
		||||
from django.utils                   import timezone, dateformat
 | 
			
		||||
 | 
			
		||||
from django.views.generic           import ListView
 | 
			
		||||
from django.views.generic           import DetailView
 | 
			
		||||
from django.utils.translation       import ugettext as _, ugettext_lazy
 | 
			
		||||
 | 
			
		||||
from aircox_programs.models                import *
 | 
			
		||||
import aircox_programs.settings
 | 
			
		||||
import aircox_programs.utils
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListQueries:
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def search (qs, q):
 | 
			
		||||
        qs = qs.filter(tags__slug__in = re.compile(r'(\s|\+)+').split(q)) | \
 | 
			
		||||
             qs.filter(title__icontains = q) | \
 | 
			
		||||
             qs.filter(subtitle__icontains = q) | \
 | 
			
		||||
             qs.filter(content__icontains = q)
 | 
			
		||||
        qs.distinct()
 | 
			
		||||
        return qs
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def thread (qs, q):
 | 
			
		||||
        return qs.filter(parent = q)
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def next (qs, q):
 | 
			
		||||
        qs = qs.filter(date__gte = timezone.now())
 | 
			
		||||
        if q:
 | 
			
		||||
            qs = qs.filter(parent = q)
 | 
			
		||||
        return qs
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def prev (qs, q):
 | 
			
		||||
        qs = qs.filter(date__lte = timezone.now())
 | 
			
		||||
        if q:
 | 
			
		||||
            qs = qs.filter(parent = q)
 | 
			
		||||
        return qs
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def date (qs, q):
 | 
			
		||||
        if not q:
 | 
			
		||||
            q = timezone.datetime.today()
 | 
			
		||||
        if type(q) is str:
 | 
			
		||||
            q = timezone.datetime.strptime(q, '%Y/%m/%d').date()
 | 
			
		||||
 | 
			
		||||
        return qs.filter(date__startswith = q)
 | 
			
		||||
 | 
			
		||||
    class Diffusion:
 | 
			
		||||
        @staticmethod
 | 
			
		||||
        def episode (qs, q):
 | 
			
		||||
            return qs.filter(episode = q)
 | 
			
		||||
 | 
			
		||||
        @staticmethod
 | 
			
		||||
        def program (qs, q):
 | 
			
		||||
            return qs.filter(program = q)
 | 
			
		||||
 | 
			
		||||
class ListQuery:
 | 
			
		||||
    model = None
 | 
			
		||||
    qs = None
 | 
			
		||||
 | 
			
		||||
    def __init__ (self, model, *kwargs):
 | 
			
		||||
        self.model = model
 | 
			
		||||
        self.__dict__.update(kwargs)
 | 
			
		||||
 | 
			
		||||
    def get_queryset (self, by, q):
 | 
			
		||||
        qs = model.objects.all()
 | 
			
		||||
        if model._meta.get_field_by_name('public'):
 | 
			
		||||
            qs = qs.filter(public = True)
 | 
			
		||||
 | 
			
		||||
        # run query set
 | 
			
		||||
        queries = Queries.__dict__.get(self.model) or Queries
 | 
			
		||||
        filter = queries.__dict__.get(by)
 | 
			
		||||
        if filter:
 | 
			
		||||
            qs = filter(qs, q)
 | 
			
		||||
 | 
			
		||||
        # order
 | 
			
		||||
        if self.sort == 'asc':
 | 
			
		||||
            qs = qs.order_by('date', 'id')
 | 
			
		||||
        else:
 | 
			
		||||
            qs = qs.order_by('-date', '-id')
 | 
			
		||||
 | 
			
		||||
        # exclude
 | 
			
		||||
        qs = qs.exclude(id = exclude)
 | 
			
		||||
        return qs
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,49 +0,0 @@
 | 
			
		||||
This application defines all base classes for the aircox platform. This includes:
 | 
			
		||||
* **Metadata**:         generic class that contains metadata
 | 
			
		||||
* **Publication**:      generic class for models that can be publicated
 | 
			
		||||
* **Track**:            informations on a track in a playlist
 | 
			
		||||
* **SoundFile**:        informations on a sound (podcast)
 | 
			
		||||
* **Schedule**:         schedule informations for programs
 | 
			
		||||
* **Article**:          simple article
 | 
			
		||||
* **Program**:          radio program
 | 
			
		||||
* **Episode**:          occurence of a radio program
 | 
			
		||||
* **Event**:            log info on what has been or what should be played
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Program
 | 
			
		||||
Each program has a directory in **AIRCOX_PROGRAMS_DATA**; For each, subdir:
 | 
			
		||||
* **public**:   public sound files and data (accessible from the website)
 | 
			
		||||
* **private**:  private sound files and data
 | 
			
		||||
* **podcasts**: podcasts that can be upload to external plateforms
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Event
 | 
			
		||||
Event have a double purpose:
 | 
			
		||||
- log played sounds
 | 
			
		||||
- plannify diffusions
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# manage.py schedule
 | 
			
		||||
Return the next songs to be played and the schedule and the programmed emissions
 | 
			
		||||
 | 
			
		||||
# manage.py monitor
 | 
			
		||||
The manage.py has a command **monitor** that:
 | 
			
		||||
* check for new sound files
 | 
			
		||||
* stat the sound files
 | 
			
		||||
* match sound files against episodes and eventually program them
 | 
			
		||||
* upload public podcasts to mixcloud if required
 | 
			
		||||
 | 
			
		||||
The command will try to match file name against a planified episode by detecting
 | 
			
		||||
a date (ISO 8601 date notation YYYY-MM-DD or YYYYMMDD) as name prefix
 | 
			
		||||
 | 
			
		||||
Tags set:
 | 
			
		||||
* **incorrect**:    the sound is not correct for diffusion (TODO: parameters)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							@ -1,237 +0,0 @@
 | 
			
		||||
# SOME DESCRIPTIVE TITLE.
 | 
			
		||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 | 
			
		||||
# This file is distributed under the same license as the PACKAGE package.
 | 
			
		||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
 | 
			
		||||
#
 | 
			
		||||
#, fuzzy
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: PACKAGE VERSION\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: \n"
 | 
			
		||||
"POT-Creation-Date: 2014-09-02 17:05+0200\n"
 | 
			
		||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 | 
			
		||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 | 
			
		||||
"Language-Team: LANGUAGE <LL@li.org>\n"
 | 
			
		||||
"Language: \n"
 | 
			
		||||
"MIME-Version: 1.0\n"
 | 
			
		||||
"Content-Type: text/plain; charset=UTF-8\n"
 | 
			
		||||
"Content-Transfer-Encoding: 8bit\n"
 | 
			
		||||
 | 
			
		||||
#: models.py:51
 | 
			
		||||
msgid "ponctual"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: models.py:52
 | 
			
		||||
msgid "every week"
 | 
			
		||||
msgstr "toutes les semaines"
 | 
			
		||||
 | 
			
		||||
#: models.py:53
 | 
			
		||||
msgid "first week"
 | 
			
		||||
msgstr "1<sup>ère</sup> semaine du mois"
 | 
			
		||||
 | 
			
		||||
#: models.py:54
 | 
			
		||||
msgid "second week"
 | 
			
		||||
msgstr "2<sup>ème</sup> semaine du mois"
 | 
			
		||||
 | 
			
		||||
#: models.py:55
 | 
			
		||||
msgid "third week"
 | 
			
		||||
msgstr "3<sup>ème</sup> semaine du mois"
 | 
			
		||||
 | 
			
		||||
#: models.py:56
 | 
			
		||||
msgid "fourth week"
 | 
			
		||||
msgstr "4<sup>ème</sup> semaine du mois"
 | 
			
		||||
 | 
			
		||||
#: models.py:57
 | 
			
		||||
msgid "first and third"
 | 
			
		||||
msgstr "la 1<sup>ère</sup> et 2<sup>ème</sup> semaine du mois"
 | 
			
		||||
 | 
			
		||||
#: models.py:58
 | 
			
		||||
msgid "second and fourth"
 | 
			
		||||
msgstr "la 2<sup>ème</sup> et 4<sup>ème</sup> semaine du mois"
 | 
			
		||||
 | 
			
		||||
#: models.py:59
 | 
			
		||||
msgid "one week on two"
 | 
			
		||||
msgstr "une semaine sur deux"
 | 
			
		||||
 | 
			
		||||
#: models.py:74
 | 
			
		||||
msgid "author"
 | 
			
		||||
msgstr "auteur"
 | 
			
		||||
 | 
			
		||||
#: models.py:78 models.py:568
 | 
			
		||||
msgid "date"
 | 
			
		||||
msgstr "date"
 | 
			
		||||
 | 
			
		||||
#: models.py:81 models.py:332
 | 
			
		||||
msgid "title"
 | 
			
		||||
msgstr "titre"
 | 
			
		||||
 | 
			
		||||
#: models.py:89 models.py:565
 | 
			
		||||
msgid "meta"
 | 
			
		||||
msgstr "metadonnées"
 | 
			
		||||
 | 
			
		||||
#: models.py:93
 | 
			
		||||
msgid "tags"
 | 
			
		||||
msgstr "mots-clés"
 | 
			
		||||
 | 
			
		||||
#: models.py:125
 | 
			
		||||
msgid "subtitle"
 | 
			
		||||
msgstr "sous-titre"
 | 
			
		||||
 | 
			
		||||
#: models.py:129
 | 
			
		||||
msgid "image"
 | 
			
		||||
msgstr "image"
 | 
			
		||||
 | 
			
		||||
#: models.py:133
 | 
			
		||||
msgid "content"
 | 
			
		||||
msgstr "contenu"
 | 
			
		||||
 | 
			
		||||
#: models.py:136 models.py:575
 | 
			
		||||
msgid "status"
 | 
			
		||||
msgstr "statut"
 | 
			
		||||
 | 
			
		||||
#: models.py:140
 | 
			
		||||
msgid "enable comments"
 | 
			
		||||
msgstr "activer les commentaires"
 | 
			
		||||
 | 
			
		||||
#: models.py:328
 | 
			
		||||
msgid "artist"
 | 
			
		||||
msgstr "artiste"
 | 
			
		||||
 | 
			
		||||
#: models.py:335
 | 
			
		||||
msgid "version"
 | 
			
		||||
msgstr "version"
 | 
			
		||||
 | 
			
		||||
#: models.py:338
 | 
			
		||||
msgid "additional informations on that track"
 | 
			
		||||
msgstr "informations supplémentaires sur cette piste"
 | 
			
		||||
 | 
			
		||||
#: models.py:343
 | 
			
		||||
msgid "by"
 | 
			
		||||
msgstr "par"
 | 
			
		||||
 | 
			
		||||
#: models.py:348
 | 
			
		||||
msgid "track"
 | 
			
		||||
msgstr "piste"
 | 
			
		||||
 | 
			
		||||
#: models.py:349
 | 
			
		||||
msgid "tracks"
 | 
			
		||||
msgstr "pistes"
 | 
			
		||||
 | 
			
		||||
#: models.py:356
 | 
			
		||||
msgid "file"
 | 
			
		||||
msgstr "fichier"
 | 
			
		||||
 | 
			
		||||
#: models.py:360 models.py:380 models.py:570
 | 
			
		||||
msgid "duration"
 | 
			
		||||
msgstr "durée"
 | 
			
		||||
 | 
			
		||||
#: models.py:364
 | 
			
		||||
msgid "podcastable"
 | 
			
		||||
msgstr "peut être podcasté"
 | 
			
		||||
 | 
			
		||||
#: models.py:366
 | 
			
		||||
msgid "if checked, the file can be podcasted"
 | 
			
		||||
msgstr "si coché, le fichier peut être podcasté"
 | 
			
		||||
 | 
			
		||||
#: models.py:368
 | 
			
		||||
msgid "incomplete sound"
 | 
			
		||||
msgstr "son incomplet"
 | 
			
		||||
 | 
			
		||||
#: models.py:370
 | 
			
		||||
msgid "the file has been cut"
 | 
			
		||||
msgstr "le fichier a été monté"
 | 
			
		||||
 | 
			
		||||
#: models.py:378
 | 
			
		||||
msgid "schedule"
 | 
			
		||||
msgstr "horaire"
 | 
			
		||||
 | 
			
		||||
#: models.py:379
 | 
			
		||||
msgid "frequency"
 | 
			
		||||
msgstr "fréquence"
 | 
			
		||||
 | 
			
		||||
#: models.py:381 models.py:452
 | 
			
		||||
msgid "rerun"
 | 
			
		||||
msgstr "rediffusion"
 | 
			
		||||
 | 
			
		||||
#: models.py:464 models.py:485 models.py:524
 | 
			
		||||
msgid "parent"
 | 
			
		||||
msgstr "parent"
 | 
			
		||||
 | 
			
		||||
#: models.py:468
 | 
			
		||||
msgid "static page"
 | 
			
		||||
msgstr "page statique"
 | 
			
		||||
 | 
			
		||||
#: models.py:471
 | 
			
		||||
msgid "article is focus"
 | 
			
		||||
msgstr "l'article est épinglé"
 | 
			
		||||
 | 
			
		||||
#: models.py:477
 | 
			
		||||
msgid "Article"
 | 
			
		||||
msgstr "Article"
 | 
			
		||||
 | 
			
		||||
#: models.py:478
 | 
			
		||||
msgid "Articles"
 | 
			
		||||
msgstr "Articles"
 | 
			
		||||
 | 
			
		||||
#: models.py:490
 | 
			
		||||
msgid "email"
 | 
			
		||||
msgstr "email"
 | 
			
		||||
 | 
			
		||||
#: models.py:495
 | 
			
		||||
msgid "website"
 | 
			
		||||
msgstr "site"
 | 
			
		||||
 | 
			
		||||
#: models.py:499
 | 
			
		||||
msgid "tag"
 | 
			
		||||
msgstr "mot-clé"
 | 
			
		||||
 | 
			
		||||
#: models.py:501
 | 
			
		||||
msgid "used in articles to refer to it"
 | 
			
		||||
msgstr "utilisé par les articles pour y faire référence"
 | 
			
		||||
 | 
			
		||||
#: models.py:510
 | 
			
		||||
msgid "Emission"
 | 
			
		||||
msgstr "Émission"
 | 
			
		||||
 | 
			
		||||
#: models.py:511
 | 
			
		||||
msgid "Emissions"
 | 
			
		||||
msgstr "Émissions"
 | 
			
		||||
 | 
			
		||||
#: models.py:529
 | 
			
		||||
msgid "podcast file"
 | 
			
		||||
msgstr "fichier de podcast"
 | 
			
		||||
 | 
			
		||||
#: models.py:534
 | 
			
		||||
msgid "playlist"
 | 
			
		||||
msgstr "playlist"
 | 
			
		||||
 | 
			
		||||
#: models.py:543
 | 
			
		||||
#, python-format
 | 
			
		||||
msgid "An unknown name for this episode of %s"
 | 
			
		||||
msgstr "Cette épisode de %s n'a pas encore de nom"
 | 
			
		||||
 | 
			
		||||
#: models.py:551
 | 
			
		||||
msgid "Episode"
 | 
			
		||||
msgstr "Épisode"
 | 
			
		||||
 | 
			
		||||
#: models.py:552
 | 
			
		||||
msgid "Episodes"
 | 
			
		||||
msgstr "Épisodes"
 | 
			
		||||
 | 
			
		||||
#: models.py:561
 | 
			
		||||
msgid "episode"
 | 
			
		||||
msgstr "épisode"
 | 
			
		||||
 | 
			
		||||
#: models.py:573
 | 
			
		||||
msgid "this is just indicative"
 | 
			
		||||
msgstr "juste indicatif"
 | 
			
		||||
 | 
			
		||||
#: models.py:578
 | 
			
		||||
msgid "canceled"
 | 
			
		||||
msgstr "annulé"
 | 
			
		||||
 | 
			
		||||
#~ msgid "third %s of the month"
 | 
			
		||||
#~ msgstr "le troisième %s du mois"
 | 
			
		||||
 | 
			
		||||
#~ msgid "fourth %s of the month"
 | 
			
		||||
#~ msgstr "le quatrième %s du mois"
 | 
			
		||||
@ -1,5 +0,0 @@
 | 
			
		||||
Django>=1.9.0
 | 
			
		||||
django-taggit>=0.12.1
 | 
			
		||||
django-autocomplete-light>=2.2.5
 | 
			
		||||
django-suit>=0.2.14
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ from django.contrib import admin
 | 
			
		||||
from django.utils.translation import ugettext as _, ugettext_lazy
 | 
			
		||||
from django.contrib.contenttypes.admin import GenericStackedInline
 | 
			
		||||
 | 
			
		||||
import programs.models as programs
 | 
			
		||||
import aircox_programs.models as programs
 | 
			
		||||
from website.models import *
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
from django.db import models
 | 
			
		||||
 | 
			
		||||
from cms.models import RelatedPost
 | 
			
		||||
import programs.models as programs
 | 
			
		||||
from aircox_cms.models import RelatedPost
 | 
			
		||||
import aircox_programs.models as programs
 | 
			
		||||
 | 
			
		||||
class Program (RelatedPost):
 | 
			
		||||
    class Relation:
 | 
			
		||||
 | 
			
		||||
@ -3,10 +3,10 @@ from django.conf.urls import url, include
 | 
			
		||||
from website.models import *
 | 
			
		||||
from website.views import *
 | 
			
		||||
 | 
			
		||||
from cms.models import Article
 | 
			
		||||
from cms.views import ViewSet, Menu, Section
 | 
			
		||||
from cms.routes import *
 | 
			
		||||
from cms.website import Website
 | 
			
		||||
from aircox_cms.models import Article
 | 
			
		||||
from aircox_cms.views import ViewSet, Menu, Section
 | 
			
		||||
from aircox_cms.routes import *
 | 
			
		||||
from aircox_cms.website import Website
 | 
			
		||||
 | 
			
		||||
class ProgramSet (ViewSet):
 | 
			
		||||
    model = Program
 | 
			
		||||
 | 
			
		||||
@ -5,8 +5,8 @@ from django.views.generic import DetailView
 | 
			
		||||
from django.core import serializers
 | 
			
		||||
from django.utils.translation import ugettext as _, ugettext_lazy
 | 
			
		||||
 | 
			
		||||
import programs.models as programs
 | 
			
		||||
from cms.views import ListSection
 | 
			
		||||
import aircox_programs.models as programs
 | 
			
		||||
from aircox_cms.views import ListSection
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PlaylistSection (ListSection):
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user