]> git.0d.be Git - panikdb.git/commitdiff
switch to standalone emissions app
authorFrédéric Péters <fpeters@0d.be>
Sat, 31 Aug 2013 09:12:38 +0000 (11:12 +0200)
committerFrédéric Péters <fpeters@0d.be>
Sat, 31 Aug 2013 09:12:38 +0000 (11:12 +0200)
48 files changed:
panikdb/aa/models.py
panikdb/emissions/__init__.py [deleted file]
panikdb/emissions/admin.py [deleted file]
panikdb/emissions/fixtures/nonstop.json [deleted file]
panikdb/emissions/forms.py [deleted file]
panikdb/emissions/management/__init__.py [deleted file]
panikdb/emissions/management/commands/__init__.py [deleted file]
panikdb/emissions/management/commands/_spip2html.py [deleted file]
panikdb/emissions/management/commands/create-sound-files.py [deleted file]
panikdb/emissions/management/commands/day-program.py [deleted file]
panikdb/emissions/management/commands/load-from-spip.py [deleted file]
panikdb/emissions/management/commands/week-program.py [deleted file]
panikdb/emissions/management/commands/whatsonair.py [deleted file]
panikdb/emissions/migrations/0001_initial.py [deleted file]
panikdb/emissions/migrations/0002_auto__add_field_emission_duration.py [deleted file]
panikdb/emissions/migrations/0003_auto__add_field_emission_email__add_field_emission_website.py [deleted file]
panikdb/emissions/migrations/0004_auto__add_field_episode_image__add_field_emission_image.py [deleted file]
panikdb/emissions/migrations/0005_auto__add_field_schedule_weeks.py [deleted file]
panikdb/emissions/migrations/0006_auto__add_newsitem__add_newscategory.py [deleted file]
panikdb/emissions/migrations/0007_auto__add_field_episode_duration__add_field_schedule_duration.py [deleted file]
panikdb/emissions/migrations/0008_auto__chg_enlarge_titles.py [deleted file]
panikdb/emissions/migrations/0009_auto__enlarge_titles_even_more.py [deleted file]
panikdb/emissions/migrations/0010_auto__add_nonstop.py [deleted file]
panikdb/emissions/migrations/0011_load_nonstop.py [deleted file]
panikdb/emissions/migrations/__init__.py [deleted file]
panikdb/emissions/models.py [deleted file]
panikdb/emissions/search_indexes.py [deleted file]
panikdb/emissions/templates/emissions/category_list.html [deleted file]
panikdb/emissions/templates/emissions/days.html [deleted file]
panikdb/emissions/templates/emissions/emission_detail.html [deleted file]
panikdb/emissions/templates/emissions/emission_form.html [deleted file]
panikdb/emissions/templates/emissions/emission_list.html [deleted file]
panikdb/emissions/templates/emissions/episode_detail.html [deleted file]
panikdb/emissions/templates/emissions/episode_form.html [deleted file]
panikdb/emissions/templates/emissions/soundfile_form.html [deleted file]
panikdb/emissions/templates/emissions/upload.html [deleted file]
panikdb/emissions/templates/search/indexes/emissions/emission_text.txt [deleted file]
panikdb/emissions/templates/search/indexes/emissions/episode_text.txt [deleted file]
panikdb/emissions/templates/search/indexes/emissions/newsitem_text.txt [deleted file]
panikdb/emissions/templatetags/__init__.py [deleted file]
panikdb/emissions/templatetags/soundfiles.py [deleted file]
panikdb/emissions/tests.py [deleted file]
panikdb/emissions/urls.py [deleted file]
panikdb/emissions/utils.py [deleted file]
panikdb/emissions/views.py [deleted file]
panikdb/settings.py
panikdb/urls.py
requirements.txt

index 712604d3880e049d13ac1c57a0fb5e5a5d21696f..bd1537cbc59e2c3e57ccec18d869b7e9ec64715f 100644 (file)
@@ -4,7 +4,7 @@ from django.contrib.auth.models import AbstractUser
 from django.core import validators
 from django.db import models
 
-from ..emissions.models import Emission
+from emissions.models import Emission
 
 class User(AbstractUser):
     emissions = models.ManyToManyField(Emission)
