diff --git a/programs/__init__.py b/aircox_cms/__init__.py
old mode 100755
new mode 100644
similarity index 100%
rename from programs/__init__.py
rename to aircox_cms/__init__.py
diff --git a/cms/admin.py b/aircox_cms/admin.py
similarity index 100%
rename from cms/admin.py
rename to aircox_cms/admin.py
diff --git a/aircox_cms/migrations/0001_initial.py b/aircox_cms/migrations/0001_initial.py
new file mode 100644
index 0000000..28ad7d2
--- /dev/null
+++ b/aircox_cms/migrations/0001_initial.py
@@ -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'),
+ ),
+ ]
diff --git a/programs/management/__init__.py b/aircox_cms/migrations/__init__.py
similarity index 100%
rename from programs/management/__init__.py
rename to aircox_cms/migrations/__init__.py
diff --git a/cms/models.py b/aircox_cms/models.py
similarity index 100%
rename from cms/models.py
rename to aircox_cms/models.py
diff --git a/cms/routes.py b/aircox_cms/routes.py
similarity index 100%
rename from cms/routes.py
rename to aircox_cms/routes.py
diff --git a/aircox_cms/static/aircox_cms/styles.css b/aircox_cms/static/aircox_cms/styles.css
new file mode 100644
index 0000000..54d97e3
--- /dev/null
+++ b/aircox_cms/static/aircox_cms/styles.css
@@ -0,0 +1,10 @@
+body { padding: 0; margin: 0; }
+
+nav.menu_top {
+ width: 100%
+ position: absolute;
+ border-bottom: 1px grey solid;
+}
+
+
+
diff --git a/cms/templates/cms/base_content.html b/aircox_cms/templates/aircox_cms/base_content.html
similarity index 100%
rename from cms/templates/cms/base_content.html
rename to aircox_cms/templates/aircox_cms/base_content.html
diff --git a/cms/templates/cms/base_site.html b/aircox_cms/templates/aircox_cms/base_site.html
similarity index 68%
rename from cms/templates/cms/base_site.html
rename to aircox_cms/templates/aircox_cms/base_site.html
index 31d738d..3646555 100644
--- a/cms/templates/cms/base_site.html
+++ b/aircox_cms/templates/aircox_cms/base_site.html
@@ -1,5 +1,14 @@
+{% load staticfiles %}
+
+ {# FIXME: page tags #}
+
+
+
+
+
+
{{ website.name }} {% if title %}- {{ title }} {% endif %}
@@ -35,6 +44,10 @@
{% endblock %}
+
+ {% if menus.right %}
+ {{ menus.right|safe }}
+ {% endif %}
{% block footer %}
@@ -44,6 +57,10 @@
{% endif %}
{% endblock %}
+
+ {% if menus.bottom %}
+ {{ menus.bottom|safe }}
+ {% endif %}
diff --git a/cms/templates/cms/detail.html b/aircox_cms/templates/aircox_cms/detail.html
similarity index 78%
rename from cms/templates/cms/detail.html
rename to aircox_cms/templates/aircox_cms/detail.html
index 2653b86..c022427 100644
--- a/cms/templates/cms/detail.html
+++ b/aircox_cms/templates/aircox_cms/detail.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 }}
diff --git a/cms/templates/cms/embed.html b/aircox_cms/templates/aircox_cms/embed.html
similarity index 100%
rename from cms/templates/cms/embed.html
rename to aircox_cms/templates/aircox_cms/embed.html
diff --git a/cms/templates/cms/list.html b/aircox_cms/templates/aircox_cms/list.html
similarity index 93%
rename from cms/templates/cms/list.html
rename to aircox_cms/templates/aircox_cms/list.html
index bb4731a..de33a17 100644
--- a/cms/templates/cms/list.html
+++ b/aircox_cms/templates/aircox_cms/list.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" %}
{% load i18n %}
{% load thumbnail %}
diff --git a/cms/templates/cms/menu.html b/aircox_cms/templates/aircox_cms/menu.html
similarity index 100%
rename from cms/templates/cms/menu.html
rename to aircox_cms/templates/aircox_cms/menu.html
diff --git a/cms/templates/cms/section.html b/aircox_cms/templates/aircox_cms/section.html
similarity index 100%
rename from cms/templates/cms/section.html
rename to aircox_cms/templates/aircox_cms/section.html
diff --git a/cms/templates/cms/section_list.html b/aircox_cms/templates/aircox_cms/section_list.html
similarity index 91%
rename from cms/templates/cms/section_list.html
rename to aircox_cms/templates/aircox_cms/section_list.html
index ad410e2..46479af 100644
--- a/cms/templates/cms/section_list.html
+++ b/aircox_cms/templates/aircox_cms/section_list.html
@@ -1,4 +1,4 @@
-{% extends "cms/section.html" %}
+{% extends "aircox_cms/section.html" %}
{% load thumbnail %}
diff --git a/aircox_cms/templates/aircox_cms/tags b/aircox_cms/templates/aircox_cms/tags
new file mode 100644
index 0000000..d01d39b
--- /dev/null
+++ b/aircox_cms/templates/aircox_cms/tags
@@ -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 //
diff --git a/programs/tests.py b/aircox_cms/tests.py
old mode 100755
new mode 100644
similarity index 100%
rename from programs/tests.py
rename to aircox_cms/tests.py
diff --git a/cms/views.py b/aircox_cms/views.py
similarity index 95%
rename from cms/views.py
rename to aircox_cms/views.py
index 8eefe68..ba95209 100644
--- a/cms/views.py
+++ b/aircox_cms/views.py
@@ -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 []
diff --git a/cms/website.py b/aircox_cms/website.py
similarity index 81%
rename from cms/website.py
rename to aircox_cms/website.py
index c87f566..fe3f877 100644
--- a/cms/website.py
+++ b/aircox_cms/website.py
@@ -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
diff --git a/programs/management/commands/__init__.py b/aircox_programs/__init__.py
old mode 100644
new mode 100755
similarity index 100%
rename from programs/management/commands/__init__.py
rename to aircox_programs/__init__.py
diff --git a/programs/admin.py b/aircox_programs/admin.py
similarity index 96%
rename from programs/admin.py
rename to aircox_programs/admin.py
index 6a7bf9b..65892fd 100755
--- a/programs/admin.py
+++ b/aircox_programs/admin.py
@@ -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 *
#
diff --git a/programs/autocomplete_light_registry.py b/aircox_programs/autocomplete_light_registry.py
similarity index 97%
rename from programs/autocomplete_light_registry.py
rename to aircox_programs/autocomplete_light_registry.py
index 0579c41..c90a4de 100644
--- a/programs/autocomplete_light_registry.py
+++ b/aircox_programs/autocomplete_light_registry.py
@@ -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)
diff --git a/programs/forms.py b/aircox_programs/forms.py
similarity index 93%
rename from programs/forms.py
rename to aircox_programs/forms.py
index b4df14e..89228d7 100644
--- a/programs/forms.py
+++ b/aircox_programs/forms.py
@@ -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):
diff --git a/programs/management/commands/_private.py b/aircox_programs/management/__init__.py
similarity index 100%
rename from programs/management/commands/_private.py
rename to aircox_programs/management/__init__.py
diff --git a/aircox_programs/management/commands/__init__.py b/aircox_programs/management/commands/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/aircox_programs/management/commands/_private.py b/aircox_programs/management/commands/_private.py
new file mode 100644
index 0000000..e69de29
diff --git a/programs/management/commands/diffusions_monitor.py b/aircox_programs/management/commands/diffusions_monitor.py
similarity index 98%
rename from programs/management/commands/diffusions_monitor.py
rename to aircox_programs/management/commands/diffusions_monitor.py
index 06833a1..f5bbfd3 100644
--- a/programs/management/commands/diffusions_monitor.py
+++ b/aircox_programs/management/commands/diffusions_monitor.py
@@ -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:
diff --git a/programs/management/commands/programs.py b/aircox_programs/management/commands/programs.py
similarity index 99%
rename from programs/management/commands/programs.py
rename to aircox_programs/management/commands/programs.py
index 0d190a1..21b4d65 100644
--- a/programs/management/commands/programs.py
+++ b/aircox_programs/management/commands/programs.py
@@ -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:
diff --git a/programs/management/commands/sounds_monitor.py b/aircox_programs/management/commands/sounds_monitor.py
similarity index 97%
rename from programs/management/commands/sounds_monitor.py
rename to aircox_programs/management/commands/sounds_monitor.py
index 2c460c0..3c6098b 100644
--- a/programs/management/commands/sounds_monitor.py
+++ b/aircox_programs/management/commands/sounds_monitor.py
@@ -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):
diff --git a/aircox_programs/migrations/0001_initial.py b/aircox_programs/migrations/0001_initial.py
new file mode 100644
index 0000000..890b13b
--- /dev/null
+++ b/aircox_programs/migrations/0001_initial.py
@@ -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'),
+ ),
+ ]
diff --git a/aircox_programs/migrations/0002_auto_20151003_1248.py b/aircox_programs/migrations/0002_auto_20151003_1248.py
new file mode 100644
index 0000000..a99881f
--- /dev/null
+++ b/aircox_programs/migrations/0002_auto_20151003_1248.py
@@ -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'),
+ ),
+ ]
diff --git a/aircox_programs/migrations/__init__.py b/aircox_programs/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/programs/models.py b/aircox_programs/models.py
similarity index 99%
rename from programs/models.py
rename to aircox_programs/models.py
index 4767cf0..83599a3 100755
--- a/programs/models.py
+++ b/aircox_programs/models.py
@@ -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):
diff --git a/programs/settings.py b/aircox_programs/settings.py
similarity index 100%
rename from programs/settings.py
rename to aircox_programs/settings.py
diff --git a/aircox_programs/tests.py b/aircox_programs/tests.py
new file mode 100755
index 0000000..7ce503c
--- /dev/null
+++ b/aircox_programs/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/aircox_programs/utils.py b/aircox_programs/utils.py
new file mode 100644
index 0000000..06fc204
--- /dev/null
+++ b/aircox_programs/utils.py
@@ -0,0 +1,6 @@
+
+def ensure_list (value):
+ if type(value) in (list, set, tuple):
+ return value
+ return [value]
+
diff --git a/aircox_programs/views.py b/aircox_programs/views.py
new file mode 100755
index 0000000..ff3f16d
--- /dev/null
+++ b/aircox_programs/views.py
@@ -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
+
+
diff --git a/programs/README.md b/programs/README.md
deleted file mode 100644
index b0240df..0000000
--- a/programs/README.md
+++ /dev/null
@@ -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)
-
-
-
-
-
-
-
-
-
diff --git a/programs/locale/fr_BE/LC_MESSAGES/django.mo b/programs/locale/fr_BE/LC_MESSAGES/django.mo
deleted file mode 100644
index cfd3e6d..0000000
Binary files a/programs/locale/fr_BE/LC_MESSAGES/django.mo and /dev/null differ
diff --git a/programs/locale/fr_BE/LC_MESSAGES/django.po b/programs/locale/fr_BE/LC_MESSAGES/django.po
deleted file mode 100644
index d1aaa76..0000000
--- a/programs/locale/fr_BE/LC_MESSAGES/django.po
+++ /dev/null
@@ -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 , 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 \n"
-"Language-Team: LANGUAGE \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ère semaine du mois"
-
-#: models.py:54
-msgid "second week"
-msgstr "2ème semaine du mois"
-
-#: models.py:55
-msgid "third week"
-msgstr "3ème semaine du mois"
-
-#: models.py:56
-msgid "fourth week"
-msgstr "4ème semaine du mois"
-
-#: models.py:57
-msgid "first and third"
-msgstr "la 1ère et 2ème semaine du mois"
-
-#: models.py:58
-msgid "second and fourth"
-msgstr "la 2ème et 4ème 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"
diff --git a/programs/requirements.txt b/programs/requirements.txt
deleted file mode 100644
index 0ff759d..0000000
--- a/programs/requirements.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Django>=1.9.0
-django-taggit>=0.12.1
-django-autocomplete-light>=2.2.5
-django-suit>=0.2.14
-
diff --git a/website/admin.py b/website/admin.py
index 4fe28b5..b0f42b0 100644
--- a/website/admin.py
+++ b/website/admin.py
@@ -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 *
diff --git a/website/models.py b/website/models.py
index c863df8..56428ea 100644
--- a/website/models.py
+++ b/website/models.py
@@ -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:
diff --git a/website/urls.py b/website/urls.py
index 94f4e38..7743b78 100644
--- a/website/urls.py
+++ b/website/urls.py
@@ -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
diff --git a/website/views.py b/website/views.py
index 1965572..dd7c3b3 100644
--- a/website/views.py
+++ b/website/views.py
@@ -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):