rename
This commit is contained in:
parent
f9d2d47ee6
commit
1a5dcc3eb9
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>
|
<html>
|
||||||
<head>
|
<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>
|
<title>{{ website.name }} {% if title %}- {{ title }} {% endif %}</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -35,6 +44,10 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
{% if menus.right %}
|
||||||
|
{{ menus.right|safe }}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% block footer %}
|
{% block footer %}
|
||||||
|
@ -44,6 +57,10 @@
|
||||||
</footer>
|
</footer>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% if menus.bottom %}
|
||||||
|
{{ menus.bottom|safe }}
|
||||||
|
{% endif %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</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 %}
|
{% block title %}
|
||||||
{{ object.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 i18n %}
|
||||||
{% load thumbnail %}
|
{% load thumbnail %}
|
|
@ -1,4 +1,4 @@
|
||||||
{% extends "cms/section.html" %}
|
{% extends "aircox_cms/section.html" %}
|
||||||
|
|
||||||
{% load thumbnail %}
|
{% 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.core import serializers
|
||||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||||
|
|
||||||
import cms.routes as routes
|
import aircox_cms.routes as routes
|
||||||
|
|
||||||
|
|
||||||
class PostBaseView:
|
class PostBaseView:
|
||||||
|
@ -67,7 +67,7 @@ class PostListView (PostBaseView, ListView):
|
||||||
return
|
return
|
||||||
self.__dict__.update(query)
|
self.__dict__.update(query)
|
||||||
|
|
||||||
template_name = 'cms/list.html'
|
template_name = 'aircox_cms/list.html'
|
||||||
allow_empty = True
|
allow_empty = True
|
||||||
|
|
||||||
route = None
|
route = None
|
||||||
|
@ -127,7 +127,7 @@ class PostDetailView (DetailView, PostBaseView):
|
||||||
"""
|
"""
|
||||||
Detail view for posts and children
|
Detail view for posts and children
|
||||||
"""
|
"""
|
||||||
template_name = 'cms/detail.html'
|
template_name = 'aircox_cms/detail.html'
|
||||||
|
|
||||||
sections = []
|
sections = []
|
||||||
|
|
||||||
|
@ -135,9 +135,12 @@ class PostDetailView (DetailView, PostBaseView):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.sections = sections or []
|
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:
|
if self.model:
|
||||||
return super().get_queryset(**kwargs).filter(published = True)
|
return super().get_queryset().filter(published = True)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def get_object (self, **kwargs):
|
def get_object (self, **kwargs):
|
||||||
|
@ -193,7 +196,7 @@ class ViewSet:
|
||||||
|
|
||||||
|
|
||||||
class Menu (View):
|
class Menu (View):
|
||||||
template_name = 'cms/menu.html'
|
template_name = 'aircox_cms/menu.html'
|
||||||
|
|
||||||
name = ''
|
name = ''
|
||||||
enabled = True
|
enabled = True
|
||||||
|
@ -227,7 +230,7 @@ class Section (View):
|
||||||
Base class for sections. Sections are view that can be used in detail view
|
Base class for sections. Sections are view that can be used in detail view
|
||||||
in order to have extra content about a post.
|
in order to have extra content about a post.
|
||||||
"""
|
"""
|
||||||
template_name = 'cms/section.html'
|
template_name = 'aircox_cms/section.html'
|
||||||
require_object = False
|
require_object = False
|
||||||
object = None
|
object = None
|
||||||
classes = ''
|
classes = ''
|
||||||
|
@ -271,7 +274,7 @@ class ListSection (Section):
|
||||||
|
|
||||||
use_icons = True
|
use_icons = True
|
||||||
icon_size = '32x32'
|
icon_size = '32x32'
|
||||||
template_name = 'cms/section_list.html'
|
template_name = 'aircox_cms/section_list.html'
|
||||||
|
|
||||||
def get_object_list (self):
|
def get_object_list (self):
|
||||||
return []
|
return []
|
|
@ -1,8 +1,11 @@
|
||||||
import cms.routes as routes
|
import aircox_cms.routes as routes
|
||||||
|
|
||||||
class Website:
|
class Website:
|
||||||
name = ''
|
name = ''
|
||||||
domain = ''
|
domain = ''
|
||||||
|
description = 'An aircox website' # public description (used in meta info)
|
||||||
|
tags = 'aircox,radio,music' # public keywords (used in meta info)
|
||||||
|
|
||||||
logo = None
|
logo = None
|
||||||
menus = None
|
menus = None
|
||||||
router = 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 suit.admin import SortableTabularInline, SortableModelAdmin
|
||||||
from autocomplete_light.contrib.taggit_field import TaggitWidget, TaggitField
|
from autocomplete_light.contrib.taggit_field import TaggitWidget, TaggitField
|
||||||
|
|
||||||
from programs.forms import *
|
from aircox_programs.forms import *
|
||||||
from programs.models import *
|
from aircox_programs.models import *
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
|
@ -1,5 +1,5 @@
|
||||||
import autocomplete_light.shortcuts as al
|
import autocomplete_light.shortcuts as al
|
||||||
from programs.models import *
|
from aircox_programs.models import *
|
||||||
|
|
||||||
from taggit.models import Tag
|
from taggit.models import Tag
|
||||||
al.register(Tag)
|
al.register(Tag)
|
|
@ -4,7 +4,7 @@ from django.contrib.admin import widgets
|
||||||
import autocomplete_light.shortcuts as al
|
import autocomplete_light.shortcuts as al
|
||||||
from autocomplete_light.contrib.taggit_field import TaggitWidget
|
from autocomplete_light.contrib.taggit_field import TaggitWidget
|
||||||
|
|
||||||
from programs.models import *
|
from aircox_programs.models import *
|
||||||
|
|
||||||
|
|
||||||
class TrackForm (forms.ModelForm):
|
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 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 aircox_programs.models import *
|
||||||
|
|
||||||
|
|
||||||
class Actions:
|
class Actions:
|
|
@ -3,7 +3,7 @@ import json
|
||||||
|
|
||||||
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
|
||||||
import programs.models as models
|
import aircox_programs.models as models
|
||||||
|
|
||||||
|
|
||||||
class Model:
|
class Model:
|
|
@ -20,8 +20,8 @@ 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
|
||||||
from programs.models import *
|
from aircox_programs.models import *
|
||||||
import programs.settings as settings
|
import aircox_programs.settings as settings
|
||||||
|
|
||||||
|
|
||||||
class Command (BaseCommand):
|
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
|
from taggit.managers import TaggableManager
|
||||||
|
|
||||||
import programs.settings as settings
|
import aircox_programs.settings as settings
|
||||||
|
|
||||||
|
|
||||||
def date_or_default (date, date_only = False):
|
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.utils.translation import ugettext as _, ugettext_lazy
|
||||||
from django.contrib.contenttypes.admin import GenericStackedInline
|
from django.contrib.contenttypes.admin import GenericStackedInline
|
||||||
|
|
||||||
import programs.models as programs
|
import aircox_programs.models as programs
|
||||||
from website.models import *
|
from website.models import *
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
from cms.models import RelatedPost
|
from aircox_cms.models import RelatedPost
|
||||||
import programs.models as programs
|
import aircox_programs.models as programs
|
||||||
|
|
||||||
class Program (RelatedPost):
|
class Program (RelatedPost):
|
||||||
class Relation:
|
class Relation:
|
||||||
|
|
|
@ -3,10 +3,10 @@ from django.conf.urls import url, include
|
||||||
from website.models import *
|
from website.models import *
|
||||||
from website.views import *
|
from website.views import *
|
||||||
|
|
||||||
from cms.models import Article
|
from aircox_cms.models import Article
|
||||||
from cms.views import ViewSet, Menu, Section
|
from aircox_cms.views import ViewSet, Menu, Section
|
||||||
from cms.routes import *
|
from aircox_cms.routes import *
|
||||||
from cms.website import Website
|
from aircox_cms.website import Website
|
||||||
|
|
||||||
class ProgramSet (ViewSet):
|
class ProgramSet (ViewSet):
|
||||||
model = Program
|
model = Program
|
||||||
|
|
|
@ -5,8 +5,8 @@ from django.views.generic import DetailView
|
||||||
from django.core import serializers
|
from django.core import serializers
|
||||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||||
|
|
||||||
import programs.models as programs
|
import aircox_programs.models as programs
|
||||||
from cms.views import ListSection
|
from aircox_cms.views import ListSection
|
||||||
|
|
||||||
|
|
||||||
class PlaylistSection (ListSection):
|
class PlaylistSection (ListSection):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user