diff --git a/panikdb/emissions/__init__.py b/panikdb/emissions/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/panikdb/emissions/admin.py b/panikdb/emissions/admin.py
deleted file mode 100644 (file)
index 228c2b3..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-from django.contrib import admin
-
-from .models import Emission, Episode, Category, Schedule, \
-        SoundFile, NewsItem, NewsCategory, Nonstop
-
-class EmissionAdmin(admin.ModelAdmin):
-    prepopulated_fields = {'slug': ('title',)}
-
-admin.site.register(Emission, EmissionAdmin)
-
-
-class EpisodeAdmin(admin.ModelAdmin):
-    prepopulated_fields = {'slug': ('title',)}
-
-admin.site.register(Episode, EpisodeAdmin)
-
-
-class CategoryAdmin(admin.ModelAdmin):
-    pass
-
-admin.site.register(Category, CategoryAdmin)
-
-
-class ScheduleAdmin(admin.ModelAdmin):
-    pass
-
-admin.site.register(Schedule, ScheduleAdmin)
-
-
-class NewsCategoryAdmin(admin.ModelAdmin):
-    pass
-
-admin.site.register(NewsCategory, NewsCategoryAdmin)
-
-
-class NewsItemAdmin(admin.ModelAdmin):
-    pass
-
-admin.site.register(NewsItem, NewsItemAdmin)
-
-
-class SoundFileAdmin(admin.ModelAdmin):
-    pass
-
-admin.site.register(SoundFile, SoundFileAdmin)
-
-
-class NonstopAdmin(admin.ModelAdmin):
-    pass
-
-admin.site.register(Nonstop, NonstopAdmin)
diff --git a/panikdb/emissions/fixtures/nonstop.json b/panikdb/emissions/fixtures/nonstop.json
deleted file mode 100644 (file)
index 8c0352f..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-[
-    {
-        "fields": {
-            "end": "02:00:00",
-            "start": "22:00:00",
-            "title": "Biodiversit\u00e9"
-        },
-        "model": "emissions.nonstop",
-        "pk": 1
-    },
-    {
-        "fields": {
-            "end": "05:00:00",
-            "start": "02:00:00",
-            "title": "R\u00eaveries"
-        },
-        "model": "emissions.nonstop",
-        "pk": 2
-    },
-    {
-        "fields": {
-            "end": "07:30:00",
-            "start": "05:00:00",
-            "title": "La Panique"
-        },
-        "model": "emissions.nonstop",
-        "pk": 3
-    },
-    {
-        "fields": {
-            "end": "10:00:00",
-            "start": "07:30:00",
-            "title": "Matin tranquille"
-        },
-        "model": "emissions.nonstop",
-        "pk": 4
-    },
-    {
-        "fields": {
-            "end": "12:00:00",
-            "start": "10:00:00",
-            "title": "Up Beat Tempo"
-        },
-        "model": "emissions.nonstop",
-        "pk": 5
-    },
-    {
-        "fields": {
-            "end": "13:00:00",
-            "start": "12:00:00",
-            "title": "L'heure de pointe"
-        },
-        "model": "emissions.nonstop",
-        "pk": 6
-    },
-    {
-        "fields": {
-            "end": "16:00:00",
-            "start": "13:00:00",
-            "title": "Le Mange Disque"
-        },
-        "model": "emissions.nonstop",
-        "pk": 7
-    },
-    {
-        "fields": {
-            "end": "19:00:00",
-            "start": "16:00:00",
-            "title": "Hop Bop and co"
-        },
-        "model": "emissions.nonstop",
-        "pk": 8
-    },
-    {
-        "fields": {
-            "end": "22:00:00",
-            "start": "19:00:00",
-            "title": "Acouph\u00e8ne"
-        },
-        "model": "emissions.nonstop",
-        "pk": 9
-    }
-]
diff --git a/panikdb/emissions/forms.py b/panikdb/emissions/forms.py
deleted file mode 100644 (file)
index 8c64779..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-import datetime
-import re
-import unicodedata
-import os
-import uuid
-
-from django import forms
-from django.forms import fields
-
-from django.core.files.storage import DefaultStorage
-from django.core.urlresolvers import reverse
-from django.utils.safestring import mark_safe
-from django.conf import settings
-from django.template.loader import render_to_string
-
-from taggit.forms import TagWidget
-import datetimewidget.widgets
-
-from .models import Emission, Episode, Diffusion, Schedule, SoundFile
-
-
-DATETIME_OPTIONS = {
-        'format': 'dd/mm/yyyy hh:ii',
-        'language': 'fr',
-        'weekStart': '1',
-        'autoclose': 'true',
-        }
-
-class DateTimeWidget(datetimewidget.widgets.DateTimeWidget):
-    def __init__(self, *args, **kwargs):
-        super(DateTimeWidget, self).__init__(*args, options=DATETIME_OPTIONS, **kwargs)
-
-
-def slugify(s):
-    s = unicodedata.normalize('NFKD', s).encode('ascii', 'ignore').lower()
-    return re.sub(r'\W+', '-', s)
-
-
-class DayAndHourWidget(forms.MultiWidget):
-    def __init__(self, attrs=None):
-        WEEKDAYS = [u'Lundi', u'Mardi', u'Mercredi', u'Jeudi', u'Vendredi', u'Samedi', u'Dimanche']
-        widgets = (
-            forms.Select(attrs=attrs, choices=([(weekday, WEEKDAYS[weekday]) for weekday in range(7)])),
-            forms.Select(attrs=attrs, choices=([(hour, hour) for hour in range(24)])),
-            forms.Select(attrs=attrs, choices=([(minute, str(minute).zfill(2)) for minute in range(60)])),
-        )
-        super(DayAndHourWidget, self).__init__(widgets, attrs)
-
-    def decompress(self, value):
-        if value:
-            return [value.weekday(), value.hour, value.minute]
-        return [None, None, None]
-
-    def value_from_datadict(self, data, files, name):
-        # we only care about day/hour/minutes, but we conveniently use a
-        # datetime value to store that; we pick 2007 as reference year as
-        # it had its January 1st on a Monday.
-        data_list = [
-            widget.value_from_datadict(data, files, name + '_%s' % i)
-            for i, widget in enumerate(self.widgets)]
-
-        if data_list:
-            return datetime.datetime(2007, 1, int(data_list[0])+1, int(data_list[1]), int(data_list[2]))
-        return None
-
-
-class JqueryFileUploadFileInput(forms.FileInput):
-    def render(self, name, value, attrs=None):
-        output = render_to_string('emissions/upload.html', {
-            'upload_url': self.url,
-            'files': self.files,
-            'name': name,
-            'STATIC_URL': settings.STATIC_URL})
-        return mark_safe(output)
-
-
-class JqueryFileUploadInput(forms.MultiWidget):
-    needs_multipart_form = True
-    upload_id_re = re.compile(r'^[a-z0-9A-Z-]+$')
-    upload_id = None
-
-    def __init__(self, attrs=None, choices=[], max_filename_length=None):
-        self.max_filename_length = max_filename_length
-        widget_list = (forms.HiddenInput(attrs=attrs),
-                JqueryFileUploadFileInput(attrs=attrs))
-        super(JqueryFileUploadInput, self).__init__(widget_list, attrs)
-
-    def decompress(self, value):
-        # map python value to widget contents
-        if self.upload_id:
-            pass
-        elif isinstance(value, (list, tuple)) and value and value[0] is not None:
-            self.upload_id = str(value[0])
-        else:
-            self.upload_id = str(uuid.uuid4())
-        return [self.upload_id, None]
-
-    def get_files_for_id(self, upload_id):
-        storage = DefaultStorage()
-        path = os.path.join('upload', upload_id)
-        if not storage.exists(path):
-            return
-        for filepath in storage.listdir(path)[1]:
-            name = os.path.basename(filepath)
-            yield storage.open(os.path.join(path, name))
-
-    def value_from_datadict(self, data, files, name):
-        '''
-           If some file was submitted, that's the value,
-           If a regular hidden_id is present, use it to find uploaded files,
-           otherwise return an empty list
-        '''
-        upload_id, file_input = super(JqueryFileUploadInput, self).value_from_datadict(data, files, name)
-        if file_input:
-            pass
-        elif JqueryFileUploadInput.upload_id_re.match(upload_id):
-            file_input = list(self.get_files_for_id(upload_id))
-        else:
-            file_input = []
-        return file_input[0]
-
-    def render(self, name, value, attrs=None):
-        self.decompress(value)
-        self.widgets[1].url = '/upload/%s/' % self.upload_id
-        self.widgets[1].url = reverse('upload', kwargs={'transaction_id': self.upload_id})
-        if self.max_filename_length:
-            self.widgets[1].url += '?max_filename_length=%d' % self.max_filename_length
-        self.widgets[1].files = '/upload/%s/' % self.get_files_for_id(self.upload_id)
-        output = super(JqueryFileUploadInput, self).render(name, value,
-                attrs)
-        fileinput_id = '%s_%s' % (attrs['id'], '1')
-        return output
-
-
-class EmissionForm(forms.ModelForm):
-    class Meta:
-        model = Emission
-        exclude = ('slug',)
-
-    def save(self, commit=True):
-        if not self.instance.slug:
-            self.instance.slug = slugify(self.instance.title)
-        return super(EmissionForm, self).save(commit=commit)
-
-
-class EpisodeForm(forms.ModelForm):
-    class Meta:
-        model = Episode
-        exclude = ('slug',)
-        widgets = {'emission': forms.HiddenInput(),
-                   'tags': TagWidget()}
-
-    def save(self, commit=True):
-        if not self.instance.slug:
-            self.instance.slug = slugify(self.instance.title)
-        return super(EpisodeForm, self).save(commit=commit)
-
-
-class EpisodeNewForm(EpisodeForm):
-    diffusion = forms.DateTimeField(label='First Diffusion',
-            widget=DateTimeWidget)
-
-    def save(self, commit=True):
-        episode = super(EpisodeNewForm, self).save(commit=commit)
-        diffusion = Diffusion()
-        diffusion.episode_id = episode.id
-        diffusion.datetime = self.cleaned_data.get('diffusion')
-        diffusion.save()
-        return episode
-
-
-class ScheduleForm(forms.ModelForm):
-    class Meta:
-        model = Schedule
-        widgets = {
-                'emission': forms.HiddenInput(),
-                'datetime': DayAndHourWidget(),
-        }
-
-
-class SoundFileForm(forms.ModelForm):
-    class Meta:
-        model = SoundFile
-        widgets = {
-                'episode': forms.HiddenInput(),
-                'file': JqueryFileUploadInput(),
-        }
-
-
-class DiffusionForm(forms.ModelForm):
-    class Meta:
-        model = Diffusion
-        widgets = {
-                'episode': forms.HiddenInput(),
-                'datetime': DateTimeWidget(),
-        }
diff --git a/panikdb/emissions/management/__init__.py b/panikdb/emissions/management/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/panikdb/emissions/management/commands/__init__.py b/panikdb/emissions/management/commands/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/panikdb/emissions/management/commands/_spip2html.py b/panikdb/emissions/management/commands/_spip2html.py
deleted file mode 100644 (file)
index 70fdb07..0000000
+++ /dev/null
@@ -1,1073 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Code scavenged from Glasnost
-# By: Odile Bénassy <obenassy@entrouvert.com>
-#     Romain Chantereau <rchantereau@entrouvert.com>
-#     Nicolas Clapiès <nclapies@easter-eggs.org>
-#     Pierre-Antoine Dejace <padejace@entrouvert.be>
-#     Thierry Dulieu <tdulieu@easter-eggs.com>
-#     Florent Monnier <monnier@codelutin.com>
-#     Cédric Musso <cmusso@easter-eggs.org>
-#     Frédéric Péters <fpeters@entrouvert.be>
-#     Benjamin Poussin <poussin@codelutin.com>
-#     Emmanuel Raviart <eraviart@entrouvert.com>
-#     Sébastien Régnier <regnier@codelutin.com>
-#     Emmanuel Saracco <esaracco@easter-eggs.com>
-#
-# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
-# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
-#     Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
-#     Emmanuel Saracco & Théridion
-# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
-#     Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
-#     Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
-#     Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
-#     Régnier, Emmanuel Saracco, Théridion & Vecam
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-import re
-import sys
-
-_non_id_chars = re.compile('[^a-z0-9]+')
-_non_id_at_ends = re.compile('^[-0-9]+|-+$')
-
-def enhanceTypo(s):
-    # typographic junkie
-    #   idea from: http://daringfireball.net/projects/smartypants/
-    s = s.replace('...', '&#8230;')   # ellipsis (...)
-    s = s.replace(' -- ', ' &#8212; ')  # em-dash
-    s = s.replace('(c)', '&copy; ')  # copyright symbol
-    return s
-
-
-def parseSpipLink(link):
-    link = link.replace('\n', ' ')
-    matchObject = re.match(
-            r'(?P<role>alias|art(icle)?|atom|book|card|election|file|'\
-             'grade|group|heading|im(g|age)?|person(ne)?|rubri(c|que)'\
-             ') *(?P<localId>\S+) *(?P<option>\S+)?', link)
-
-    if matchObject is None:
-        name = link
-        for prefix in [ 'http://', 'https://', 'ftp://', 'mailto:' ]:
-            if name.startswith(prefix):
-                if not '/' in name[len(prefix):]:
-                    name = name[len(prefix):]
-                break
-        else:
-            name = ''
-        return name, link
-
-    role = matchObject.group('role')
-    localId = matchObject.group('localId')
-    option = matchObject.group('option') and \
-            ':%s' % matchObject.group('option') or ''
-
-    return ('XXX', '#')
-
-
-class Formatter:
-    def close(self, **keywords):
-        return ''
-
-    def list(self, list):
-        def getListIndent(stack):
-            if len(stack) == 0:
-                return -1
-            else:
-                return stack[-1][0]
-        stack = []
-        result = ''
-        for line in list:
-            indent, type, text = line
-            while indent < getListIndent(stack):
-                result += self.listEnd(len(stack), stack[-1][1])
-                del stack[-1]
-            if indent > getListIndent(stack):
-                stack.append((indent, type))
-                result += self.listBegin(len(stack) - 1, type)
-            result += self.listItem(len(stack), text)
-        while stack:
-            result += self.listEnd(len(stack) - 1, stack[-1][1])
-            del stack[-1]
-        return result
-
-    def open(self, **keywords):
-        return ''
-
-    def prescaleImage(self):
-        return 1
-
-    def table(self, table, hasHeader):
-        result = ''
-        rows = len(table)
-        cols = max(map(len, table))
-        result += self.tableBegin(rows, cols)
-        for i in range(len(table)):
-            row = table[i]
-            rowNumber = i
-            if hasHeader:
-                rowNumber -= 1
-            result += self.tableLineBegin(rowNumber,
-                                          isHeader = i == 0 and hasHeader)
-            j = 0
-            for cell in row:
-                if type(cell) in (str, unicode) and cell.strip() == '###':
-                    cell = rowNumber + 1
-                result += self.tableCell(cell, rowNumber, j,
-                                         isHeader = i == 0 and hasHeader)
-                j += 1
-            result += self.tableLineEnd(i, isHeader = i == 0 and hasHeader)
-        result += self.tableEnd(isHeader = len(table) == 1 and hasHeader)
-        return result
-
-    def text(self, text):
-        return text
-
-
-class FormatterHtml(Formatter):
-    def __init__(self):
-        self.states = [ '' ]
-
-    def intertitle(self, text, sublevel = 0):
-        nameText = re.sub('<.*?>', '', text).strip()
-        # from docutils/nodes.py, def make_id(string)
-        nameText = _non_id_chars.sub('-', ' '.join(nameText.lower().split()))
-        nameText = _non_id_at_ends.sub('', nameText)
-
-        return '<h%(sectionLevel)d id="%(nameText)s">%(text)s'\
-               '</h%(sectionLevel)d>\n\n' % {
-            'text': text.strip(),
-            'sectionLevel': self.sectionLevel + sublevel,
-            'nameText': nameText,
-            }
-
-    def lineBreak(self):
-        return '<br />\n'
-
-    def list(self, list):
-        # FIXME: the Formatter.list method doesn't work for sub-lists, so it is
-        # rewritten here. Maybe this method should also be used by
-        # Formatter.list
-        def getListIndent(stack):
-            if len(stack) == 0:
-                return -1
-            else:
-                return stack[-1][0]
-        self.states.append('blockLevel')
-        stack = []
-        result = ''
-        for line in list:
-            indent, type, text = line
-            while indent < getListIndent(stack):
-                result += self.listItemEnd()
-                result += self.listEnd(len(stack), stack[-1][1])
-                del stack[-1]
-            if indent > getListIndent(stack):
-                stack.append((indent, type))
-                result += '\n'
-                result += self.listBegin(len(stack) - 1, type)
-            else:
-                result += self.listItemEnd()
-            result += self.listItemBegin(len(stack), text)
-        while stack:
-            result += self.listItemEnd()
-            result += self.listEnd(len(stack) - 1, stack[-1][1])
-            del stack[-1]
-        return result
-
-    def listBegin(self, indent, type):
-        if type:
-            type = 'ol'
-        else:
-            type = 'ul'
-        return '%(indent)s<%(type)s>\n' % {
-            'indent': '  ' * indent,
-            'type': type,
-            }
-
-    def listEnd(self, indent, type):
-        if type:
-            type = 'ol'
-        else:
-            type = 'ul'
-        return '%(indent)s</%(type)s>\n' % {
-            'indent': '  ' * indent,
-            'type': type,
-            }
-
-    def listItemBegin(self, indent, item):
-        return '%(indent)s<li>%(item)s' % {
-            'indent': '  ' * indent,
-            'item': item.strip('*'),
-            }
-
-    def listItemEnd(self):
-        return '</li>\n'
-
-    def nonBreakingSpace(self):
-        return '&nbsp;'
-
-    def open(self, **keywords):
-        self.sectionLevel = 2
-        if keywords.has_key('sectionLevel'):
-            self.sectionLevel = int(keywords['sectionLevel'])
-        return ''
-
-    def paragraph(self, text):
-
-        # turn URL into links
-        def repl(match):
-            m = match.group(0)
-            if m[0] == '"' and m[-1] == '"':
-                return m
-            if m[0] in '>' and m[-1] == '<':
-                return m
-            m = m.rstrip('<').lstrip('>')
-            return '<a href="%s">%s</a>' % (m, m)
-        t1 = text
-        text = re.sub(r'([">]?http[s]?://[a-zA-Z0-9\.\/-]*[<"]?)', repl, text, re.DOTALL)
-
-        if self.states[-1] == 'blockLevel':
-            self.states.pop()
-            return text
-
-
-        def line80(text):
-            t = []
-            i = 0
-            while 1:
-                val = text[i+70:].find(' ')
-                if val == -1:
-                    t.append(text[i:])
-                    break
-                part = text[i:i+70+val+1]
-                t.append(part)
-                i += len(part)
-            return '\n'.join(t)
-
-        text = enhanceTypo(text.strip())
-        text = line80(text.replace('\n', ' '))
-        text = text.replace('\n_ ', '\n<br/>\n')
-        if not text:
-            return self.lineBreak()
-        return '<p>%(text)s</p>\n\n' % {
-            'text': text,
-            }
-
-    def preformatted(self, text):
-        if not text:
-            return ''
-##         text = self.text(text)
-        self.states.append('blockLevel')
-        return '<pre>%(text)s</pre>' % {
-            'text': text,
-            }
-
-    def preformattedInline(self, text):
-        if not text:
-            return ''
-        text = self.text(text)
-        return '<code>%(text)s</code>' % {
-            'text': text,
-            }
-
-    def punctuationAndSpace(self, punctuation):
-        return {
-            u'« ': u'«&nbsp;',
-            }[punctuation]
-
-    def spaceAndPunctuation(self, punctuation):
-        return {
-            u' :': u'&nbsp;:',
-            u' ;': u'&nbsp;;',
-            u' !': u'&nbsp;!',
-            u' ?': u'&nbsp;?',
-            u' »': u'&nbsp;»',
-            u' %': u'&nbsp;%',
-            u' ...': u'&nbsp;...',
-            }[punctuation]
-
-    def tableBegin(self, rows, cols):
-        self.states.append('blockLevel')
-        return '<table>\n'
-
-    def tableCell(self, cell, row, col, isHeader):
-        if not cell:
-            cell = '&nbsp;'
-        if isHeader:
-            tag = 'th'
-            attrtag = ' scope="col"'
-        else:
-            tag = 'td'
-            attrtag = ''
-        return '    <%(tag)s%(attrtag)s>%(cell)s</%(tag)s>\n' % {
-            'tag': tag,
-            'cell': cell.strip(),
-            'attrtag': attrtag,
-            }
-
-    def tableEnd(self, isHeader = 0):
-        return '</table>\n'
-
-    def tableLineBegin(self, tableLineCount, isHeader = 0):
-        if isHeader:
-            return '  <tr>\n'
-        elif (tableLineCount + 1) % 2 == 0:
-            return '  <tr class="even">\n'
-        else:
-            return '  <tr class="odd">\n'
-
-    def tableLineEnd(self, tableLineCount, isHeader = 0):
-        return '  </tr>\n'
-
-    def text(self, text):
-        if not text:
-            return ''
-        text = text.replace('&', '&amp;')
-        text = text.replace('<', '&lt;')
-        #text = text.replace('\x85', '&#8230;')  # ellipsis (...)
-        return text
-
-
-class FormatterHtmlComplete(FormatterHtml):
-    _footNotes = None
-
-    def close(self, **keywords):
-        footNotes = self._footNotes
-        if footNotes is None or len(footNotes) == 0:
-            return ''
-        indexes = footNotes.keys()
-        indexes.sort()
-        result = '<div class="spip-notes">\n'
-        for index in indexes:
-            result += '<p>'
-            result += '[<a href="#nh%(index)s" name="nb%(index)s" '\
-                      'class="spip-note">%(index)s</a>]&nbsp;%(text)s' % {
-                'index': index,
-                'text': footNotes[index],
-                }
-            result += '</p>\n'
-        result += '</div>\n'
-        return result
-
-    def emphasis(self, text):
-        if not text:
-            return ''
-        return '<em>%(text)s</em>' % {
-            'text': text,
-            }
-
-    def footNoteCall(self, footNote):
-        if self._footNotes is None:
-            self._footNotes = {}
-        index = len(self._footNotes) + 1
-        self._footNotes[index] = footNote
-        return '&nbsp;[<a href="#nb%(index)s" name="nh%(index)s" '\
-                'class="spip-note">%(index)s</a>]' % { 'index': index }
-
-    def image(self, name, url, width=None, height=None, fullUrl=None, align=None):
-        if width:
-            width = ' width="%s"' % width
-        else:
-            width = ''
-        if height:
-            height = ' height="%s"' % height
-        else:
-            height = ''
-        if align:
-            align = ' style="float: %s;"' % align
-        else:
-            align = ''
-        image = """\
-<img src="%(url)s" alt="%(name)s" title="%(name)s"%(height)s%(width)s%(align)s />\
-""" % {
-            'height': height,
-            'name': name,
-            'url': url,
-            'width': width,
-            'align': align,
-            }
-        if fullUrl:
-            image = '<a href="%(fullUrl)s">%(image)s</a>' % {
-                'fullUrl': fullUrl,
-                'image': image,
-                }
-        return image
-
-    def lineSeparator(self):
-        return '<hr />\n'
-
-    def link(self, name, url, title=None):
-        url = url.replace('"', '&quot;') # '"' must be converted.
-        # The following replace should not be done. An url must be left as is.
-        # url = url.replace('&', '&amp;') #
-        # url = url.replace('<', '&lt;') # ?
-        # url = url.replace('>', '&gt;') # ?
-        attrs = ['href="%s"' % url]
-        if title:
-            attrs.append('title="%s"' % title)
-        if url.startswith('http://'):
-            attrs.append('class="external"')
-        attrs = ' '.join(attrs)
-        return '<a %s>%s</a>' % (attrs, name)
-
-    def strong(self, text):
-        if not text:
-            return ''
-        return '<strong>%(text)s</strong>' % {
-            'text': text,
-            }
-
-    def teletype(self, text):
-        if not text:
-            return ''
-        return '<tt>%(text)s</tt>' % {
-            'text': text,
-            }
-
-
-class FormatterHtmlSimple(FormatterHtml):
-    def emphasis(self, text):
-        return text
-
-    def footNoteCall(self, footNote):
-        return ''
-
-    def image(self, name, url, width = None, height = None, fullUrl = None):
-        return ''
-
-    def lineSeparator(self):
-        return '<br />\n'
-
-    def link(self, name, url, title=None):
-        return str(name)
-
-    def strong(self, text):
-        return text
-
-    def teletype(self, text):
-        return text
-
-
-
-class SpipParser:
-    codeRegexp = r"""
-(?P<codeStop>\</(code|CODE)\>)
-|(?P<wordAsIs>\w+)
-"""
-    codeRegexp = codeRegexp.replace('\n', '')
-    codeRegexpObject = None
-    footNoteRegexp = r"""
-(?P<footNoteStop>\]\])
-|(?P<image>\<((im(g|age)?)|(IM(G|AGE)?)) *(\d+|[^ \>]+)( +\d+\*\d+)?\>)
-|(?P<teletypeStart>\(\()
-|(?P<teletypeStop>\)\))
-|(?P<strongStart>\{\{)
-|(?P<strongStop>\}\})
-|(?P<emphasisStart>\{)
-|(?P<emphasisStop>\})
-|(?P<linkStart>\[)
-|(?P<antislash>\\.?)
-|(?P<punctuationAndSpace>[«] )
-|(?P<spaceAndPunctuation> ([:;!\?»%]|\.\.\.))
-|(?P<nonBreakingSpace>~)
-|(?P<word>\w+)
-"""
-    footNoteRegexp = footNoteRegexp.replace('\n', '')
-    footNoteRegexpObject = None
-    linkNameRegexp = r"""
-(?P<image>\<((im(g|age)?)|(IM(G|AGE)?)) *(\d+|[^ \>]+)( +\d+\*\d+)?\>)
-|(?P<teletypeStart>\(\()
-|(?P<teletypeStop>\)\))
-|(?P<strongStart>\{\{)
-|(?P<strongStop>\}\})
-|(?P<emphasisStart>\{)
-|(?P<emphasisStop>\})
-|(?P<linkMiddle>->)
-|(?P<linkWithoutMiddleStop>\])
-|(?P<antislash>\\.?)
-|(?P<punctuationAndSpace>[«] )
-|(?P<spaceAndPunctuation> ([:;!\?»%]|\.\.\.))
-|(?P<nonBreakingSpace>~)
-|(?P<word>\w+)
-"""
-    linkNameRegexp = linkNameRegexp.replace('\n', '')
-    linkNameRegexpObject = None
-    linkRegexp = r"""
-(?P<linkStop>\])
-|(?P<wordInUrl>\w+)
-"""
-    linkRegexp = linkRegexp.replace('\n', '')
-    linkRegexpObject = None
-    listRegexp = r"""
-(?P<listLineStart>^ *-([0-9aAiI]\.)?(?=[^-]))
-|(?P<listLineStop>\r?\n(?= *-([0-9aAiI]\.)?(?=[^-])))
-|(?P<listLineContinuation>\r?\n(?= +))
-|(?P<listStop>(?=\r?\n|$))
-|(?P<image>\<((im(g|age)?)|(IM(G|AGE)?)) *(\d+|[^ \>]+)( +\d+\*\d+)?\>)
-|(?P<teletypeStart>\(\()
-|(?P<teletypeStop>\)\))
-|(?P<strongStart>\{\{)
-|(?P<strongStop>\}\})
-|(?P<emphasisStart>\{)
-|(?P<emphasisStop>\})
-|(?P<footNoteStart>\[\[)
-|(?P<linkStart>\[)
-|(?P<antislash>\\.?)
-|(?P<punctuationAndSpace>[«] )
-|(?P<spaceAndPunctuation> ([:;!\?»%]|\.\.\.))
-|(?P<nonBreakingSpace>~)
-|(?P<word>\w+)
-"""
-    listRegexp = listRegexp.replace('\n', '')
-    listRegexpObject = None
-    paragraphRegexp = r"""
-(?P<paragraphStop>\r?\n( *\r?\n)* *(?=\r?\n|$))
-|(?P<lineSeparator>^ *[-_]{4,} *(\r?\n|$))
-|(?P<intertitleStart>^ *\{\{\{)
-|(?P<intertitleStop>\}\}\}( *$|))
-|(?P<listStart>^ *-([0-9aAiI]\.)?)
-|(?P<tableWithHeaderStart>^ *\|(?=( *\{\{.*?\}\} *\|)+ *(\r?\n|$)))
-|(?P<tableStart>^ *\|)
-|(?P<codeStart>\<(code|CODE)\>)
-|(?P<image>\<((im(g|age)?)|(IM(G|AGE)?)) *(\d+|[^ \>]+)( +\d+\*\d+)?\>)
-|(?P<teletypeStart>\(\()
-|(?P<teletypeStop>\)\))
-|(?P<strongStart>\{\{)
-|(?P<strongStop>\}\})
-|(?P<emphasisStart>\{)
-|(?P<emphasisStop>\})
-|(?P<footNoteStart>\[\[)
-|(?P<linkStart>\[)
-|(?P<antislash>\\.?)
-|(?P<punctuationAndSpace>[«] )
-|(?P<spaceAndPunctuation> ([:;!\?»%]|\.\.\.))
-|(?P<nonBreakingSpace>~)
-|(?P<word>\w+)
-"""
-    paragraphRegexp = paragraphRegexp.replace('\n', '')
-    paragraphRegexpObject = None
-    posDelta = 0
-    spipRegexp = r"""
-(?P<paragraphStart>\r?\n)
-"""
-    spipRegexp = spipRegexp.replace('\n', '')
-    spipRegexpObject = None
-    states = None
-    tableRegexp = r"""
-(?P<rowStart>^ *\|)
-|(?P<rowStop>\| *\r?\n(?= *\|))
-|(?P<tableStop>\| *(?=\r?\n|$))
-|(?P<cellRestart>\|)
-|(?P<image>\<((im(g|age)?)|(IM(G|AGE)?)) *(\d+|[^ \>]+)( +\d+\*\d+)?\>)
-|(?P<teletypeStart>\(\()
-|(?P<teletypeStop>\)\))
-|(?P<strongStart>\{\{)
-|(?P<strongStop>\}\})
-|(?P<emphasisStart>\{)
-|(?P<emphasisStop>\})
-|(?P<footNoteStart>\[\[)
-|(?P<linkStart>\[)
-|(?P<antislash>\\.?)
-|(?P<punctuationAndSpace>[«] )
-|(?P<spaceAndPunctuation> ([:;!\?»%]|\.\.\.))
-|(?P<nonBreakingSpace>~)
-|(?P<word>\w+)
-"""
-    tableRegexp = tableRegexp.replace('\n', '')
-    tableRegexpObject = None
-
-    def __init__(self, documents):
-        self.documents = documents
-
-        self.codeRegexpObject = re.compile(self.codeRegexp,
-                                           re.MULTILINE | re.DOTALL)
-        self.footNoteRegexpObject = re.compile(self.footNoteRegexp,
-                                               re.MULTILINE | re.DOTALL)
-        self.linkNameRegexpObject = re.compile(self.linkNameRegexp,
-                                               re.MULTILINE | re.DOTALL)
-        self.linkRegexpObject = re.compile(self.linkRegexp,
-                                           re.MULTILINE | re.DOTALL)
-        self.listRegexpObject = re.compile(self.listRegexp,
-                                           re.MULTILINE | re.DOTALL)
-        self.paragraphRegexpObject = re.compile(self.paragraphRegexp,
-                                                re.MULTILINE | re.DOTALL)
-        self.spipRegexpObject = re.compile(self.spipRegexp,
-                                           re.MULTILINE | re.DOTALL)
-        self.tableRegexpObject = re.compile(self.tableRegexp,
-                                            re.MULTILINE | re.DOTALL)
-        self.states = []
-        self.pushState({
-            'state': None,
-            })
-        self.pushState({
-            'formattedText': '',
-            'paragraphsCount': 0,
-            'regexpObject': self.spipRegexpObject,
-            'state': 'spip',
-            })
-        self.pushState({
-            'formattedText': '',
-            'ignoreEmptyParagraph': 0,
-            'regexpObject': self.paragraphRegexpObject,
-            'state': 'paragraph',
-            })
-
-    def format(self, formatter, rawText, **keywords):
-        self.formatter = formatter
-        formattedText = self.formatter.open(**keywords)
-        if not rawText:
-            rawText = ''
-        rawText = rawText.expandtabs()
-        pos = 0
-        while pos < len(rawText):
-            regexpObject = self.getVar('regexpObject')
-            matchObject = regexpObject.match(rawText, pos)
-            if matchObject is None or matchObject.lastgroup is None:
-                self.setVar(
-                    'formattedText',
-                    self.getVar('formattedText') \
-                    + self.formatter.text(rawText[pos]))
-                pos += 1
-            else:
-                groupName = matchObject.lastgroup
-                result = apply(getattr(self, 'handle_' + groupName),
-                               (matchObject.group(groupName), ))
-                if result:
-                    self.setVar('formattedText',
-                                self.getVar('formattedText') + result)
-                pos = matchObject.end(groupName) + self.posDelta
-                if self.posDelta != 0:
-                    del self.posDelta
-        while len(self.states) > 2:
-            if self.getVar('state') == 'list':
-                result = self.handle_listStop(None)
-                if result:
-                    self.setVar('formattedText',
-                                self.getVar('formattedText') + result)
-            elif self.getVar('state') == 'paragraph':
-                result = self.handle_paragraphStop(None, isLastParagraph = 1)
-                if result:
-                    self.setVar('formattedText',
-                                self.getVar('formattedText') + result)
-            else:
-                self.pullState()
-        formattedText += self.getVar('formattedText')
-        formattedText = formattedText.strip() + '\n'
-        formattedText += self.formatter.close(**keywords)
-        return formattedText
-
-    def getVar(self, name):
-        for state in self.states:
-            if state.has_key(name):
-                return state[name]
-        else:
-            raise KeyError(name)
-
-    def getPreviousVar(self, name):
-        for state in self.states[1:]:
-            if state.has_key(name):
-                return state[name]
-        else:
-            raise KeyError(name)
-
-    def handle_antislash(self, group):
-        character = group[1]
-        if character == 'n':
-            return self.formatter.lineBreak()
-        else:
-            return self.formatter.text(character)
-
-    def handle_cellRestart(self, group):
-        self.handle_cellStop(group)
-        self.handle_cellStart(group)
-        return None
-
-    def handle_cellStart(self, group):
-        table = self.getVar('table')
-        table[-1].append([])
-        return None
-
-    def handle_cellStop(self, group):
-        table = self.getVar('table')
-        table[-1][-1] = self.getVar('formattedText')
-        self.setVar('formattedText', '')
-        return None
-
-    def handle_codeStart(self, group):
-        self.pushState({
-            'formattedText': '',
-            'regexpObject': self.codeRegexpObject,
-            'state': 'code',
-            })
-        return None
-
-    def handle_codeStop(self, group):
-        if self.getVar('state') != 'code':
-            return None
-        formattedText = self.getVar('formattedText')
-        self.pullState()
-        return self.formatter.preformatted(formattedText)
-
-    def handle_emphasisStart(self, group):
-        self.pushState({
-            'formattedText': '',
-            'state': 'emphasis',
-            })
-        return None
-
-    def handle_emphasisStop(self, group):
-        if self.getVar('state') != 'emphasis':
-            return None
-        formattedText = self.getVar('formattedText')
-        self.pullState()
-        return self.formatter.emphasis(formattedText)
-
-    def handle_footNoteStart(self, group):
-        self.pushState({
-            'formattedText': '',
-            'regexpObject': self.footNoteRegexpObject,
-            'state': 'footNote',
-            })
-        return None
-
-    def handle_footNoteStop(self, group):
-        if self.getVar('state') != 'footNote':
-            return None
-        formattedText = self.getVar('formattedText')
-        self.pullState()
-        return self.formatter.footNoteCall(formattedText)
-
-    def handle_image(self, group):
-        matchObject = re.match(
-                r'\<((im(g|age)?)|(IM(G|AGE)?)) '\
-                 '*((?P<localId>\d+)|(?P<url>[^ \>]+))'\
-                 '(?P<align>\|[a-z]+)?'\
-                 '( +(?P<width>\d+)\*(?P<height>\d+))?\>', group)
-        localId = matchObject.group('localId')
-        url = matchObject.group('url')
-        width = matchObject.group('width')
-        height = matchObject.group('height')
-        align = matchObject.group('align')
-        name = localId
-        if align:
-            align = align[1:]
-        if not url and localId:
-            doc = self.documents.get(localId)
-            if doc and doc.filename:
-                url = '/media/IMG/' + doc.filename
-        fullUrl = None
-        return self.formatter.image(name, url, width, height, fullUrl, align)
-
-    def handle_intertitleStart(self, group):
-        inParagraph = self.getVar('state') == 'paragraph'
-        if inParagraph:
-            result = self.handle_paragraphStop(None, ignoreEmptyParagraph = 1)
-            if result:
-                self.setVar('formattedText',
-                            self.getVar('formattedText') + result)
-        self.pushState({
-            'formattedText': '',
-            'inParagraph': inParagraph,
-            'regexpObject': self.paragraphRegexpObject,
-            'state': 'intertitle',
-            })
-        return None
-
-    def handle_intertitleStop(self, group):
-        if self.getVar('state') == 'intertitle':
-            formattedText = self.getVar('formattedText')
-            inParagraph = self.getVar('inParagraph')
-            self.pullState()
-            formattedText = self.formatter.intertitle(formattedText)
-            self.setVar('formattedText',
-                        self.getVar('formattedText') + formattedText)
-            if inParagraph:
-                return self.handle_paragraphStart(None,
-                                                  ignoreEmptyParagraph = 1)
-            else:
-                return None
-        elif self.getVar('state') == 'strong':
-            self.posDelta -= 1
-            return self.handle_strongStop(group[:-1])
-        elif self.getVar('state') == 'emphasis':
-            self.posDelta -= 2
-            return self.handle_emphasisStop(group[:-2])
-        else:
-            return None
-
-    def handle_lineSeparator(self, group):
-        inParagraph = self.getVar('state') == 'paragraph'
-        if inParagraph:
-            result = self.handle_paragraphStop(None, ignoreEmptyParagraph = 1)
-            if result:
-                self.setVar('formattedText',
-                            self.getVar('formattedText') + result)
-        formattedText = self.formatter.lineSeparator()
-        self.setVar('formattedText',
-                    self.getVar('formattedText') + formattedText)
-        if inParagraph:
-            return self.handle_paragraphStart(None, ignoreEmptyParagraph = 1)
-        else:
-            return None
-
-    def handle_linkMiddle(self, group):
-        if self.getVar('state') != 'linkName':
-            return None
-        name = self.getVar('formattedText')
-        self.pullState()
-        self.pushState({
-            'formattedText': '',
-            'name': name,
-            'regexpObject': self.linkRegexpObject,
-            'state': 'link',
-            })
-        return None
-
-    def handle_linkStart(self, group):
-        self.pushState({
-            'formattedText': '',
-            'regexpObject': self.linkNameRegexpObject,
-            'state': 'linkName',
-            })
-        return None
-
-    def handle_linkStop(self, group):
-        if self.getVar('state') != 'link':
-            return None
-        title = None
-        name = self.getVar('name')
-        link = self.getVar('formattedText')
-        self.pullState()
-        link = link.strip()
-        title, url = parseSpipLink(link)
-        if not title:
-            title = url
-        if name and '|' in name:
-            oTitle = title
-            try:
-                name, title = name.split('|', 2)
-            except ValueError:
-                # XXX
-                print 'error splitting', repr(name)
-                name, title = oTitle, 'XXX'
-            if not name:
-                name = oTitle
-        elif not name:
-            name = title
-            title = None
-        if name == title or url == title:
-            title = None
-        return self.formatter.link(name.strip(), url, title)
-
-    def handle_linkWithoutMiddleStop(self, group):
-        if self.getVar('state') != 'linkName':
-            return None
-        formattedText = self.getVar('formattedText')
-        self.pullState()
-        return self.formatter.text('[') \
-               + formattedText \
-               + self.formatter.text(']')
-
-    def handle_listLineStart(self, group):
-        matchObject = re.match(
-            r'^(?P<indent> *)-((?P<type>[0-9aAiI])\.)?',
-            group)
-        indent = len(matchObject.group('indent'))
-        type = matchObject.group('type')
-        list = self.getVar('list')
-        list.append([indent, type, None])
-        return None
-
-    def handle_listLineContinuation(self, group):
-        return None
-
-    def handle_listLineStop(self, group):
-        list = self.getVar('list')
-        list[-1][-1] = self.getVar('formattedText').lstrip()
-        self.setVar('formattedText', '')
-        return None
-
-    def handle_listStart(self, group):
-        self.pushState({
-            'formattedText': '',
-            'list': [],
-            'regexpObject': self.listRegexpObject,
-            'state': 'list',
-            })
-        return self.handle_listLineStart(group)
-
-    def handle_listStop(self, group):
-        if self.getVar('state') != 'list':
-            # The following pullState is mandatory, because group is empty, so
-            # if we don't pull a state, handle_listStop will be called forever.
-            if len(self.states) > 2:
-                self.pullState()
-            return None
-        self.handle_listLineStop(group)
-        list = self.getVar('list')
-        self.pullState()
-        return self.formatter.list(list)
-
-    def handle_nonBreakingSpace(self, group):
-        return self.formatter.nonBreakingSpace()
-
-    def handle_paragraphStart(self, group, ignoreEmptyParagraph = 1):
-        self.pushState({
-            'formattedText': '',
-            'ignoreEmptyParagraph': ignoreEmptyParagraph,
-            'regexpObject': self.paragraphRegexpObject,
-            'state': 'paragraph',
-            })
-        return None
-
-    def handle_paragraphStop(self, group, ignoreEmptyParagraph = 0,
-                             isLastParagraph = 0):
-        if self.getVar('state') != 'paragraph':
-            return None
-        formattedText = self.getVar('formattedText').strip()
-        ignoreEmptyParagraph = ignoreEmptyParagraph \
-                               or self.getVar('ignoreEmptyParagraph')
-        self.pullState()
-        self.setVar('paragraphsCount', self.getVar('paragraphsCount') + 1)
-        if ignoreEmptyParagraph and not formattedText:
-            return None
-        elif isLastParagraph and self.getVar('paragraphsCount') == 1:
-            return formattedText
-        elif re.match('^<strong>.+</strong>$', formattedText) and \
-                len(re.findall('<strong>.+?</strong>', formattedText)) == 1:
-            formattedText = formattedText[8:-9]
-            return self.formatter.intertitle(formattedText, sublevel = 1)
-        else:
-            return self.formatter.paragraph(formattedText)
-
-    def handle_punctuationAndSpace(self, punctuation):
-        return self.formatter.punctuationAndSpace(punctuation)
-
-    def handle_rowStart(self, group):
-        table = self.getVar('table')
-        table.append([])
-        return self.handle_cellStart(group)
-
-    def handle_rowStop(self, group):
-        return self.handle_cellStop(group)
-
-    def handle_spaceAndPunctuation(self, punctuation):
-        return self.formatter.spaceAndPunctuation(punctuation)
-
-    def handle_strongStart(self, group):
-        if self.getVar('state') == 'table' and self.getVar('hasHeader'):
-            return None
-        self.pushState({
-            'formattedText': '',
-            'state': 'strong',
-            })
-        return None
-
-    def handle_strongStop(self, group):
-        if self.getVar('state') != 'strong':
-            return None
-        formattedText = self.getVar('formattedText')
-        self.pullState()
-        return self.formatter.strong(formattedText)
-
-    def handle_tableStart(self, group, hasHeader = 0):
-        self.pushState({
-            'formattedText': '',
-            'hasHeader': hasHeader,
-            'table': [],
-            'regexpObject': self.tableRegexpObject,
-            'state': 'table',
-            })
-        return self.handle_rowStart(group)
-
-    def handle_tableStop(self, group):
-        self.handle_rowStop(group)
-        table = self.getVar('table')
-        hasHeader = self.getVar('hasHeader')
-        self.pullState()
-        return self.formatter.table(table, hasHeader)
-
-    def handle_tableWithHeaderStart(self, group):
-        return self.handle_tableStart(group, hasHeader = 1)
-
-    def handle_teletypeStart(self, group):
-        self.pushState({
-            'formattedText': '',
-            'state': 'teletype',
-            })
-        return None
-
-    def handle_teletypeStop(self, group):
-        if self.getVar('state') != 'teletype':
-            return None
-        formattedText = self.getVar('formattedText')
-        self.pullState()
-        return self.formatter.teletype(formattedText)
-
-    def handle_word(self, word):
-        return self.formatter.text(word)
-
-    def handle_wordAsIs(self, word):
-        return word
-
-    def handle_wordInUrl(self, word):
-        return word
-
-    def hasVar(self, name):
-        for state in self.states:
-            if state.has_key(name):
-                return 1
-        else:
-            return 0
-
-    def pullState(self):
-        del self.states[0]
-
-    def pushState(self, state):
-        self.states.insert(0, state)
-
-    def setVar(self, name, value):
-        self.states[0][name] = value
-
-
-def makeHtmlFromSpip(text, simple=0, inline=0, documents=None, **keywords):
-    if not text:
-        return ''
-
-    text = text.replace('\r\n', '\n').replace('<quote></quote>', '')
-    #text = text.replace('\x91', "'").replace('\x92', "'").replace(
-    #        '\x93', "'").replace('\x94', "'").replace(
-    #        '\x81', "'").replace('\x82', "'").replace(
-    #        '&#8217;', "'").replace('&#8230;', '...').replace(
-    #        '&#8211;', '--').replace('&#8220;', '"').replace(
-    #        '&#180;', "'").replace('&#8221;', '"').replace(
-    #        '&#8216;', "'").replace('&#339;', 'oe')
-
-    if not inline:
-        # Force the spip parser to produce paragraphs.
-        text += '\n\n'
-    parser = SpipParser(documents=documents)
-    if simple:
-        formatter = FormatterHtmlSimple()
-    else:
-        formatter = FormatterHtmlComplete()
-    return parser.format(formatter, text, **keywords).strip()
-
-
-if __name__ == '__main__':
-     print makeHtmlFromSpip(unicode(file(sys.argv[1]).read(), 'utf-8'))
diff --git a/panikdb/emissions/management/commands/create-sound-files.py b/panikdb/emissions/management/commands/create-sound-files.py
deleted file mode 100644 (file)
index cdd65d1..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-import base64
-import mutagen
-import mutagen.mp3
-import os
-import subprocess
-
-from optparse import make_option
-
-from django.core.management.base import BaseCommand, CommandError
-
-from ...models import SoundFile
-
-
-class Command(BaseCommand):
-
-    option_list = BaseCommand.option_list + (
-        make_option('--force',
-            action='store_true',
-            dest='force',
-            default=False,
-            help='Create files even if they exist'),
-        make_option('--reset-metadata',
-            action='store_true',
-            dest='reset_metadata',
-            default=False,
-            help='Reset metadata on all files'),
-        make_option('--emission',
-            dest='emission',
-            metavar='EMISSION',
-            default=None,
-            help='Process files belonging to emission only'),
-        make_option('--episode',
-            dest='episode',
-            metavar='EPISODE',
-            default=None,
-            help='Process files belonging to episode only'),
-        )
-
-    def handle(self, force, reset_metadata, emission, episode, verbosity, **kwargs):
-        self.verbose = (verbosity > 1)
-
-        for soundfile in SoundFile.objects.select_related().exclude(podcastable=False):
-            if emission and soundfile.episode.emission.slug != emission:
-                continue
-            if episode and soundfile.episode.slug != episode:
-                continue
-            if soundfile.file is None or not os.path.exists(soundfile.file.path):
-                continue
-            for format in ('ogg', 'mp3'):
-                file_path = soundfile.get_format_path(format)
-                if not os.path.exists(file_path) or force:
-                    self.create(soundfile, format)
-                if force or reset_metadata:
-                    self.set_metadata(soundfile, format)
-
-    def create(self, soundfile, format):
-        file_path = soundfile.get_format_path(format)
-
-        cmd = ['sox', soundfile.file.path, file_path]
-
-        if format == 'ogg':
-            cmd[-1:-1] = ['-C', '4'] # q4 (~128kbps)
-        elif format == 'mp3':
-            cmd[-1:-1] = ['-C', '-4'] # vbr @ ~128kbps
-
-        if self.verbose:
-            print 'creating', file_path
-            cmd[1:1] = ['--show-progress']
-            print '  ', ' '.join(cmd)
-
-        subprocess.call(cmd)
-
-    def set_metadata(self, soundfile, format):
-        file_path = soundfile.get_format_path(format)
-
-        if format == 'mp3':
-            audio = mutagen.mp3.MP3(file_path, ID3=mutagen.easyid3.EasyID3)
-        elif format == 'ogg':
-            audio = mutagen.File(file_path)
-
-        if 'comment' in audio:
-            del audio['comment']
-        if soundfile.fragment is True and soundfile.title:
-            audio['title'] = '%s - %s' % (
-                    soundfile.episode.title,
-                    soundfile.title)
-        else:
-            audio['title'] = soundfile.episode.title
-        audio['album'] = soundfile.episode.emission.title
-        audio['artist'] = 'Radio Panik'
-
-        if soundfile.episode.image or soundfile.episode.emission.image:
-            image = (soundfile.episode.image or soundfile.episode.emission.image)
-            image.file.open()
-            if os.path.splitext(image.path)[1].lower() in ('.jpeg', '.jpg'):
-                mimetype = 'image/jpeg'
-            elif os.path.splitext(image.path)[1].lower() == '.png':
-                mimetype = 'image/png'
-            else:
-                mimetype = None
-            if mimetype:
-                if format == 'ogg':
-                    audio['coverartmime'] = mimetype
-                    audio['coverartdescription'] = 'image'
-                    audio['coverart'] = base64.encodestring(image.read()).replace('\n', '')
-                elif format == 'mp3':
-                    audio.save()
-                    audio = mutagen.mp3.MP3(file_path)
-                    audio.tags.add(mutagen.id3.APIC(
-                            encoding=3, description='image',
-                            type=3, mime=mimetype, data=image.read()))
-            image.close()
-
-        audio.save()
diff --git a/panikdb/emissions/management/commands/day-program.py b/panikdb/emissions/management/commands/day-program.py
deleted file mode 100644 (file)
index 49bb676..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-from datetime import datetime
-
-from django.core.management.base import BaseCommand, CommandError
-
-from ...utils import day_program
-
-
-class Command(BaseCommand):
-    def handle(self, year, month, day, **options):
-        date = datetime(int(year), int(month), int(day))
-        for entry in day_program(date):
-            print entry.datetime, entry
diff --git a/panikdb/emissions/management/commands/load-from-spip.py b/panikdb/emissions/management/commands/load-from-spip.py
deleted file mode 100644 (file)
index e85efde..0000000
+++ /dev/null
@@ -1,544 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from datetime import datetime
-import time
-import gzip
-import xml.etree.ElementTree as ET
-import os
-import re
-import urllib2
-
-from optparse import make_option
-
-from django.conf import settings
-from django.core.files import File
-from django.core.management.base import BaseCommand, CommandError
-from django.core.urlresolvers import reverse
-from django.utils.text import slugify
-
-from ...models import Emission, Episode, Diffusion, Category, SoundFile, NewsItem
-from ...models import get_sound_path
-
-
-from _spip2html import makeHtmlFromSpip
-
-
-class Rubric(object):
-    archived = False
-
-    spip_url_marker = '-'
-    spip_url_object_name = 'rubrique'
-
-    def __init__(self):
-        self.articles = {}
-        self.rubrics = {}
-        self.categories = []
-
-    @property
-    def id(self):
-        return self.id_rubrique
-
-
-class Article(object):
-    spip_url_marker = ''
-    spip_url_object_name = 'article'
-
-    @property
-    def id(self):
-        return self.id_article
-
-
-class Breve(object):
-    spip_url_marker = '+'
-    spip_url_object_name = 'breve'
-
-    @property
-    def id(self):
-        return self.id_breve
-
-
-class KeywordGroup(object):
-    def __init__(self):
-        self.keywords = {}
-
-
-class Keyword(object):
-    related_object = None
-
-
-class Document(object):
-    pass
-
-
-class Command(BaseCommand):
-    args = 'filename'
-    help = 'Load emissions and episodes from a Spip dump file'
-
-    option_list = BaseCommand.option_list + (
-            make_option('--no-updates',
-                action='store_true',
-                dest='dont_update',
-                default=False,
-                help='Only create new objects, do not update existing ones'),
-            make_option('--stats-skipped',
-                dest='stats_skipped_file',
-                metavar='FILE',
-                default=None,
-                help='Create a CSV file ith skipped articles'),
-        make_option('--rewritemap',
-            dest='rewritemap_file',
-            metavar='FILE',
-            default=None,
-            help='Create a Apache RewriteMap'),
-    )
-
-    def handle(self, filename, dont_update, rewritemap_file, stats_skipped_file, **options):
-        self.do_updates = (not dont_update)
-        if rewritemap_file:
-            self.rewritemap = []
-        if stats_skipped_file:
-            self.stats_skipped_file = file(stats_skipped_file, 'w')
-        else:
-            self.stats_skipped_file = None
-        with open(filename) as fd:
-            content = fd.read()
-            # the spip_courriers parts of the spip export are not properly
-            # encoded, we manually remove them here so the XML file can be
-            # parsed correctly.
-            content = content[:content.find('<spip_courriers>')] + \
-                      content[content.rfind('</spip_courriers>')+17:]
-            self.root = ET.fromstring(content)
-
-            self.load_keyword_groups()
-            self.load_keywords()
-            self.load_rubrics()
-
-            emission_rubric_ids = []
-            straight_emission_rubric_ids = []
-            for rubric in self.rubrics['2'].rubrics.values(): # 'Les emissions'
-                emission_rubric_ids.append(rubric.id_rubrique)
-                straight_emission_rubric_ids.append(rubric.id_rubrique)
-                for subrubric in rubric.rubrics.values():
-                    emission_rubric_ids.append(subrubric.id_rubrique)
-
-            self.load_breves()
-            self.load_articles(emission_rubric_ids)
-
-            self.set_urls()
-
-            self.load_documents()
-            self.load_document_links()
-
-            if self.do_updates:
-                self.process_emission_keywords()
-                self.process_episode_keywords()
-
-            for emission_id in straight_emission_rubric_ids:
-                rubric = self.rubrics[emission_id]
-                emission = self.get_or_create_emission(rubric)
-                if rewritemap_file:
-                    self.add_rewritemap_entries(rubric, emission)
-
-                for article in rubric.articles.values():
-                    episode = self.get_or_create_episode(article, emission)
-                    if episode is None:
-                        continue
-                    if rewritemap_file:
-                        self.add_rewritemap_entries(article, episode)
-
-                    self.set_sound_files(article, episode)
-
-            for breve in self.breves.values():
-                newsitem = self.get_or_create_newsitem(breve)
-                if rewritemap_file:
-                    self.add_rewritemap_entries(breve, newsitem)
-
-        if rewritemap_file:
-            self.write_rewritemap(rewritemap_file)
-
-        if self.stats_skipped_file:
-            self.stats_skipped_file.close()
-
-    def load_keyword_groups(self):
-        self.keyword_groups = {}
-        for keywordgroup_xml in self.root.iter('spip_groupes_mots'):
-            keyword_group = KeywordGroup()
-            for attr in ('id_groupe', 'titre'):
-                setattr(keyword_group, attr, keywordgroup_xml.find(attr).text)
-            if keyword_group.id_groupe not in ('11', # archives
-                                               '12', # subjects
-                                               '3',  # category
-                                               '10', # transversal
-                                               ):
-                continue
-            self.keyword_groups[keyword_group.id_groupe] = keyword_group
-
-    def load_keywords(self):
-        self.keywords = {}
-        for keyword_xml in self.root.iter('spip_mots'):
-            keyword = Keyword()
-            for attr in ('id_mot', 'titre', 'id_groupe'):
-                setattr(keyword, attr, keyword_xml.find(attr).text)
-            if not keyword.id_groupe in self.keyword_groups:
-                continue
-            if keyword.id_mot in ('92',): # blacklist
-                continue
-            self.keywords[keyword.id_mot] = keyword
-            self.keyword_groups[keyword.id_groupe] = keyword
-
-    def load_rubrics(self):
-        self.rubrics = {}
-        for rubric_xml in self.root.iter('spip_rubriques'):
-            rubric = Rubric()
-            for attr in ('id_rubrique', 'id_parent', 'titre',
-                         'descriptif', 'texte'):
-                setattr(rubric, attr, rubric_xml.find(attr).text)
-            self.rubrics[rubric.id_rubrique] = rubric
-
-        for rubric in self.rubrics.values():
-            if rubric.id_parent and rubric.id_parent != '0':
-                self.rubrics[rubric.id_parent].rubrics[rubric.id_rubrique] = rubric
-
-    def load_breves(self):
-        self.breves = {}
-        for breve_xml in self.root.iter('spip_breves'):
-            breve = Breve()
-            for attr in ('id_breve', 'titre', 'texte',
-                         'date_heure', 'statut'):
-                setattr(breve, attr, breve_xml.find(attr).text)
-            if breve.statut != 'publie':
-                continue
-            self.breves[breve.id_breve] = breve
-
-    def load_articles(self, emission_rubric_ids):
-        self.articles = {}
-        for article_xml in self.root.iter('spip_articles'):
-            if article_xml.find('id_rubrique').text == '65':
-                pass # rubric for events, handle with care
-            elif not article_xml.find('id_rubrique').text in emission_rubric_ids:
-                continue
-            article = Article()
-            for attr in ('id_rubrique', 'id_article', 'titre', 'surtitre',
-                         'soustitre', 'descriptif', 'chapo', 'texte',
-                         'date_redac', 'statut', 'date'):
-                setattr(article, attr, article_xml.find(attr).text)
-
-            if article.id_rubrique == '65':
-                # this is an event, they get a special handling, to be
-                # merged with newsitems
-                if article.statut not in ('publie', 'prop'):
-                    continue
-                breve = Breve()
-                breve.id_breve = '0%s' % article.id_article
-                breve.titre = article.titre
-                breve.texte = article.texte
-                breve.date_heure = article.date
-                self.breves[breve.id_breve] = breve
-                continue
-
-            if article.statut != 'publie':
-                continue
-            article.mots_cles = []
-            self.articles[article.id_article] = article
-
-            if self.rubrics[article.id_rubrique].id_parent != '2':
-                # the spip structure didn't really expect subrubrics in the
-                # 'emissions' section, but people added some nevertheless,
-                # move related articles to their parent rubric.
-                article.id_rubrique = self.rubrics[article.id_rubrique].id_parent
-
-            self.rubrics[article.id_rubrique].articles[article.id_article] = article
-
-    def set_urls(self):
-        for spip_url_xml in self.root.iter('spip_urls'):
-            id_objet = spip_url_xml.find('id_objet').text
-            url = spip_url_xml.find('url').text
-            if spip_url_xml.find('type').text == 'article' and id_objet in self.articles:
-                self.articles[id_objet].url = url
-            elif spip_url_xml.find('type').text == 'article' and ('0%s' % id_objet) in self.breves:
-                self.breves['0' + id_objet].url = url
-            elif spip_url_xml.find('type').text == 'rubrique' and id_objet in self.rubrics:
-                self.rubrics[id_objet].url = url
-            elif spip_url_xml.find('type').text == 'mot' and id_objet in self.keywords:
-                self.keywords[id_objet].url = url
-            elif spip_url_xml.find('type').text == 'breve' and id_objet in self.breves:
-                self.breves[id_objet].url = url
-
-    def load_documents(self):
-        self.documents = {}
-        for spip_doc_xml in self.root.iter('spip_documents'):
-            id_document = spip_doc_xml.find('id_document').text
-            doc = Document()
-            doc.filename = spip_doc_xml.find('fichier').text
-            doc.title = spip_doc_xml.find('titre').text
-            if spip_doc_xml.find('distant').text == 'oui':
-                url = doc.filename
-                doc.filename = os.path.split(url)[-1]
-                filename = os.path.join('media/IMG/', doc.filename)
-                if not os.path.exists('media/IMG'):
-                    continue
-                if not os.path.exists(filename):
-                    fd = file(filename, 'w')
-                    fd.write(urllib2.urlopen(url).read())
-                    fd.close()
-            self.documents[id_document] = doc
-
-    def load_document_links(self):
-        self.attached_documents = {}
-        for spip_doc_liens_xml in self.root.iter('spip_documents_liens'):
-            id_document = spip_doc_liens_xml.find('id_document').text
-            id_object = spip_doc_liens_xml.find('id_objet').text
-            if spip_doc_liens_xml.find('objet').text != 'article':
-                continue
-            if not self.attached_documents.get(id_object):
-                self.attached_documents[id_object] = []
-            self.attached_documents[id_object].append(self.documents.get(id_document))
-
-    def process_emission_keywords(self):
-        for rubrickeyword_xml in self.root.iter('spip_mots_rubriques'):
-            keyword_id = rubrickeyword_xml.find('id_mot').text
-            rubric_id = rubrickeyword_xml.find('id_rubrique').text
-            rubric = self.rubrics.get(rubric_id)
-            if not rubric:
-                continue
-
-            if keyword_id == '100': # archive
-                rubric.archived = True
-                continue
-
-            keyword = self.keywords.get(keyword_id)
-            if keyword is None:
-                continue
-
-            if keyword.id_groupe == '3': # category
-                rubric.categories.append(keyword)
-                if not keyword.related_object:
-                    cs = Category.objects.filter(title=keyword.titre)
-                    if len(cs):
-                        c = cs[0]
-                    else:
-                        c = Category()
-                    c.title = keyword.titre
-                    c.save()
-                    keyword.related_object = c
-
-    def process_episode_keywords(self):
-        for articlekeyword_xml in self.root.iter('spip_mots_articles'):
-            keyword_id = articlekeyword_xml.find('id_mot').text
-            article_id = articlekeyword_xml.find('id_article').text
-            article = self.articles.get(article_id)
-            if not article:
-                continue
-
-            keyword = self.keywords.get(keyword_id)
-            if keyword is None:
-                continue
-
-            if keyword.id_groupe in ('10', '12'): # transversales & sujets
-                article.mots_cles.append(keyword.titre)
-
-    def get_or_create_emission(self, rubric):
-        slug = rubric.url.lower()
-        possible_slugs = [rubric.url.lower(), rubric.url.lower().split(',')[0]]
-        for slug in possible_slugs:
-            try:
-                emission = Emission.objects.get(slug=slug)
-                break
-            except Emission.DoesNotExist:
-                continue
-        else:
-            emission = Emission()
-
-        emission.slug = possible_slugs[-1]
-
-        if emission.id and not self.do_updates:
-            return emission
-
-        slug = slug.split(',')[0]
-        emission.slug = slug
-        emission.title = rubric.titre
-        emission.archived = rubric.archived
-        emission.description = makeHtmlFromSpip(rubric.descriptif,
-                        documents=self.documents) or None
-        emission.text = makeHtmlFromSpip(rubric.texte,
-                        documents=self.documents) or None
-
-        image_path = None
-        for ext in ('.jpg', '.png', '.gif'):
-            if os.path.exists('media/IMG/rubon%s%s' % (rubric.id_rubrique, ext)):
-                image_path = ['media/IMG/rubon%s%s' % (rubric.id_rubrique, ext)]
-                break
-        else:
-            if emission.text:
-                image_path = re.findall('src="/(media/IMG.*?)"', emission.text, re.DOTALL)
-            elif emission.description:
-                image_path = re.findall('src="/(media/IMG.*?)"', emission.description, re.DOTALL)
-
-        self.set_image(emission, image_path)
-
-        emission.save()
-        emission.categories.clear()
-        for category in rubric.categories:
-            emission.categories.add(category.related_object)
-        emission.save()
-        return emission
-
-    def get_or_create_episode(self, article, emission):
-        if article.date_redac == '0000-00-00 00:00:00':
-            # date_redac was used for the diffusion date, if it's
-            # not set it's probably not really an episode
-            if self.stats_skipped_file:
-                episode_files = self.attached_documents.get(article.id_article)
-                if episode_files:
-                    has_sound = u'♫'
-                else:
-                    has_sound = '-'
-                base_spip_edit_url = 'http://www.radiopanik.org/spip/ecrire/?exec=articles_edit&id_article='
-                print >> self.stats_skipped_file, unicode('%s\t%s\t%s\t%s%s' % (
-                    emission.title, article.titre, has_sound,
-                    base_spip_edit_url, article.id_article)).encode('utf-8')
-            return None
-
-        possible_slugs = [article.url.lower()]
-        if article.url.lower().startswith('nouvel-article'):
-            possible_slugs.append(slugify(unicode(article.titre))[:40] + '-%s' % article.id_article)
-
-        for slug in possible_slugs:
-            try:
-                episode = Episode.objects.get(slug=slug)
-                break
-            except Episode.DoesNotExist:
-                continue
-        else:
-            episode = Episode()
-
-        episode.slug = possible_slugs[-1]
-
-        if episode.id and not self.do_updates:
-            return episode
-
-        episode.emission = emission
-        episode.title = article.titre
-        episode.description = makeHtmlFromSpip(article.descriptif,
-                        documents=self.documents) or None
-        episode.text = makeHtmlFromSpip(article.texte,
-                        documents=self.documents) or None
-
-        image_path = None
-        for ext in ('.jpg', '.png', '.gif'):
-            if os.path.exists('media/IMG/arton%s%s' % (article.id_article, ext)):
-                image_path = ['media/IMG/arton%s%s' % (article.id_article, ext)]
-                break
-        else:
-            if episode.text:
-                image_path = re.findall('src="/(media/IMG.*?)"', episode.text, re.DOTALL)
-            elif episode.description:
-                image_path = re.findall('src="/(media/IMG.*?)"', episode.description, re.DOTALL)
-
-        self.set_image(episode, image_path)
-
-        episode.save()
-
-        for motcle in article.mots_cles:
-            episode.tags.add(motcle.lower())
-
-        if not Diffusion.objects.filter(episode=episode).count():
-            diffusion = Diffusion()
-            diffusion.episode = episode
-            try:
-                diffusion.datetime = datetime.strptime(article.date_redac, '%Y-%m-%d %H:%M:%S')
-            except ValueError:
-                pass
-            else:
-                diffusion.save()
-
-        return episode
-
-    def set_sound_files(self, article, episode):
-        if SoundFile.objects.filter(episode=episode).count():
-            return # skip episodes that already have sound files
-        episode_files = self.attached_documents.get(article.id_article)
-        if episode_files:
-            for episode_file in episode_files:
-                if episode_file is None:
-                    continue
-                if os.path.splitext(episode_file.filename)[-1] not in ('.ogg', '.mp3'):
-                    continue
-                if not os.path.exists('media/IMG/' + episode_file.filename):
-                    continue
-                soundfile = SoundFile()
-                soundfile.episode = episode
-                soundfile.podcastable = True
-                soundfile.fragment = False
-                soundfile.title = episode_file.title or '[pas de titre]'
-                sound_path = os.path.join(settings.MEDIA_ROOT,
-                        get_sound_path(soundfile, episode_file.filename))
-                if os.path.exists(sound_path):
-                    os.unlink(sound_path)
-                soundfile.file = File(file('media/IMG/' + episode_file.filename))
-                soundfile.save()
-
-    def get_or_create_newsitem(self, breve):
-        slug = breve.url.lower()
-        try:
-            newsitem = NewsItem.objects.get(slug=slug)
-        except NewsItem.DoesNotExist:
-            newsitem = NewsItem()
-
-        if newsitem.id and not self.do_updates:
-            return newsitem
-
-        newsitem.title = breve.titre
-        newsitem.slug = slug
-        newsitem.text = makeHtmlFromSpip(breve.texte,
-                documents=self.documents) or None
-        newsitem.datetime = datetime.strptime(breve.date_heure, '%Y-%m-%d %H:%M:%S')
-        for ext in ('.jpg', '.png', '.gif'):
-            if os.path.exists('media/IMG/breveon%s%s' % (breve.id_breve, ext)):
-                image_path = ['media/IMG/breveon%s%s' % (breve.id_breve, ext)]
-                break
-        else:
-            image_path = re.findall('src="/(media/IMG.*?)"', newsitem.text, re.DOTALL)
-        self.set_image(newsitem, image_path)
-        newsitem.save()
-
-    def set_image(self, object, image_path):
-        if not image_path:
-            return
-        image_path = image_path[0]
-        if object.image and os.path.basename(object.image.path) == os.path.basename(image_path):
-            return
-        object.image = File(file(image_path))
-
-    def add_rewritemap_entries(self, spip_object, django_object):
-        if isinstance(django_object, Emission):
-            object_url = reverse('emission-view', kwargs={'slug': django_object.slug})
-        elif isinstance(django_object, Episode):
-            object_url = reverse('episode-view', kwargs={
-                'slug': django_object.slug, 'emission_slug': django_object.emission.slug})
-        elif isinstance(django_object, NewsItem):
-            object_url = reverse('news-view', kwargs={'slug': django_object.slug})
-        else:
-            return
-
-        if spip_object.id[0] == '0':
-            # our hack mapping some articles to newsitems
-            spip_object.spip_url_object_name = 'article'
-            spip_object.spip_url_marker = ''
-
-        urls = []
-        urls.append('%s%s' % (spip_object.spip_url_object_name, spip_object.id))
-        urls.append('spip.php?%s%s' % (spip_object.spip_url_object_name, spip_object.id))
-        urls.append('%s%s.html' % (spip_object.spip_url_object_name, spip_object.id))
-        if spip_object.spip_url_object_name == 'article':
-            urls.append(spip_object.id)
-        urls.append('%s%s%s' % (spip_object.spip_url_marker, spip_object.url, spip_object.spip_url_marker))
-
-        for url in urls:
-            self.rewritemap.append((url, object_url))
-
-    def write_rewritemap(self, rewritemap_file):
-        fd = file(rewritemap_file, 'w')
-        for src, dst in self.rewritemap:
-            print >> fd, src, dst
-        fd.close()
diff --git a/panikdb/emissions/management/commands/week-program.py b/panikdb/emissions/management/commands/week-program.py
deleted file mode 100644 (file)
index c153da8..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-from datetime import datetime, timedelta
-
-from django.core.management.base import BaseCommand, CommandError
-from django.views.generic.dates import _date_from_string
-
-from ...utils import period_program
-
-
-class Command(BaseCommand):
-    def handle(self, year, week, **options):
-        date = _date_from_string(year, '%Y',
-                '1', '%w',
-                week, '%W')
-        date = datetime(*date.timetuple()[:3])
-        for entry in period_program(date, date+timedelta(days=7)):
-            print entry.datetime, entry
diff --git a/panikdb/emissions/management/commands/whatsonair.py b/panikdb/emissions/management/commands/whatsonair.py
deleted file mode 100644 (file)
index d016c6f..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-from django.core.management.base import BaseCommand, CommandError
-
-from ...utils import whatsonair
-
-
-class Command(BaseCommand):
-    def handle(self, *args, **options):
-        onair = whatsonair()
-        print 'found episode:', onair.get('episode')
-        print 'found emission:', onair.get('emission')
-        print 'found nonstop:', onair.get('nonstop')
diff --git a/panikdb/emissions/migrations/0001_initial.py b/panikdb/emissions/migrations/0001_initial.py
deleted file mode 100644 (file)
index adeea02..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'Category'
-        db.create_table(u'emissions_category', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('title', self.gf('django.db.models.fields.CharField')(max_length=50)),
-        ))
-        db.send_create_signal(u'emissions', ['Category'])
-
-        # Adding model 'Emission'
-        db.create_table(u'emissions_emission', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('title', self.gf('django.db.models.fields.CharField')(max_length=50)),
-            ('slug', self.gf('django.db.models.fields.SlugField')(max_length=50)),
-            ('description', self.gf('ckeditor.fields.RichTextField')(null=True, blank=True)),
-            ('text', self.gf('ckeditor.fields.RichTextField')(null=True)),
-            ('archived', self.gf('django.db.models.fields.BooleanField')(default=False)),
-        ))
-        db.send_create_signal(u'emissions', ['Emission'])
-
-        # Adding M2M table for field categories on 'Emission'
-        m2m_table_name = db.shorten_name(u'emissions_emission_categories')
-        db.create_table(m2m_table_name, (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('emission', models.ForeignKey(orm[u'emissions.emission'], null=False)),
-            ('category', models.ForeignKey(orm[u'emissions.category'], null=False))
-        ))
-        db.create_unique(m2m_table_name, ['emission_id', 'category_id'])
-
-        # Adding model 'Schedule'
-        db.create_table(u'emissions_schedule', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('emission', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['emissions.Emission'])),
-            ('datetime', self.gf('django.db.models.fields.DateTimeField')()),
-            ('rerun', self.gf('django.db.models.fields.BooleanField')(default=False)),
-        ))
-        db.send_create_signal(u'emissions', ['Schedule'])
-
-        # Adding model 'Episode'
-        db.create_table(u'emissions_episode', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('emission', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['emissions.Emission'])),
-            ('title', self.gf('django.db.models.fields.CharField')(max_length=50)),
-            ('slug', self.gf('django.db.models.fields.SlugField')(max_length=50)),
-            ('description', self.gf('ckeditor.fields.RichTextField')(null=True, blank=True)),
-            ('text', self.gf('ckeditor.fields.RichTextField')(null=True)),
-        ))
-        db.send_create_signal(u'emissions', ['Episode'])
-
-        # Adding model 'Diffusion'
-        db.create_table(u'emissions_diffusion', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('episode', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['emissions.Episode'])),
-            ('datetime', self.gf('django.db.models.fields.DateTimeField')()),
-        ))
-        db.send_create_signal(u'emissions', ['Diffusion'])
-
-        # Adding model 'SoundFile'
-        db.create_table(u'emissions_soundfile', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('episode', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['emissions.Episode'])),
-            ('file', self.gf('django.db.models.fields.files.FileField')(max_length=250)),
-            ('podcastable', self.gf('django.db.models.fields.BooleanField')(default=False)),
-            ('fragment', self.gf('django.db.models.fields.BooleanField')(default=False)),
-            ('title', self.gf('django.db.models.fields.CharField')(max_length=50)),
-        ))
-        db.send_create_signal(u'emissions', ['SoundFile'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'Category'
-        db.delete_table(u'emissions_category')
-
-        # Deleting model 'Emission'
-        db.delete_table(u'emissions_emission')
-
-        # Removing M2M table for field categories on 'Emission'
-        db.delete_table(db.shorten_name(u'emissions_emission_categories'))
-
-        # Deleting model 'Schedule'
-        db.delete_table(u'emissions_schedule')
-
-        # Deleting model 'Episode'
-        db.delete_table(u'emissions_episode')
-
-        # Deleting model 'Diffusion'
-        db.delete_table(u'emissions_diffusion')
-
-        # Deleting model 'SoundFile'
-        db.delete_table(u'emissions_soundfile')
-
-
-    models = {
-        u'emissions.category': {
-            'Meta': {'object_name': 'Category'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.diffusion': {
-            'Meta': {'object_name': 'Diffusion'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        u'emissions.emission': {
-            'Meta': {'object_name': 'Emission'},
-            'archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['emissions.Category']", 'symmetrical': 'False'}),
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.episode': {
-            'Meta': {'object_name': 'Episode'},
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.schedule': {
-            'Meta': {'object_name': 'Schedule'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'rerun': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        u'emissions.soundfile': {
-            'Meta': {'object_name': 'SoundFile'},
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'}),
-            'fragment': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'podcastable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['emissions']
\ No newline at end of file
diff --git a/panikdb/emissions/migrations/0002_auto__add_field_emission_duration.py b/panikdb/emissions/migrations/0002_auto__add_field_emission_duration.py
deleted file mode 100644 (file)
index ceb8cae..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Emission.duration'
-        db.add_column(u'emissions_emission', 'duration',
-                      self.gf('django.db.models.fields.IntegerField')(default=60),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Emission.duration'
-        db.delete_column(u'emissions_emission', 'duration')
-
-
-    models = {
-        u'emissions.category': {
-            'Meta': {'object_name': 'Category'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.diffusion': {
-            'Meta': {'object_name': 'Diffusion'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        u'emissions.emission': {
-            'Meta': {'object_name': 'Emission'},
-            'archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['emissions.Category']", 'symmetrical': 'False'}),
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'default': '60'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.episode': {
-            'Meta': {'object_name': 'Episode'},
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.schedule': {
-            'Meta': {'object_name': 'Schedule'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'rerun': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        u'emissions.soundfile': {
-            'Meta': {'object_name': 'SoundFile'},
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'}),
-            'fragment': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'podcastable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['emissions']
\ No newline at end of file
diff --git a/panikdb/emissions/migrations/0003_auto__add_field_emission_email__add_field_emission_website.py b/panikdb/emissions/migrations/0003_auto__add_field_emission_email__add_field_emission_website.py
deleted file mode 100644 (file)
index cb4d462..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Emission.email'
-        db.add_column(u'emissions_emission', 'email',
-                      self.gf('django.db.models.fields.EmailField')(max_length=254, null=True, blank=True),
-                      keep_default=False)
-
-        # Adding field 'Emission.website'
-        db.add_column(u'emissions_emission', 'website',
-                      self.gf('django.db.models.fields.URLField')(max_length=200, null=True, blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Emission.email'
-        db.delete_column(u'emissions_emission', 'email')
-
-        # Deleting field 'Emission.website'
-        db.delete_column(u'emissions_emission', 'website')
-
-
-    models = {
-        u'emissions.category': {
-            'Meta': {'object_name': 'Category'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.diffusion': {
-            'Meta': {'object_name': 'Diffusion'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        u'emissions.emission': {
-            'Meta': {'object_name': 'Emission'},
-            'archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['emissions.Category']", 'symmetrical': 'False'}),
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'default': '60'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '254', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
-            'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
-        },
-        u'emissions.episode': {
-            'Meta': {'object_name': 'Episode'},
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.schedule': {
-            'Meta': {'object_name': 'Schedule'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'rerun': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        u'emissions.soundfile': {
-            'Meta': {'object_name': 'SoundFile'},
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'}),
-            'fragment': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'podcastable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['emissions']
\ No newline at end of file
diff --git a/panikdb/emissions/migrations/0004_auto__add_field_episode_image__add_field_emission_image.py b/panikdb/emissions/migrations/0004_auto__add_field_episode_image__add_field_emission_image.py
deleted file mode 100644 (file)
index 54348ef..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Episode.image'
-        db.add_column(u'emissions_episode', 'image',
-                      self.gf('django.db.models.fields.files.ImageField')(max_length=250, null=True, blank=True),
-                      keep_default=False)
-
-        # Adding field 'Emission.image'
-        db.add_column(u'emissions_emission', 'image',
-                      self.gf('django.db.models.fields.files.ImageField')(max_length=250, null=True, blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Episode.image'
-        db.delete_column(u'emissions_episode', 'image')
-
-        # Deleting field 'Emission.image'
-        db.delete_column(u'emissions_emission', 'image')
-
-
-    models = {
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'emissions.category': {
-            'Meta': {'object_name': 'Category'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.diffusion': {
-            'Meta': {'object_name': 'Diffusion'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        u'emissions.emission': {
-            'Meta': {'object_name': 'Emission'},
-            'archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['emissions.Category']", 'symmetrical': 'False'}),
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'default': '60'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '254', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
-            'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
-        },
-        u'emissions.episode': {
-            'Meta': {'object_name': 'Episode'},
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.schedule': {
-            'Meta': {'object_name': 'Schedule'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'rerun': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        u'emissions.soundfile': {
-            'Meta': {'object_name': 'SoundFile'},
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'}),
-            'fragment': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'podcastable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'taggit.tag': {
-            'Meta': {'object_name': 'Tag'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'})
-        },
-        u'taggit.taggeditem': {
-            'Meta': {'object_name': 'TaggedItem'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_tagged_items'", 'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_items'", 'to': u"orm['taggit.Tag']"})
-        }
-    }
-
-    complete_apps = ['emissions']
\ No newline at end of file
diff --git a/panikdb/emissions/migrations/0005_auto__add_field_schedule_weeks.py b/panikdb/emissions/migrations/0005_auto__add_field_schedule_weeks.py
deleted file mode 100644 (file)
index 896deea..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Schedule.weeks'
-        db.add_column(u'emissions_schedule', 'weeks',
-                      self.gf('django.db.models.fields.IntegerField')(default=15),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Schedule.weeks'
-        db.delete_column(u'emissions_schedule', 'weeks')
-
-
-    models = {
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'emissions.category': {
-            'Meta': {'object_name': 'Category'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.diffusion': {
-            'Meta': {'object_name': 'Diffusion'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        u'emissions.emission': {
-            'Meta': {'object_name': 'Emission'},
-            'archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['emissions.Category']", 'symmetrical': 'False'}),
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'default': '60'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '254', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
-            'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
-        },
-        u'emissions.episode': {
-            'Meta': {'object_name': 'Episode'},
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.schedule': {
-            'Meta': {'object_name': 'Schedule'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'rerun': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'weeks': ('django.db.models.fields.IntegerField', [], {'default': '15'})
-        },
-        u'emissions.soundfile': {
-            'Meta': {'object_name': 'SoundFile'},
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'}),
-            'fragment': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'podcastable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'taggit.tag': {
-            'Meta': {'object_name': 'Tag'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'})
-        },
-        u'taggit.taggeditem': {
-            'Meta': {'object_name': 'TaggedItem'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_tagged_items'", 'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_items'", 'to': u"orm['taggit.Tag']"})
-        }
-    }
-
-    complete_apps = ['emissions']
\ No newline at end of file
diff --git a/panikdb/emissions/migrations/0006_auto__add_newsitem__add_newscategory.py b/panikdb/emissions/migrations/0006_auto__add_newsitem__add_newscategory.py
deleted file mode 100644 (file)
index 260183f..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'NewsItem'
-        db.create_table(u'emissions_newsitem', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('title', self.gf('django.db.models.fields.CharField')(max_length=50)),
-            ('slug', self.gf('django.db.models.fields.SlugField')(max_length=50)),
-            ('text', self.gf('ckeditor.fields.RichTextField')()),
-            ('datetime', self.gf('django.db.models.fields.DateTimeField')()),
-            ('image', self.gf('django.db.models.fields.files.ImageField')(max_length=250, null=True, blank=True)),
-            ('category', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['emissions.NewsCategory'], null=True)),
-            ('emission', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['emissions.Emission'], null=True)),
-        ))
-        db.send_create_signal(u'emissions', ['NewsItem'])
-
-        # Adding model 'NewsCategory'
-        db.create_table(u'emissions_newscategory', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('title', self.gf('django.db.models.fields.CharField')(max_length=50)),
-        ))
-        db.send_create_signal(u'emissions', ['NewsCategory'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'NewsItem'
-        db.delete_table(u'emissions_newsitem')
-
-        # Deleting model 'NewsCategory'
-        db.delete_table(u'emissions_newscategory')
-
-
-    models = {
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'emissions.category': {
-            'Meta': {'object_name': 'Category'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.diffusion': {
-            'Meta': {'object_name': 'Diffusion'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        u'emissions.emission': {
-            'Meta': {'object_name': 'Emission'},
-            'archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['emissions.Category']", 'symmetrical': 'False'}),
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'default': '60'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '254', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
-            'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
-        },
-        u'emissions.episode': {
-            'Meta': {'object_name': 'Episode'},
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.newscategory': {
-            'Meta': {'object_name': 'NewsCategory'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.newsitem': {
-            'Meta': {'object_name': 'NewsItem'},
-            'category': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.NewsCategory']", 'null': 'True'}),
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']", 'null': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.schedule': {
-            'Meta': {'object_name': 'Schedule'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'rerun': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'weeks': ('django.db.models.fields.IntegerField', [], {'default': '15'})
-        },
-        u'emissions.soundfile': {
-            'Meta': {'object_name': 'SoundFile'},
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'}),
-            'fragment': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'podcastable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'taggit.tag': {
-            'Meta': {'object_name': 'Tag'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'})
-        },
-        u'taggit.taggeditem': {
-            'Meta': {'object_name': 'TaggedItem'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_tagged_items'", 'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_items'", 'to': u"orm['taggit.Tag']"})
-        }
-    }
-
-    complete_apps = ['emissions']
\ No newline at end of file
diff --git a/panikdb/emissions/migrations/0007_auto__add_field_episode_duration__add_field_schedule_duration.py b/panikdb/emissions/migrations/0007_auto__add_field_episode_duration__add_field_schedule_duration.py
deleted file mode 100644 (file)
index dd10dd9..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Episode.duration'
-        db.add_column(u'emissions_episode', 'duration',
-                      self.gf('django.db.models.fields.IntegerField')(null=True, blank=True),
-                      keep_default=False)
-
-        # Adding field 'Schedule.duration'
-        db.add_column(u'emissions_schedule', 'duration',
-                      self.gf('django.db.models.fields.IntegerField')(null=True, blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Episode.duration'
-        db.delete_column(u'emissions_episode', 'duration')
-
-        # Deleting field 'Schedule.duration'
-        db.delete_column(u'emissions_schedule', 'duration')
-
-
-    models = {
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'emissions.category': {
-            'Meta': {'object_name': 'Category'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.diffusion': {
-            'Meta': {'object_name': 'Diffusion'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        u'emissions.emission': {
-            'Meta': {'object_name': 'Emission'},
-            'archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['emissions.Category']", 'symmetrical': 'False'}),
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'default': '60'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '254', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
-            'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
-        },
-        u'emissions.episode': {
-            'Meta': {'object_name': 'Episode'},
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.newscategory': {
-            'Meta': {'object_name': 'NewsCategory'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.newsitem': {
-            'Meta': {'object_name': 'NewsItem'},
-            'category': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.NewsCategory']", 'null': 'True'}),
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']", 'null': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.schedule': {
-            'Meta': {'object_name': 'Schedule'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'rerun': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'weeks': ('django.db.models.fields.IntegerField', [], {'default': '15'})
-        },
-        u'emissions.soundfile': {
-            'Meta': {'object_name': 'SoundFile'},
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'}),
-            'fragment': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'podcastable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'taggit.tag': {
-            'Meta': {'object_name': 'Tag'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'})
-        },
-        u'taggit.taggeditem': {
-            'Meta': {'object_name': 'TaggedItem'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_tagged_items'", 'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_items'", 'to': u"orm['taggit.Tag']"})
-        }
-    }
-
-    complete_apps = ['emissions']
\ No newline at end of file
diff --git a/panikdb/emissions/migrations/0008_auto__chg_enlarge_titles.py b/panikdb/emissions/migrations/0008_auto__chg_enlarge_titles.py
deleted file mode 100644 (file)
index c396d75..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Changing field 'SoundFile.title'
-        db.alter_column(u'emissions_soundfile', 'title', self.gf('django.db.models.fields.CharField')(max_length=100))
-
-        # Changing field 'NewsItem.title'
-        db.alter_column(u'emissions_newsitem', 'title', self.gf('django.db.models.fields.CharField')(max_length=100))
-
-        # Changing field 'Episode.title'
-        db.alter_column(u'emissions_episode', 'title', self.gf('django.db.models.fields.CharField')(max_length=100))
-
-        # Changing field 'Emission.title'
-        db.alter_column(u'emissions_emission', 'title', self.gf('django.db.models.fields.CharField')(max_length=100))
-
-    def backwards(self, orm):
-
-        # Changing field 'SoundFile.title'
-        db.alter_column(u'emissions_soundfile', 'title', self.gf('django.db.models.fields.CharField')(max_length=50))
-
-        # Changing field 'NewsItem.title'
-        db.alter_column(u'emissions_newsitem', 'title', self.gf('django.db.models.fields.CharField')(max_length=50))
-
-        # Changing field 'Episode.title'
-        db.alter_column(u'emissions_episode', 'title', self.gf('django.db.models.fields.CharField')(max_length=50))
-
-        # Changing field 'Emission.title'
-        db.alter_column(u'emissions_emission', 'title', self.gf('django.db.models.fields.CharField')(max_length=50))
-
-    models = {
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'emissions.category': {
-            'Meta': {'object_name': 'Category'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.diffusion': {
-            'Meta': {'object_name': 'Diffusion'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        u'emissions.emission': {
-            'Meta': {'object_name': 'Emission'},
-            'archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['emissions.Category']", 'symmetrical': 'False'}),
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'default': '60'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '254', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
-        },
-        u'emissions.episode': {
-            'Meta': {'object_name': 'Episode'},
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'emissions.newscategory': {
-            'Meta': {'object_name': 'NewsCategory'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.newsitem': {
-            'Meta': {'object_name': 'NewsItem'},
-            'category': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.NewsCategory']", 'null': 'True'}),
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']", 'null': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'emissions.schedule': {
-            'Meta': {'object_name': 'Schedule'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'rerun': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'weeks': ('django.db.models.fields.IntegerField', [], {'default': '15'})
-        },
-        u'emissions.soundfile': {
-            'Meta': {'object_name': 'SoundFile'},
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'}),
-            'fragment': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'podcastable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'taggit.tag': {
-            'Meta': {'object_name': 'Tag'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'})
-        },
-        u'taggit.taggeditem': {
-            'Meta': {'object_name': 'TaggedItem'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_tagged_items'", 'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_items'", 'to': u"orm['taggit.Tag']"})
-        }
-    }
-
-    complete_apps = ['emissions']
\ No newline at end of file
diff --git a/panikdb/emissions/migrations/0009_auto__enlarge_titles_even_more.py b/panikdb/emissions/migrations/0009_auto__enlarge_titles_even_more.py
deleted file mode 100644 (file)
index d49e114..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Changing field 'SoundFile.title'
-        db.alter_column(u'emissions_soundfile', 'title', self.gf('django.db.models.fields.CharField')(max_length=200))
-
-        # Changing field 'NewsItem.title'
-        db.alter_column(u'emissions_newsitem', 'title', self.gf('django.db.models.fields.CharField')(max_length=200))
-
-        # Changing field 'Episode.title'
-        db.alter_column(u'emissions_episode', 'title', self.gf('django.db.models.fields.CharField')(max_length=200))
-
-        # Changing field 'Emission.title'
-        db.alter_column(u'emissions_emission', 'title', self.gf('django.db.models.fields.CharField')(max_length=200))
-
-    def backwards(self, orm):
-
-        # Changing field 'SoundFile.title'
-        db.alter_column(u'emissions_soundfile', 'title', self.gf('django.db.models.fields.CharField')(max_length=100))
-
-        # Changing field 'NewsItem.title'
-        db.alter_column(u'emissions_newsitem', 'title', self.gf('django.db.models.fields.CharField')(max_length=100))
-
-        # Changing field 'Episode.title'
-        db.alter_column(u'emissions_episode', 'title', self.gf('django.db.models.fields.CharField')(max_length=100))
-
-        # Changing field 'Emission.title'
-        db.alter_column(u'emissions_emission', 'title', self.gf('django.db.models.fields.CharField')(max_length=100))
-
-    models = {
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'emissions.category': {
-            'Meta': {'object_name': 'Category'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.diffusion': {
-            'Meta': {'object_name': 'Diffusion'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        u'emissions.emission': {
-            'Meta': {'object_name': 'Emission'},
-            'archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['emissions.Category']", 'symmetrical': 'False'}),
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'default': '60'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '254', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
-            'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
-        },
-        u'emissions.episode': {
-            'Meta': {'object_name': 'Episode'},
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
-        },
-        u'emissions.newscategory': {
-            'Meta': {'object_name': 'NewsCategory'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.newsitem': {
-            'Meta': {'object_name': 'NewsItem'},
-            'category': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.NewsCategory']", 'null': 'True'}),
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']", 'null': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
-        },
-        u'emissions.schedule': {
-            'Meta': {'object_name': 'Schedule'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'rerun': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'weeks': ('django.db.models.fields.IntegerField', [], {'default': '15'})
-        },
-        u'emissions.soundfile': {
-            'Meta': {'object_name': 'SoundFile'},
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'}),
-            'fragment': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'podcastable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
-        },
-        u'taggit.tag': {
-            'Meta': {'object_name': 'Tag'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'})
-        },
-        u'taggit.taggeditem': {
-            'Meta': {'object_name': 'TaggedItem'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_tagged_items'", 'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_items'", 'to': u"orm['taggit.Tag']"})
-        }
-    }
-
-    complete_apps = ['emissions']
\ No newline at end of file
diff --git a/panikdb/emissions/migrations/0010_auto__add_nonstop.py b/panikdb/emissions/migrations/0010_auto__add_nonstop.py
deleted file mode 100644 (file)
index 9310f11..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'Nonstop'
-        db.create_table(u'emissions_nonstop', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('title', self.gf('django.db.models.fields.CharField')(max_length=50)),
-            ('start', self.gf('django.db.models.fields.TimeField')()),
-            ('end', self.gf('django.db.models.fields.TimeField')()),
-        ))
-        db.send_create_signal(u'emissions', ['Nonstop'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'Nonstop'
-        db.delete_table(u'emissions_nonstop')
-
-
-    models = {
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'emissions.category': {
-            'Meta': {'object_name': 'Category'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.diffusion': {
-            'Meta': {'object_name': 'Diffusion'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        u'emissions.emission': {
-            'Meta': {'object_name': 'Emission'},
-            'archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['emissions.Category']", 'symmetrical': 'False'}),
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'default': '60'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '254', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
-            'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
-        },
-        u'emissions.episode': {
-            'Meta': {'object_name': 'Episode'},
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
-        },
-        u'emissions.newscategory': {
-            'Meta': {'object_name': 'NewsCategory'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.newsitem': {
-            'Meta': {'object_name': 'NewsItem'},
-            'category': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.NewsCategory']", 'null': 'True'}),
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']", 'null': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
-        },
-        u'emissions.nonstop': {
-            'Meta': {'object_name': 'Nonstop'},
-            'end': ('django.db.models.fields.TimeField', [], {}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'start': ('django.db.models.fields.TimeField', [], {}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.schedule': {
-            'Meta': {'object_name': 'Schedule'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'rerun': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'weeks': ('django.db.models.fields.IntegerField', [], {'default': '15'})
-        },
-        u'emissions.soundfile': {
-            'Meta': {'object_name': 'SoundFile'},
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'}),
-            'fragment': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'podcastable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
-        },
-        u'taggit.tag': {
-            'Meta': {'object_name': 'Tag'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'})
-        },
-        u'taggit.taggeditem': {
-            'Meta': {'object_name': 'TaggedItem'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_tagged_items'", 'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_items'", 'to': u"orm['taggit.Tag']"})
-        }
-    }
-
-    complete_apps = ['emissions']
diff --git a/panikdb/emissions/migrations/0011_load_nonstop.py b/panikdb/emissions/migrations/0011_load_nonstop.py
deleted file mode 100644 (file)
index 2b475a9..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import DataMigration
-from django.db import models
-
-class Migration(DataMigration):
-
-    def forwards(self, orm):
-        from django.core.management import call_command
-        call_command('loaddata', 'nonstop.json')
-
-    def backwards(self, orm):
-        pass
-
-    models = {
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'emissions.category': {
-            'Meta': {'object_name': 'Category'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.diffusion': {
-            'Meta': {'object_name': 'Diffusion'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        u'emissions.emission': {
-            'Meta': {'object_name': 'Emission'},
-            'archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['emissions.Category']", 'symmetrical': 'False'}),
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'default': '60'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '254', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
-            'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
-        },
-        u'emissions.episode': {
-            'Meta': {'object_name': 'Episode'},
-            'description': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
-        },
-        u'emissions.newscategory': {
-            'Meta': {'object_name': 'NewsCategory'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.newsitem': {
-            'Meta': {'object_name': 'NewsItem'},
-            'category': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.NewsCategory']", 'null': 'True'}),
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']", 'null': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'text': ('ckeditor.fields.RichTextField', [], {}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
-        },
-        u'emissions.nonstop': {
-            'Meta': {'object_name': 'Nonstop'},
-            'end': ('django.db.models.fields.TimeField', [], {}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'start': ('django.db.models.fields.TimeField', [], {}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'emissions.schedule': {
-            'Meta': {'object_name': 'Schedule'},
-            'datetime': ('django.db.models.fields.DateTimeField', [], {}),
-            'duration': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'emission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Emission']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'rerun': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'weeks': ('django.db.models.fields.IntegerField', [], {'default': '15'})
-        },
-        u'emissions.soundfile': {
-            'Meta': {'object_name': 'SoundFile'},
-            'episode': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['emissions.Episode']"}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'}),
-            'fragment': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'podcastable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
-        },
-        u'taggit.tag': {
-            'Meta': {'object_name': 'Tag'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'})
-        },
-        u'taggit.taggeditem': {
-            'Meta': {'object_name': 'TaggedItem'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_tagged_items'", 'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_items'", 'to': u"orm['taggit.Tag']"})
-        }
-    }
-
-    complete_apps = ['emissions']
-    symmetrical = True
diff --git a/panikdb/emissions/migrations/__init__.py b/panikdb/emissions/migrations/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/panikdb/emissions/models.py b/panikdb/emissions/models.py
deleted file mode 100644 (file)
index aa1ae6f..0000000
+++ /dev/null
@@ -1,296 +0,0 @@
-import datetime
-import os
-
-from django.forms import fields
-from django.core.urlresolvers import reverse
-
-from django.db import models
-
-from ckeditor.fields import RichTextField
-from taggit.managers import TaggableManager
-
-from utils import maybe_resize
-
-
-class WeekdayMixin:
-    DAY_HOUR_START = 6
-
-    def get_weekday(self):
-        weekday = self.datetime.weekday() + 7
-        if self.datetime.time() < datetime.time(self.DAY_HOUR_START, 0):
-            weekday -= 1
-        weekday %= 7
-        return weekday
-
-    def is_on_weekday(self, day): # day is [1..7]
-        week_day = self.datetime.weekday()
-        if self.datetime.hour < self.DAY_HOUR_START:
-            week_day -= 1
-        week_day = (week_day % 7) + 1
-        return week_day == day
-
-
-class Category(models.Model):
-    title = models.CharField(max_length=50)
-
-    def sorted_emission(self):
-        return self.emission_set.order_by('title')
-
-    def __unicode__(self):
-        return self.title
-
-
-def get_emission_image_path(instance, filename):
-    return os.path.join('images', instance.slug,
-            os.path.basename(filename))
-
-
-class Emission(models.Model):
-    title = models.CharField(max_length=200)
-    slug = models.SlugField()
-    description = RichTextField(null=True, blank=True)
-    text = RichTextField(null=True)
-    archived = models.BooleanField(default=False)
-    categories = models.ManyToManyField(Category)
-
-    # XXX: languages (models.ManyToManyField(Language))
-
-    duration = models.IntegerField(default=60)
-
-    email = models.EmailField(max_length=254, null=True, blank=True)
-    website = models.URLField(null=True, blank=True)
-
-    image = models.ImageField(upload_to=get_emission_image_path, max_length=250, null=True, blank=True)
-
-    def get_absolute_url(self):
-        return reverse('emission-view', kwargs={'slug': str(self.slug)})
-
-    def __unicode__(self):
-        return self.title
-
-    def save(self, *args, **kwargs):
-        super(Emission, self).save(*args, **kwargs)
-        if self.id is not None and self.image:
-            maybe_resize(self.image.path)
-
-    def get_absolute_url(self):
-        return reverse('emission-view',
-                        kwargs={'slug':  str(self.slug)})
-
-    def get_schedules(self):
-        return Schedule.objects.filter(emission=self).order_by('datetime')
-
-    def get_sorted_emissions(self):
-        return self.episode_set.select_related().extra(select={
-                'first_diffusion': 'emissions_diffusion.datetime',
-                },
-                select_params=(False, True),
-                where=['''datetime = (SELECT MIN(datetime)
-                                        FROM emissions_diffusion
-                                       WHERE episode_id = emissions_episode.id)'''],
-                tables=['emissions_diffusion'],
-            ).order_by('-first_diffusion')
-
-
-
-class Schedule(models.Model, WeekdayMixin):
-
-    WEEK_CHOICES = (
-        (0b1111, 'Every week'),
-        (0b0001, 'First week'),
-        (0b0010, 'Second week'),
-        (0b0100, 'Third week'),
-        (0b1000, 'Fourth week'),
-        (0b0101, 'First and third week'),
-        (0b1010, 'Second and fourth week')
-    )
-    emission = models.ForeignKey('Emission', verbose_name=u'Emission')
-    datetime = models.DateTimeField()
-    weeks = models.IntegerField(default=15, choices=WEEK_CHOICES)
-    rerun = models.BooleanField(default=False)
-    duration = models.IntegerField(null=True, blank=True)
-
-    @property
-    def weeks_string(self):
-        if self.weeks == 0b0001:
-            return u'1er du mois'
-        elif self.weeks == 0b0010:
-            return u'2e du mois'
-        elif self.weeks == 0b0100:
-            return u'3e du mois'
-        elif self.weeks == 0b1000:
-            return u'4e du mois'
-        elif self.weeks == 0b0101:
-            return '1er et 3e'
-        elif self.weeks == 0b1010:
-            return '2e et 4e'
-        return None
-
-    def get_duration(self):
-        if self.duration:
-            return self.duration
-        else:
-            return self.emission.duration
-
-    def match_week(self, week_no):
-        if week_no == 4:
-            week_no = 3
-        if (self.weeks & (0b0001<<(week_no)) == 0):
-            return False
-        return True
-
-    def matches(self, dt):
-        weekday = dt.weekday()
-        if dt.hour < self.DAY_HOUR_START:
-            weekday -= 1
-        if weekday != self.get_weekday():
-            return False
-        if self.weeks != 0b1111:
-            week_no = (dt.day-1) // 7
-            if self.match_week(week_no) is False:
-                return False
-        if dt.time() >= self.datetime.time() and \
-                dt.time() <= (self.datetime + datetime.timedelta(minutes=self.get_duration())).time():
-            return True
-        return False
-
-    def __unicode__(self):
-        return u'%s at %s' % (self.emission.title,
-                self.datetime.strftime('%a %H:%M'))
-
-
-def get_episode_image_path(instance, filename):
-    return os.path.join('images', instance.emission.slug,
-            os.path.basename(filename))
-
-
-class Episode(models.Model):
-    emission = models.ForeignKey('Emission', verbose_name=u'Emission')
-    title = models.CharField(max_length=200)
-    slug = models.SlugField()
-    description = RichTextField(null=True, blank=True)
-    text = RichTextField(null=True)
-    tags = TaggableManager(blank=True)
-    duration = models.IntegerField(null=True, blank=True)
-
-    image = models.ImageField(upload_to=get_episode_image_path, max_length=250, null=True, blank=True)
-
-    # XXX: languages (models.ManyToManyField(Language))
-
-    def __unicode__(self):
-        return self.title
-
-    def save(self, *args, **kwargs):
-        super(Episode, self).save(*args, **kwargs)
-        if self.id is not None and self.image:
-            maybe_resize(self.image.path)
-
-    def get_duration(self):
-        if self.duration:
-            return self.duration
-        else:
-            return self.emission.duration
-
-    def get_absolute_url(self):
-        return reverse('episode-view',
-                        kwargs={'emission_slug': str(self.emission.slug),
-                                'slug':  str(self.slug)})
-
-    def has_sound(self):
-        return (self.soundfile_set.count() > 0)
-
-    _main_sound = False
-
-    @property
-    def main_sound(self):
-        if self._main_sound is not False:
-            return self._main_sound
-
-        t = self.soundfile_set.exclude(podcastable=False).exclude(fragment=True)
-        if t:
-            self._main_sound = t[0]
-        else:
-            self._main_sound = None
-
-        return self._main_sound
-
-    @main_sound.setter
-    def main_sound(self, value):
-        self._main_sound = value
-
-
-class Diffusion(models.Model, WeekdayMixin):
-    episode = models.ForeignKey('Episode', verbose_name=u'Episode')
-    datetime = models.DateTimeField()
-
-    def __unicode__(self):
-        return u'%s at %02d:%02d' % (self.episode.title, self.datetime.hour,
-                self.datetime.minute)
-
-    def get_duration(self):
-        return self.episode.get_duration()
-
-
-def get_sound_path(instance, filename):
-    return os.path.join('sounds', instance.episode.emission.slug,
-            os.path.basename(filename))
-
-class SoundFile(models.Model):
-    episode = models.ForeignKey('Episode', verbose_name=u'Episode')
-    file = models.FileField(upload_to=get_sound_path, max_length=250)
-    podcastable = models.BooleanField(default=False)
-    fragment = models.BooleanField(default=False)
-    title = models.CharField(max_length=200)
-
-    def get_format_filename(self, format):
-        return '%s_%05d__%s.%s' % (
-                self.episode.slug,
-                self.id,
-                (self.fragment and '0' or '1'),
-                format)
-
-    def get_format_path(self, format):
-        if not self.file:
-            return None
-        return '%s/%s' % (os.path.dirname(self.file.path), self.get_format_filename(format))
-
-    def get_format_url(self, format):
-        if not self.file:
-            return None
-        return '%s/%s' % (os.path.dirname(self.file.url), self.get_format_filename(format))
-
-
-class NewsCategory(models.Model):
-    title = models.CharField(max_length=50)
-
-    def __unicode__(self):
-        return self.title
-
-
-def get_newsitem_image_path(instance, filename):
-    return os.path.join('images', 'news', instance.slug,
-            os.path.basename(filename))
-
-
-class NewsItem(models.Model):
-    title = models.CharField(max_length=200)
-    slug = models.SlugField()
-    text = RichTextField()
-    datetime = models.DateTimeField()
-    image = models.ImageField(upload_to=get_newsitem_image_path, max_length=250, null=True, blank=True)
-
-    tags = TaggableManager(blank=True)
-    category = models.ForeignKey('NewsCategory', verbose_name=u'Category', null=True, blank=True)
-    emission = models.ForeignKey('Emission', null=True, blank=True)
-
-    def __unicode__(self):
-        return self.title
-
-
-class Nonstop(models.Model):
-    title = models.CharField(max_length=50)
-    start = models.TimeField()
-    end = models.TimeField()
-
-    def __unicode__(self):
-        return self.title
diff --git a/panikdb/emissions/search_indexes.py b/panikdb/emissions/search_indexes.py
deleted file mode 100644 (file)
index 35a6aeb..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-import datetime
-
-from haystack import indexes
-
-from .models import Emission, Episode, NewsItem
-
-
-class EmissionIndex(indexes.SearchIndex, indexes.Indexable):
-    title = indexes.CharField(model_attr='title', boost=1.5)
-    text = indexes.CharField(document=True, use_template=True)
-    categories = indexes.MultiValueField(faceted=True)
-
-    def prepare(self, obj):
-        data = super(EmissionIndex, self).prepare(obj)
-        data['boost'] = 1.3
-        return data
-
-    def get_model(self):
-        return Emission
-
-    def prepare_categories(self, obj):
-        return [category.title for category in obj.categories.all()]
-
-
-class EpisodeIndex(indexes.SearchIndex, indexes.Indexable):
-    title = indexes.CharField(model_attr='title', boost=1.5)
-    text = indexes.CharField(document=True, use_template=True)
-    tags = indexes.MultiValueField(faceted=True)
-
-    def get_model(self):
-        return Episode
-
-    def prepare_tags(self, obj):
-        return [tag.name for tag in obj.tags.all()]
-
-
-class NewsItemIndex(indexes.SearchIndex, indexes.Indexable):
-    title = indexes.CharField(model_attr='title', boost=1.5)
-    text = indexes.CharField(document=True, use_template=True)
-    tags = indexes.MultiValueField(faceted=True)
-
-    def prepare(self, obj):
-        data = super(NewsItemIndex, self).prepare(obj)
-        today = datetime.datetime.today()
-        if obj.datetime < today - datetime.timedelta(weeks=15):
-            # push older news in later pages
-            data['boost'] = 0.8
-        elif obj.datetime > today - datetime.timedelta(weeks=3):
-            # pull recent news
-            data['boost'] = 1.5
-        return data
-
-    def get_model(self):
-        return NewsItem
-
-    def prepare_tags(self, obj):
-        return [tag.name for tag in obj.tags.all()]
diff --git a/panikdb/emissions/templates/emissions/category_list.html b/panikdb/emissions/templates/emissions/category_list.html
deleted file mode 100644 (file)
index e384e76..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-{% extends "base.html" %}
-
-{% block appbar %}
-<h2>Émissions</h2>
-<span><a href=".">Par ordre alphabétique</a> - <a href="days">Par jour</a> - <a href="categories">Par genre</a></span>
-{% endblock %}
-
-{% block content %}
-
-{% for category in object_list %}
-<h3>{{ category.title }}</h3>
-
-<ul class="emission-list">
-{% for emission in category.sorted_emission %}
-{% if not emission.archived %}
-<li><a href="{{ emission.slug }}/">{{ emission.title }}</a></li>
-{% endif %}
-{% endfor %}
-</ul>
-
-{% endfor %}
-
-{% endblock %}
diff --git a/panikdb/emissions/templates/emissions/days.html b/panikdb/emissions/templates/emissions/days.html
deleted file mode 100644 (file)
index e485a1e..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-{% extends "base.html" %}
-
-{% block appbar %}
-<h2>Émissions</h2>
-<span><a href=".">Par ordre alphabétique</a> - <a href="days">Par jour</a> - <a href="categories">Par genre</a></span>
-{% endblock %}
-
-{% block content %}
-
-{% for day in days %}
-<h3>{{ day.datetime|date:"D" }}</h3>
-
-<ul class="emission-list">
-{% for schedule in day.schedules %}
-<li>{{ schedule.datetime|date:"H:i" }} <a href="{{ schedule.emission.slug }}/">{{ schedule.emission.title }}</a></li>
-{% endfor %}
-</ul>
-
-{% endfor %}
-
-{% endblock %}
diff --git a/panikdb/emissions/templates/emissions/emission_detail.html b/panikdb/emissions/templates/emissions/emission_detail.html
deleted file mode 100644 (file)
index 6568cb4..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-{% extends "base.html" %}
-
-{% block appbar %}
-<h2>{{ emission.title }}
-{% for category in emission.categories.all %}
-{% if forloop.first %} - {% endif %}
-<small><i>{{ category.title }} </i></small>
-{% endfor %}
-</h2>
-<span><a href="../">Retourner à la liste des émissions</a></span>
-{% endblock %}
-
-{% block content %}
-
-{% if emission.description %}
-<div class="description">
-{{ emission.description|safe }}
-</div>
-{% endif %}
-
-{% if emission.text %}
-{{ emission.text|safe }}
-{% endif %}
-
-<h3>Horaires</h3>
-
-<ul>
-{% for schedule in schedules %}
-<li>{{ schedule.datetime|date:"l G:i" }}
-{% if schedule.rerun %} (rediff) {% endif %}
-<a href="schedule/{{ schedule.id }}/remove" class="icon-remove-sign" title="Retirer"></a>
-</li>
-{% endfor %}
-</ul>
-
-<a id="add-schedule-link" href="#">Ajouter un horaire de diffusion</a>
-
-<form id="add-schedule-form" action="add-schedule" method="POST" style="display: none;">
-{% csrf_token %}
-{{ add_schedule_form.as_p }}
-<input type="submit" value="Ajouter cet horaire"/>
-</form>
-
-
-<h3>Épisodes</h3>
-
-<ul class="episode-list">
-{% for episode in episodes %}
-<li>{{ episode.first_diffusion|date:"d E o H:i"|lower }}
-<br/>   <a href="{{ episode.slug }}/">{{ episode.title }}</a>
-{% if episode.has_sound %}<span class="icon-music"/>{%endif%}
-</li>
-{% endfor %}
-</ul>
-
-
-<a href="add">New Episode</a> - <a href="edit/">Edit</a>
-
-
-
-{% endblock %}
-
-{% block page-end %}
-<script>
-$(function() {
-  $('#add-schedule-link').click(
-    function() {
-      $('#add-schedule-form').dialog({modal: true, title: 'Horaire', width: 'auto'});
-    });
-});
-</script>
-{% endblock %}
diff --git a/panikdb/emissions/templates/emissions/emission_form.html b/panikdb/emissions/templates/emissions/emission_form.html
deleted file mode 100644 (file)
index 2e12a79..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "base.html" %}
-
-{% block extrascripts %}
-<script src="{{ STATIC_URL }}ckeditor/ckeditor/ckeditor.js">
-</script>
-{% endblock %}
-
-{% block appbar %}
-<h2>{{ emission.title }}</h2>
-<span><a href="../">Retourner à l'émission</a></span>
-{% endblock %}
-
-
-{% block content %}
-    <form method="post">
-      <div id="form-content">
-        {% csrf_token %}
-        {{ form.as_p }}
-      </div>
-      {% block buttons %}
-      <button class="enable-on-change">Modifier</button>
-      {% endblock %}
-    </form>
-{% endblock %}
-
diff --git a/panikdb/emissions/templates/emissions/emission_list.html b/panikdb/emissions/templates/emissions/emission_list.html
deleted file mode 100644 (file)
index 2af3bc7..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-{% extends "base.html" %}
-
-{% block appbar %}
-<h2>Émissions</h2>
-<span><a href=".">Par ordre alphabétique</a> - <a href="days">Par jour</a> - <a href="categories">Par genre</a></span>
-{% endblock %}
-
-{% block content %}
-
-<ul class="emission-list">
-{% for emission in object_list %}
-{% if not emission.archived %}
-<li><a href="{{ emission.slug }}/">{{ emission.title }}</a></li>
-{% endif %}
-{% endfor %}
-</ul>
-
-<h3>Anciennes émissions</h3>
-
-<ul class="emission-list">
-{% for emission in object_list %}
-{% if emission.archived %}
-<li><a href="{{ emission.slug }}/">{{ emission.title }}</a></li>
-{% endif %}
-{% endfor %}
-</ul>
-
-
-<a href="add">New</a>
-
-{% endblock %}
diff --git a/panikdb/emissions/templates/emissions/episode_detail.html b/panikdb/emissions/templates/emissions/episode_detail.html
deleted file mode 100644 (file)
index e7373c0..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-{% extends "base.html" %}
-
-{% block appbar %}
-<h2>{{ episode.emission.title }} — {{ episode.title }}</h2>
-<span><a href="../">Retourner à l'émission</a></span>
-{% endblock %}
-
-{% block content %}
-
-<a class="big-friendly-button" href="edit/">Modifier</a>
-
-<a class="big-friendly-button" id="add-diffusion-link" href="#">Ajouter une diffusion</a>
-
-<a class="big-friendly-button" id="add-soundfile-link" href="#">Ajouter un son</a></p>
-
-
-{% if episode.description %}
-<div class="description">
-{{ episode.description|safe }}
-</div>
-{% endif %}
-
-{% if episode.text %}
-{{ episode.text|safe }}
-{% endif %}
-
-<h3>Diffusions</h3>
-
-<ul>
-{% for diffusion in diffusions %}
-<li>{{ diffusion.datetime }}
-<a href="diffusion/{{ diffusion.id }}/remove" class="icon-remove-sign" title="Retirer"></a>
-</li>
-{% endfor %}
-</ul>
-
-<form id="add-diffusion-form" action="add-diffusion" method="POST" style="display: none;">
-{% csrf_token %}
-{{ add_diffusion_form.as_p }}
-<input type="submit" value="Ajouter cet horaire"/>
-</form>
-
-
-
-<h3>Sons</h3>
-
-<table id="soundfiles">
-<thead>
-<tr>
- <th>Fichier</th>
- <th>Titre</th>
- <th>Podcastable?</th>
- <th>Fragment?</th>
-</thead>
-<tbody>
-{% for soundfile in soundfiles %}
-<tr>
-<td><a href="{{ soundfile.file.url }}">{{ soundfile.file.name }}</a></td>
-<td>{{ soundfile.title }}</td>
-<td>{{ soundfile.podcastable }}</td>
-<td>{{ soundfile.fragment }}</td>
-{% endfor %}
-</tbody>
-</table>
-
-<form id="add-soundfile-form" action="add-soundfile" method="POST" style="display: none;">
-{% csrf_token %}
-{{ add_soundfile_form.as_p }}
-<input type="submit" value="Ajouter ce son"/>
-</form>
-
-{% endblock %}
-
-
-{% block page-end %}
-<script>
-$(function() {
-  $('#add-soundfile-link').click(
-    function() {
-      $('#add-soundfile-form').dialog({modal: true, title: 'Son', width: 'auto'});
-    });
-
-  $('#add-diffusion-link').click(
-    function() {
-      $('#add-diffusion-form').dialog({modal: true, title: 'Horaire', width: 'auto'});
-    });
-});
-</script>
-{% endblock %}
diff --git a/panikdb/emissions/templates/emissions/episode_form.html b/panikdb/emissions/templates/emissions/episode_form.html
deleted file mode 100644 (file)
index 0310f93..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-{% extends "base.html" %}
-
-{% block extrascripts %}
-<script src="{{ STATIC_URL }}ckeditor/ckeditor/ckeditor.js">
-</script>
-{% endblock %}
-
-{% block appbar %}
-{% if episode.id %}
-<h2>{{ episode.emission.title }} — {{ episode.title }}</h2>
-<span><a href="../">Retourner à l'épisode</a></span>
-{% else %}
-<h2>{{ emission.title }} — Nouvel épisode</h2>
-<span><a href="./">Retourner à l'émission</a></span>
-{% endif %}
-{% endblock %}
-
-
-{% block content %}
-
-    <form method="post">
-      <div id="form-content">
-        {% csrf_token %}
-        <input type="hidden" name="id_emission" value="{{ emission.id }}"/>
-        {{ form.as_p }}
-      </div>
-      {% block buttons %}
-      {% if episode.id %}
-      <button>Modifier</button>
-      {% else %}
-      <button>Ajouter</button>
-      {% endif %}
-      {% endblock %}
-    </form>
-{% endblock %}
diff --git a/panikdb/emissions/templates/emissions/soundfile_form.html b/panikdb/emissions/templates/emissions/soundfile_form.html
deleted file mode 100644 (file)
index abb879c..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-{% extends "base.html" %}
-
-{% block extrascripts %}
-<script src="{{ STATIC_URL }}ckeditor/ckeditor/ckeditor.js">
-</script>
-{% endblock %}
-
-{% block content %}
-    <form method="post">
-      <div id="form-content">
-        {% csrf_token %}
-        {{ form.as_p }}
-      </div>
-      {% block buttons %}
-      <button class="enable-on-change">Modifier</button>
-      {% endblock %}
-    </form>
-{% endblock %}
-
diff --git a/panikdb/emissions/templates/emissions/upload.html b/panikdb/emissions/templates/emissions/upload.html
deleted file mode 100644 (file)
index 5aaa7a5..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-{% load i18n %}
-<div id="fileupload" class="file-upload-widget">
-  <div class="fileupload-buttonbar">
-    <label class="fileinput-button">
-      <input type="file" name="{{ name }}" data-url="{{ upload_url }}">
-      <span class="fileinfo"><span class="filename"/></span>
-    </label>
-  </div>
-  <div class="fileupload-content">
-    <div class="fileprogress" style="display: none;">
-      <div class="bar">
-      Upload en cours…
-      </div>
-    </div>
-  </div>
-</div>
diff --git a/panikdb/emissions/templates/search/indexes/emissions/emission_text.txt b/panikdb/emissions/templates/search/indexes/emissions/emission_text.txt
deleted file mode 100644 (file)
index 5916825..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-{{ object.title }}
-
-{{ object.description|striptags }}
-
-{{ object.text|striptags }}
diff --git a/panikdb/emissions/templates/search/indexes/emissions/episode_text.txt b/panikdb/emissions/templates/search/indexes/emissions/episode_text.txt
deleted file mode 100644 (file)
index 47238eb..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-{{ object.title }}
-
-{{ object.description|striptags }}
-
-{{ object.text|striptags }}
-
-{% for tag in object.tags.all %} {{ tag.name }} {% endfor %}
diff --git a/panikdb/emissions/templates/search/indexes/emissions/newsitem_text.txt b/panikdb/emissions/templates/search/indexes/emissions/newsitem_text.txt
deleted file mode 100644 (file)
index 6f1d5ee..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-{{ object.title }}
-
-{{ object.text|striptags }}
-
-{% if object.emission %}
-{{ object.emission.title }}
-{% endif %}
-
-{% for tag in object.tags.all %} {{ tag.name }} {% endfor %}
diff --git a/panikdb/emissions/templatetags/__init__.py b/panikdb/emissions/templatetags/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/panikdb/emissions/templatetags/soundfiles.py b/panikdb/emissions/templatetags/soundfiles.py
deleted file mode 100644 (file)
index a3234c5..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-import os
-
-from django.template import Library
-
-register = Library()
-
-
-@register.filter(name='is_format_available')
-def is_available(soundfile, format='ogg'):
-    if soundfile is None:
-        return False
-    sound_path = soundfile.get_format_path(format)
-    if not sound_path:
-        return False
-    return os.path.exists(sound_path)
-
-@register.filter(name='format_url')
-def format_url(soundfile, format='ogg'):
-    return soundfile.get_format_url(format)
diff --git a/panikdb/emissions/tests.py b/panikdb/emissions/tests.py
deleted file mode 100644 (file)
index 501deb7..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
-This file demonstrates writing tests using the unittest module. These will pass
-when you run "manage.py test".
-
-Replace this with more appropriate tests for your application.
-"""
-
-from django.test import TestCase
-
-
-class SimpleTest(TestCase):
-    def test_basic_addition(self):
-        """
-        Tests that 1 + 1 always equals 2.
-        """
-        self.assertEqual(1 + 1, 2)
diff --git a/panikdb/emissions/urls.py b/panikdb/emissions/urls.py
deleted file mode 100644 (file)
index c84660f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-from django.conf.urls import patterns, url
-
-from .views import *
-
-urlpatterns = patterns('',
-    url(r'^$', EmissionListView.as_view(), name='emission-list'),
-    url(r'^categories$', CategoryListView.as_view(), name='category-list'),
-    url(r'^days$', DaysView.as_view(), name='days'),
-    url(r'^add$', EmissionCreateView.as_view(), name='emission-add'),
-
-    url(r'^upload/(?P<transaction_id>[a-zA-Z0-9-]+)/$', UploadView.as_view(), name='upload'),
-
-    url(r'^(?P<slug>[\w,-]+)/$', EmissionDetailView.as_view(), name='emission-view'),
-    url(r'^(?P<slug>[\w,-]+)/edit/$', EmissionUpdateView.as_view(), name='emission-update'),
-    url(r'^(?P<slug>[\w,-]+)/delete/$', EmissionDeleteView.as_view(), name='emission-delete'),
-    url(r'^(?P<slug>[\w,-]+)/add-schedule$', EmissionAddScheduleView.as_view(), name='emission-add-schedule'),
-
-    url(r'^(?P<emission_slug>[\w,-]+)/schedule/(?P<pk>\d+)/remove$',
-            ScheduleDeleteView.as_view(), name='schedule-delete'),
-
-    url(r'^(?P<emission_slug>[\w,-]+)/add$', EpisodeCreateView.as_view(), name='episode-add'),
-    url(r'^(?P<emission_slug>[\w,-]+)/(?P<slug>[\w,-]+)/$', EpisodeDetailView.as_view(), name='episode-view'),
-    url(r'^(?P<emission_slug>[\w,-]+)/(?P<slug>[\w,-]+)/edit/$', EpisodeUpdateView.as_view(), name='episode-update'),
-    url(r'^(?P<emission_slug>[\w,-]+)/(?P<slug>[\w,-]+)/delete/$', EpisodeDeleteView.as_view(), name='episode-delete'),
-    url(r'^(?P<emission_slug>[\w,-]+)/(?P<slug>[\w,-]+)/add-soundfile$',
-            EpisodeAddSoundFileView.as_view(), name='episode-add-soundfile'),
-    url(r'^(?P<emission_slug>[\w,-]+)/(?P<slug>[\w,-]+)/add-diffusion$',
-            EpisodeAddDiffusionView.as_view(), name='episode-add-diffusion'),
-    url(r'^(?P<emission_slug>[\w,-]+)/(?P<slug>[\w,-]+)/diffusion/(?P<pk>\d+)/remove$',
-            DiffusionDeleteView.as_view(), name='diffusion-delete'),
-
-)
diff --git a/panikdb/emissions/utils.py b/panikdb/emissions/utils.py
deleted file mode 100644 (file)
index ac06e61..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-from datetime import datetime, timedelta, time
-import os
-from PIL import Image
-
-def maybe_resize(image_path):
-    if not os.path.exists(image_path):
-        return
-    image = Image.open(image_path)
-    if max(image.size) > 1000:
-        # no sense storing images that large
-        factor = 1000. / max(image.size)
-        image = image.resize(
-                (int(image.size[0]*factor), int(image.size[1]*factor)),
-                Image.ANTIALIAS)
-        image.save(image_path)
-
-
-def whatsonair():
-    from models import Diffusion, Schedule, Nonstop
-
-    now = datetime.now()
-    program = day_program(now)
-    program = [x for x in program if not x.datetime > now]
-
-    emission = None
-    episode = None
-    nonstop = None
-    current_slot = None
-    if program and program[-1].datetime + timedelta(minutes=program[-1].get_duration()) > now:
-        current_slot = program[-1]
-        if isinstance(current_slot, Schedule):
-            emission = current_slot.emission
-        elif isinstance(current_slot, Diffusion):
-            episode = current_slot.episode
-            emission = episode.emission
-    else:
-        for nonstop in Nonstop.objects.all():
-            if (nonstop.start < nonstop.end and (
-                    now.time() >= nonstop.start and now.time() < nonstop.end)) or \
-               (nonstop.start > nonstop.end and (
-                    now.time() >= nonstop.start or now.time() < nonstop.end)):
-                current_slot = nonstop
-                break
-        else:
-            nonstop = None
-
-    return {'emission': emission,
-            'episode': episode,
-            'nonstop': nonstop,
-            'current_slot': current_slot}
-
-
-def period_program(date_start, date_end):
-    from models import Diffusion, Schedule, Nonstop, WeekdayMixin
-
-    diffusions = Diffusion.objects.select_related().filter(
-            datetime__range=(date_start, date_end)).order_by('datetime')
-    diffusions = [x for x in diffusions if x.datetime >= date_start and
-                    x.datetime < date_end]
-
-    # the secondary sortkey puts schedules that happens everyweek after
-    # specific ones, this will be useful later on, when multiple schedules
-    # happen at the same time and we have to remove the least specific.
-    period_schedules = Schedule.objects.select_related().order_by('datetime', 'weeks')
-
-    program = []
-    current_date = date_start
-    while current_date < date_end:
-        week_day = current_date.weekday()
-        week_no = ((current_date.day-1) // 7)
-        day_schedules = [x for x in period_schedules if x.get_weekday() == week_day and x.match_week(week_no)]
-        for schedule in day_schedules:
-            schedule.datetime = datetime(
-                    current_date.year, current_date.month, current_date.day,
-                    schedule.datetime.hour, schedule.datetime.minute) + \
-                            timedelta(days=schedule.datetime.weekday()-current_date.weekday())
-        program.extend(day_schedules)
-        current_date += timedelta(days=1)
-
-    for i, schedule in enumerate(program):
-        if schedule is None:
-            continue
-
-        # look for a diffusion matching this schedule
-        d = [x for x in diffusions if x.datetime.timetuple()[:5] == schedule.datetime.timetuple()[:5]]
-        if d:
-            diffusions.remove(d[0])
-            program[i] = d[0]
-            for j, other_schedule in enumerate(program[i+1:]):
-                # remove other emissions scheduled at the same time
-                if other_schedule.datetime.timetuple()[:5] == schedule.datetime.timetuple()[:5]:
-                    program[i+1+j] = None
-                else:
-                    break
-
-    # here we are with remaining diffusions, those that were not overriding a
-    # planned schedle
-    for diffusion in diffusions:
-        program = [x for x in program if x is not None]
-        try:
-            just_before_program = [x for x in program if x.datetime < diffusion.datetime][-1]
-            new_diff_index = program.index(just_before_program)+1
-        except IndexError:
-            # nothing before
-            new_diff_index = 0
-        program.insert(new_diff_index, diffusion)
-
-        # cut (or even remove) programs that started earlier but continued over
-        # this program start time
-        i = new_diff_index
-        while i > 0:
-            previous = program[i-1]
-            previous_endtime = previous.datetime + timedelta(minutes=previous.get_duration())
-            if previous_endtime > diffusion.datetime:
-                previous.duration = (diffusion.datetime - previous.datetime).seconds / 60
-                if previous.duration <= 0:
-                    program[i-1] = None
-            i -= 1
-
-        # push back (or remove) programs that started before this program ends
-        # (this may be unnecessary as next step does that again for all
-        # programs)
-        diffusion_endtime = diffusion.datetime + timedelta(minutes=diffusion.get_duration())
-        i = new_diff_index
-        while i < len(program)-1:
-            next_prog = program[i+1]
-            if next_prog.datetime < diffusion_endtime:
-                diff = diffusion_endtime - next_prog.datetime
-                if (diff.seconds/60) > next_prog.get_duration():
-                    program[i+1] = None
-                else:
-                    next_prog.datetime = diffusion_endtime
-                    next_prog.duration = next_prog.get_duration() - (diff.seconds/60)
-            i += 1
-
-    # remove overlapping programs
-    program = [x for x in program if x is not None]
-    for i, slot in enumerate(program):
-        if slot is None:
-            continue
-
-        slot_end = slot.datetime + timedelta(minutes=slot.get_duration())
-
-        j = i+1
-        while j < len(program)-1:
-            if program[j]:
-                if slot_end > program[j].datetime:
-                    program[j] = None
-            j += 1
-
-    program = [x for x in program if x is not None]
-
-    # last step is adding nonstop zones between slots
-    nonstops = Nonstop.objects.all()
-
-    class NonstopSlot(WeekdayMixin):
-        def __init__(self, start, end):
-            self.datetime = None
-            labels = []
-            for nonstop in nonstops:
-                nonstop_day_start = start.replace(hour=nonstop.start.hour, minute=nonstop.start.minute)
-                nonstop_day_end = start.replace(hour=nonstop.end.hour, minute=nonstop.end.minute)
-                if nonstop.end < nonstop.start:
-                    if start.time() < nonstop.end:
-                        nonstop_day_start -= timedelta(days=1)
-                    else:
-                        nonstop_day_end += timedelta(days=1)
-
-                if nonstop_day_start < end and nonstop_day_end > start:
-                    if self.datetime is None:
-                        self.datetime = nonstop_day_end
-                    labels.append(nonstop.title)
-            self.label = u', '.join(labels)
-
-        def __repr__(self):
-            return repr(self.label)
-
-        def get_duration(self):
-            # fake duration
-            return 0
-
-
-    first_day_start = datetime(*date_start.replace(hour=6, minute=0).timetuple()[:5])
-    last_day_end = datetime(*date_end.replace(hour=5, minute=0).timetuple()[:5])
-
-    program.insert(0, NonstopSlot(first_day_start, program[0].datetime))
-
-    i = 0
-    while i < len(program)-1:
-        slot = program[i]
-        if not isinstance(slot, NonstopSlot):
-            slot_end = slot.datetime + timedelta(minutes=slot.get_duration())
-            next_slot = program[i+1]
-
-            if slot_end < next_slot.datetime:
-                next_day_start = next_slot.datetime.replace(hour=5, minute=0)
-                if slot_end < next_day_start and next_slot.datetime > next_day_start:
-                    program[i+1:i+1] = [NonstopSlot(slot_end, next_day_start),
-                            NonstopSlot(next_day_start, next_slot.datetime)]
-                else:
-                    program[i+1:i+1] = [NonstopSlot(slot_end, next_slot.datetime)]
-
-        i += 1
-
-    program.append(NonstopSlot(program[-1].datetime, last_day_end))
-
-    return program
-
-def day_program(date):
-    date_start = datetime(*date.timetuple()[:3])
-    date_end = date_start + timedelta(days=1)
-    return period_program(date_start, date_end)
diff --git a/panikdb/emissions/views.py b/panikdb/emissions/views.py
deleted file mode 100644 (file)
index ebb596f..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-import datetime
-import os
-
-from django.core.files.storage import DefaultStorage
-from django.http import HttpResponse, Http404
-from django.core.urlresolvers import reverse, reverse_lazy
-from django.utils import simplejson
-
-from django.views.decorators.csrf import csrf_exempt
-from django.views.generic.base import View, TemplateView, RedirectView
-from django.views.generic.edit import CreateView, UpdateView, DeleteView
-from django.views.generic.list import ListView
-from django.views.generic.detail import DetailView
-
-import haystack.views
-
-from .models import Emission, Episode, Diffusion, Category, Schedule, SoundFile
-from .forms import EmissionForm, EpisodeForm, EpisodeNewForm, ScheduleForm, \
-                   DiffusionForm, SoundFileForm
-
-
-__all__ = ['EmissionListView', 'EmissionDetailView', 'EmissionCreateView',
-           'EmissionUpdateView', 'EmissionDeleteView',
-           'EpisodeCreateView', 'EpisodeDetailView', 'EpisodeUpdateView',
-           'EpisodeDeleteView', 'EmissionAddScheduleView',
-           'ScheduleDeleteView', 'CategoryListView', 'DaysView',
-           'UploadView', 'EpisodeAddSoundFileView',
-           'EpisodeAddDiffusionView', 'DiffusionDeleteView']
-
-
-class EmissionListView(ListView):
-    model = Emission
-
-    def get_queryset(self):
-        return Emission.objects.order_by('title')
-
-
-class CategoryListView(ListView):
-    model = Category
-
-    def get_queryset(self):
-        return Category.objects.order_by('title')
-
-
-class EmissionDetailView(DetailView):
-    model = Emission
-
-    def get_context_data(self, **kwargs):
-        context = super(EmissionDetailView, self).get_context_data(**kwargs)
-        context['add_schedule_form'] = ScheduleForm(initial={'emission': self.object})
-        context['schedules'] = Schedule.objects.filter(emission=self.object).order_by('datetime')
-
-        # get all episodes, with an additional attribute to get the date of
-        # their first diffusion
-        context['episodes'] = \
-                Episode.objects.select_related().filter(emission=self.object
-                    ).extra(select={
-                        'first_diffusion': 'emissions_diffusion.datetime',
-                        },
-                        select_params=(False, True),
-                        where=['''datetime = (SELECT MIN(datetime)
-                                                FROM emissions_diffusion
-                                               WHERE episode_id = emissions_episode.id)'''],
-                        tables=['emissions_diffusion'],
-                    ).order_by('-first_diffusion')
-
-        # get all related soundfiles in a single query
-        soundfiles = {}
-        for soundfile in SoundFile.objects.filter(podcastable=True,
-                fragment=False, episode__emission=self.object):
-            soundfiles[soundfile.episode_id] = soundfile
-
-        # replace dynamic property by a static attribute, to avoid database
-        # lookups
-        for episode in context['episodes']:
-            episode.main_sound = soundfiles.get(episode.id)
-
-        return context
-
-
-class EmissionCreateView(CreateView):
-    form_class = EmissionForm
-    model = Emission
-
-    success_url = reverse_lazy('emission-list')
-
-
-class EmissionUpdateView(UpdateView):
-    form_class = EmissionForm
-    model = Emission
-
-
-class EmissionDeleteView(DeleteView):
-    model = Emission
-
-
-class EpisodeCreateView(CreateView):
-    model = Episode
-    form_class = EpisodeNewForm
-
-    def get_initial(self):
-        initial = super(EpisodeCreateView, self).get_initial()
-        initial['emission'] = Emission.objects.get(slug=self.kwargs.get('emission_slug'))
-        initial['duration'] = initial['emission'].duration
-        return initial
-
-    def get_context_data(self, **kwargs):
-        context = super(EpisodeCreateView, self).get_context_data(**kwargs)
-        context['emission'] = Emission.objects.get(slug=self.kwargs.get('emission_slug'))
-        return context
-
-    def get_success_url(self):
-        return self.object.get_absolute_url()
-
-
-class EpisodeDetailView(DetailView):
-    model = Episode
-
-    def get_context_data(self, **kwargs):
-        context = super(EpisodeDetailView, self).get_context_data(**kwargs)
-        context['diffusions'] = Diffusion.objects.filter(episode=self.object.id)
-        context['soundfiles'] = SoundFile.objects.filter(episode=self.object.id)
-        context['add_soundfile_form'] = SoundFileForm(initial={'episode': self.object})
-        context['add_diffusion_form'] = DiffusionForm(initial={'episode': self.object})
-        context['emission'] = Emission.objects.get(slug=self.kwargs.get('emission_slug'))
-        # get all episodes, with an additional attribute to get the date of
-        # their first diffusion
-        context['episodes'] = \
-                Episode.objects.filter(emission=context['emission']
-                    ).extra(select={
-                        'first_diffusion': 'emissions_diffusion.datetime',
-                        },
-                        select_params=(False, True),
-                        where=['''datetime = (SELECT MIN(datetime)
-                                                FROM emissions_diffusion
-                                               WHERE episode_id = emissions_episode.id)'''],
-                        tables=['emissions_diffusion'],
-                    ).order_by('-first_diffusion')
-
-        # get all related soundfiles in a single query
-        soundfiles = {}
-        for soundfile in SoundFile.objects.filter(podcastable=True,
-                fragment=False, episode__emission=self.object):
-            soundfiles[soundfile.episode_id] = soundfile
-
-        # replace dynamic property by a static attribute, to avoid database
-        # lookups
-        for episode in context['episodes']:
-            episode.main_sound = soundfiles.get(episode.id)
-        return context
-
-
-class EpisodeUpdateView(UpdateView):
-    form_class = EpisodeForm
-    model = Episode
-
-
-class EpisodeDeleteView(DeleteView):
-    model = Episode
-
-
-class EmissionAddScheduleView(CreateView):
-    form_class = ScheduleForm
-    model = Schedule
-
-    def get_success_url(self):
-        return self.object.emission.get_absolute_url()
-
-
-class ScheduleDeleteView(RedirectView):
-    def get_redirect_url(self, emission_slug, pk):
-        Schedule.objects.filter(id=pk).delete()
-        return reverse('emission-view', kwargs={'slug': str(emission_slug)})
-
-
-class DaysView(TemplateView):
-    template_name = 'emissions/days.html'
-
-    def get_context_data(self, **kwargs):
-        context = super(DaysView, self).get_context_data(**kwargs)
-        schedules = Schedule.objects.all().order_by('datetime')
-        days = []
-        for day in range(7):
-            days.append({'schedules': [x for x in schedules if x.is_on_weekday(day+1)],
-                         'datetime': datetime.datetime(2007, 1, day+1)})
-        context['days'] = days
-        return context
-
-class JSONResponse(HttpResponse):
-    """JSON response class."""
-    def __init__(self, obj='', json_opts={}, mimetype='application/json', *args, **kwargs):
-        content = simplejson.dumps(obj, **json_opts)
-        super(JSONResponse,self).__init__(content, mimetype, *args, **kwargs)
-
-
-class UploadView(View):
-
-    def response_mimetype(self, request):
-        if 'application/json' in request.META['HTTP_ACCEPT']:
-            return 'application/json'
-        else:
-            return 'text/plain'
-
-    @csrf_exempt
-    def post(self, request, transaction_id):
-        storage = DefaultStorage()
-        max_filename_length = 256
-        url = reverse('upload', kwargs={'transaction_id': transaction_id})
-        if request.FILES is None:
-            response = JSONResponse({}, {}, self.response_mimetype(request))
-            response['Content-Disposition'] = 'inline; filename=files.json'
-            return response
-        data = []
-        for uploaded_file in request.FILES.values():
-            path = os.path.join('upload', str(transaction_id), uploaded_file.name)
-            filename = storage.save(path, uploaded_file)
-            url = '%s%s' % (url, os.path.basename(filename))
-            data.append({'name': uploaded_file.name, 'size': uploaded_file.size, 'url': url})
-        response = JSONResponse(data, {}, self.response_mimetype(request))
-        response['Content-Disposition'] = 'inline; filename=files.json'
-        return response
-
-
-class EpisodeAddSoundFileView(CreateView):
-    form_class = SoundFileForm
-    model = SoundFile
-
-    def get_success_url(self):
-        return self.object.episode.get_absolute_url()
-
-
-class EpisodeAddDiffusionView(CreateView):
-    form_class = DiffusionForm
-    model = Diffusion
-
-    def get_success_url(self):
-        return self.object.episode.get_absolute_url()
-
-
-class DiffusionDeleteView(RedirectView):
-    def get_redirect_url(self, emission_slug, slug, pk):
-        Diffusion.objects.filter(id=pk).delete()
-        return reverse('episode-view', kwargs={'emission_slug': str(emission_slug),
-                                               'slug': str(slug)})
-
-
-class FacetedSearchView(haystack.views.FacetedSearchView):
-    def extra_context(self):
-        context = super(FacetedSearchView, self).extra_context()
-        context['selected_categories'] = [
-                x.split(':', 1)[1] for x in self.request.GET.getlist('selected_facets')
-                if x.startswith('categories_exact')]
-        context['selected_tags'] = [
-                x.split(':', 1)[1] for x in self.request.GET.getlist('selected_facets')
-                if x.startswith('tags_exact')]
-        return context
index 6193fe38ea962b04cf0b12fe2fd99be8725e949d..bda0ca80739afc8778d67ab7194fa12364d12933 100644 (file)
@@ -130,7 +130,7 @@ INSTALLED_APPS = (
     'jquery',
     'datetimewidget',
     'django_bootstrap_staticfiles',
-    'panikdb.emissions',
+    'emissions',
     'panikdb.aa',
 )
 
index 219c2104f8c49c54ffefe48def77fd0a050695eb..60bedce62c2ad6ae22dfb50ce55a33af5b295b8f 100644 (file)
@@ -12,7 +12,7 @@ from haystack.forms import FacetedSearchForm
 from haystack.query import SearchQuerySet
 
 from emissions.views import FacetedSearchView
-from .emissions.urls import urlpatterns as emissions_urlpatterns
+from emissions.urls import urlpatterns as emissions_urlpatterns
 
 from urls_utils import decorated_includes
 
index 23f050462682d160d6b5fd5f0da070b84f5b8e15..4883cff51d81c149c685a221c074dde1c81cf89d 100644 (file)
@@ -7,3 +7,4 @@ django-registration
 django-jquery
 django-datetime-widget
 django-bootstrap-staticfiles
+git+http://git.domainepublic.net/git/django-panik-emissions.git