--- /dev/null
+from optparse import make_option
+from django.conf import settings
+from django.core.management.base import BaseCommand, CommandError
+from django.contrib.auth.models import User
+
+
+class Command(BaseCommand):
+ help = """Create a default admin user if it doesn't exist.
+ you SHOULD change the password and the email afterwards!"""
+
+ username = 'admin'
+ password = 'admin'
+ email = 'root@example.com'
+
+ def handle(self, *args, **options):
+ admin = User.objects.filter(username=self.username)
+ if not admin:
+ user = User(username=self.username)
+ user.set_password(self.password)
+ user.email = self.email
+ user.is_superuser = True
+ user.is_staff = True
+ user.save()
+ print('User ' + self.username + ' created')
--- /dev/null
+from datetime import datetime, timedelta
+from optparse import make_option
+
+from django.conf import settings
+from django.core.management.base import BaseCommand, CommandError
+from django.contrib.auth.models import User
+from django.core.mail import EmailMessage
+
+import mezzanine_agenda.models as ma_models
+from mezzanine.generic.models import AssignedKeyword, Keyword
+
+import eve.models as eve_models
+
+
+class Command(BaseCommand):
+ """Synchronize events from E-vement to mezzanine_agenda"""
+
+
+ option_list = BaseCommand.option_list + (
+ make_option('-m', '--meta_event',
+ dest='meta_event',
+ help='define eve meta_event'),
+ )
+
+ default_user = User.objects.get(username='admin')
+
+ def cleanup(self):
+ # for event in ma_models.Event.objects.all():
+ # event.delete()
+ # for location in ma_models.EventLocation.objects.all():
+ # location.delete()
+ for event_price in ma_models.EventPrice.objects.all():
+ event_price.delete()
+
+ def handle(self, *args, **kwargs):
+ # self.cleanup()
+ meta_event_name = kwargs.get('meta_event')
+ meta_trans_all = eve_models.MetaEventTranslation.objects.all()
+ for meta_trans in meta_trans_all:
+ if meta_trans.name == meta_event_name:
+ break
+ eve_events = eve_models.Event.objects.filter(meta_event=meta_trans.id)
+ for eve_event in eve_events:
+ event_trans = eve_models.EventTranslation.objects.filter(id=eve_event, lang='fr')[0]
+ manifestations = eve_event.manifestations.all().order_by('happens_at')
+ first = True
+ for manifestation in manifestations:
+ events = ma_models.Event.objects.filter(external_id=manifestation.id)
+ if not events:
+ event = ma_models.Event(external_id=manifestation.id)
+ else:
+ event = events[0]
+ event.start = manifestation.happens_at
+ event.end = manifestation.happens_at + timedelta(seconds=manifestation.duration)
+ event.title = event_trans.name
+ event.user = self.default_user
+
+ locations = ma_models.EventLocation.objects.filter(title=manifestation.location.name)
+ if locations:
+ location = locations[0]
+ else:
+ location = ma_models.EventLocation(title=manifestation.location.name)
+ address = '\n'.join([manifestation.location.address, manifestation.location.postalcode + ' ' + manifestation.location.city])
+ location.address = address
+ location.external_id = manifestation.id
+ location.clean()
+ location.save()
+ event.location = location
+ event.save()
+ keyword, _ = Keyword.objects.get_or_create(title=eve_event.event_category.name)
+ event.keywords.add(AssignedKeyword(keyword=keyword), bulk=False)
+
+ eve_prices = eve_models.PriceManifestation.objects.filter(manifestation=manifestation)
+ for price in eve_prices:
+ event_price, c = ma_models.EventPrice.objects.get_or_create(value=float(price.value))
+ if event:
+ if not event_price in event.prices.all():
+ event.prices.add(event_price)
+
+ if not first:
+ event.parent = parent
+ else:
+ parent = event
+ first = False
+
+ event.save()
--- /dev/null
+import os, time
+
+from optparse import make_option
+from django.conf import settings
+from django.core.management.base import BaseCommand, CommandError
+from django.db import connections
+
+
+class Command(BaseCommand):
+ help = "wait for default DB connection"
+
+ db_name = 'default'
+ N = 20
+
+ def handle(self, *args, **options):
+ i = 0
+ connected = False
+ db_conn = connections[self.db_name]
+ while not connected:
+ try:
+ c = db_conn.cursor()
+ connected = True
+ except:
+ print('error connecting to DB...')
+ if i > self.N:
+ print('...exiting')
+ raise
+ print('...retrying')
+ i += 1
+ time.sleep(1)
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-07-07 14:14
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('organization core', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='basicpage',
+ name='photo',
+ ),
+ migrations.RemoveField(
+ model_name='basicpage',
+ name='photo_alignment',
+ ),
+ migrations.RemoveField(
+ model_name='basicpage',
+ name='photo_card',
+ ),
+ migrations.RemoveField(
+ model_name='basicpage',
+ name='photo_card_credits',
+ ),
+ migrations.RemoveField(
+ model_name='basicpage',
+ name='photo_credits',
+ ),
+ migrations.RemoveField(
+ model_name='basicpage',
+ name='photo_description',
+ ),
+ migrations.RemoveField(
+ model_name='basicpage',
+ name='photo_slider',
+ ),
+ migrations.RemoveField(
+ model_name='basicpage',
+ name='photo_slider_credits',
+ ),
+ ]
from django.db import models
+from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse, reverse_lazy
+
from mezzanine.pages.models import Page, RichText
from mezzanine.core.fields import RichTextField, OrderField, FileField
-from django.conf import settings
-
-from organization.media.models import Photos
-
-ALIGNMENT_CHOICES = (('left', _('left')), ('right', _('right')))
-MEDIA_BASE_URL = getattr(settings, 'MEDIA_BASE_URL', 'http://medias.ircam.fr/embed/media/')
-
class Named(models.Model):
return slugify(self.__unicode__())
+class Titled(models.Model):
+ """Base object with title and description"""
+
+ title = models.CharField(_('title'), max_length=512)
+ description = models.TextField(_('description'), blank=True)
+
+ class Meta:
+ abstract = True
+
+ def __unicode__(self):
+ return self.title
+
+
class SubTitle(models.Model):
sub_title = models.TextField(_('sub title'), blank=True, max_length=1024)
abstract = True
-class BasicPage(Page, RichText, SubTitle, Photos):
+class BasicPage(Page, RichText, SubTitle):
class Meta:
verbose_name = 'basic page'
--- /dev/null
+# -*- coding: utf-8 -*-
+from mezzanine.pages.models import Page
+from mezzanine.blog.models import BlogPost
+from mezzanine.template import Library
+from mezzanine_agenda.models import Event
+from mezzanine.conf import settings
+from random import shuffle
+
+from organization.festival.models import *
+from organization.magazine.models import *
+
+register = Library()
+
+
+@register.filter
+def subtract(value, arg):
+ return value - arg
+
+@register.as_tag
+def featured_edito(*args):
+ qs = Page.objects.filter(slug="edito")
+ if qs:
+ return qs[0].get_content_model()
+ else:
+ return None
+
+@register.as_tag
+def featured_events(*args):
+ featured = Featured.objects.all()
+ if featured:
+ return featured[0].events.order_by('start')
+ return None
+
+@register.as_tag
+def featured(*args):
+ featured_list = []
+ featured = Featured.objects.filter(id=settings.HOME_FEATURED_ID)
+ if featured:
+ featured = featured[0]
+ for post in featured.blogposts.all():
+ featured_list.append(post)
+ for video in featured.videos.all():
+ featured_list.append(video)
+ for artist in featured.artists.all():
+ featured_list.append(artist)
+ for playlist in featured.playlists.all():
+ featured_list.append(playlist)
+ shuffle(featured_list)
+ return featured_list
+
+@register.as_tag
+def featured_breaking_news_content(*args):
+ featured = Featured.objects.filter(id=settings.BREAKING_NEWS_FEATURED_ID)
+ if featured:
+ featured = featured[0]
+ news = featured.pages.all()
+ if news:
+ return news[0].richtextpage.content
+ else:
+ return ''
+ return ''
+
+@register.filter
+def get_class(obj):
+ return obj.__class__.__name__
+
+@register.filter
+def unique_posts(events):
+ post_list = []
+ for event in events:
+ for post in event.blog_posts.all():
+ print(post)
+ if not post in post_list:
+ post_list.append(post)
+ return post_list
+
+@register.filter
+def no_parents(events):
+ return events.filter(parent=None)
from django.shortcuts import render
-# Create your views here.
+
+class SlugMixin(object):
+
+ def get_object(self):
+ objects = self.model.objects.all()
+ return get_object_or_404(objects, slug=self.kwargs['slug'])
--- /dev/null
+from django.contrib import admin
+
+from organization.featured.models import *
+
+
+class FeaturedAdmin(admin.ModelAdmin):
+
+ model = Featured
+ list_display = ('__unicode__',)
+ filter_horizontal = ['events', 'videos', 'articles', 'pages', 'playlists']
+
+
+admin.site.register(Featured, FeaturedAdmin)
--- /dev/null
+from __future__ import unicode_literals
+
+from django.apps import AppConfig
+
+
+class FeaturedConfig(AppConfig):
+ name = 'featured'
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-07-07 14:14
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ('organization magazine', '0002_article'),
+ ('mezzanine_agenda', '0014_event_brochure'),
+ ('organization core', '0002_auto_20160707_1614'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Featured',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=512, verbose_name='name')),
+ ('description', models.TextField(blank=True, verbose_name='description')),
+ ('articles', models.ManyToManyField(blank=True, related_name='featured', to='organization magazine.Article', verbose_name='articles')),
+ ('events', models.ManyToManyField(blank=True, related_name='featured', to='mezzanine_agenda.Event', verbose_name='events')),
+ ('pages', models.ManyToManyField(blank=True, related_name='featured', to='organization core.BasicPage', verbose_name='pages')),
+ ],
+ options={
+ 'abstract': False,
+ },
+ ),
+ ]
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-07-07 14:14
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ('featured', '0001_initial'),
+ ('organization media', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='featured',
+ name='playlists',
+ field=models.ManyToManyField(blank=True, related_name='featured', to='organization media.Playlist', verbose_name='playlists'),
+ ),
+ migrations.AddField(
+ model_name='featured',
+ name='videos',
+ field=models.ManyToManyField(blank=True, related_name='featured', to='organization media.Video', verbose_name='videos'),
+ ),
+ ]
--- /dev/null
+from __future__ import unicode_literals
+
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+from django.core.urlresolvers import reverse, reverse_lazy
+from django.conf import settings
+
+from organization.core.models import *
+from organization.magazine.models import *
+from organization.media.models import *
+
+from mezzanine_agenda.models import Event
+
+
+class Featured(Named):
+ """(Featured description)"""
+
+ pages = models.ManyToManyField(BasicPage, verbose_name=_('pages'), related_name='featured', blank=True)
+ articles = models.ManyToManyField(Article, verbose_name=_('articles'), related_name='featured', blank=True)
+ events = models.ManyToManyField(Event, verbose_name=_('events'), related_name='featured', blank=True)
+ videos = models.ManyToManyField(Video, verbose_name=_('videos'), related_name='featured', blank=True)
+ playlists = models.ManyToManyField(Playlist, verbose_name=_('playlists'), related_name='featured', blank=True)
+
+ def __unicode__(self):
+ return self.name
--- /dev/null
+# -*- coding: utf-8 -*-
+from mezzanine.pages.models import Page
+from mezzanine.blog.models import BlogPost
+from mezzanine.template import Library
+from mezzanine_agenda.models import Event
+from mezzanine.conf import settings
+from random import shuffle
+
+from organization.festival.models import *
+from organization.featured.models import *
+
+register = Library()
+
+
+@register.filter
+def subtract(value, arg):
+ return value - arg
+
+@register.as_tag
+def featured_edito(*args):
+ qs = Page.objects.filter(slug="edito")
+ if qs:
+ return qs[0].get_content_model()
+ else:
+ return None
+
+@register.as_tag
+def featured_events(*args):
+ featured = Featured.objects.all()
+ if featured:
+ return featured[0].events.order_by('start')
+ return None
+
+@register.as_tag
+def featured(*args):
+ featured_list = []
+ featured = Featured.objects.filter(id=settings.HOME_FEATURED_ID)
+ if featured:
+ featured = featured[0]
+ for post in featured.blogposts.all():
+ featured_list.append(post)
+ for video in featured.videos.all():
+ featured_list.append(video)
+ for artist in featured.artists.all():
+ featured_list.append(artist)
+ for playlist in featured.playlists.all():
+ featured_list.append(playlist)
+ shuffle(featured_list)
+ return featured_list
+
+@register.as_tag
+def featured_breaking_news_content(*args):
+ featured = Featured.objects.filter(id=settings.BREAKING_NEWS_FEATURED_ID)
+ if featured:
+ featured = featured[0]
+ news = featured.pages.all()
+ if news:
+ return news[0].richtextpage.content
+ else:
+ return ''
+ return ''
+
+@register.filter
+def get_class(obj):
+ return obj.__class__.__name__
+
+@register.filter
+def unique_posts(events):
+ post_list = []
+ for event in events:
+ for post in event.blog_posts.all():
+ print(post)
+ if not post in post_list:
+ post_list.append(post)
+ return post_list
+
+@register.filter
+def no_parents(events):
+ return events.filter(parent=None)
--- /dev/null
+from django.test import TestCase
+
+# Create your tests here.
--- /dev/null
+from django.shortcuts import render
+
+# Create your views here.
model = Artist
-class VideoAdmin(admin.ModelAdmin):
-
- model = Video
-
-
-class VideoAdminDisplayable(DisplayableAdmin):
-
- fieldsets = deepcopy(VideoAdmin.fieldsets)
- filter_horizontal = ['artists']
-
-
-class AudioAdmin(admin.ModelAdmin):
-
- model = Audio
-
-
-class AudioAdminDisplayable(DisplayableAdmin):
-
- fieldsets = deepcopy(AudioAdmin.fieldsets)
- filter_horizontal = ['artists']
-
-
class ArtistAdminDisplayable(DisplayableAdmin):
fieldsets = deepcopy(ArtistAdmin.fieldsets)
-class PlaylistAdmin(admin.ModelAdmin):
-
- model = Playlist
- list_display = ('__unicode__',)
- filter_horizontal = ['audios']
-
-
-class FeaturedAdmin(admin.ModelAdmin):
-
- model = Featured
- list_display = ('__unicode__',)
- filter_horizontal = ['artists', 'events', 'videos', 'pages', 'blogposts', 'pages', 'playlists']
-
-
admin.site.register(Artist, ArtistAdminDisplayable)
-admin.site.register(Video, VideoAdminDisplayable)
-admin.site.register(Audio, AudioAdminDisplayable)
-admin.site.register(Playlist, PlaylistAdmin)
-admin.site.register(Featured, FeaturedAdmin)
-admin.site.register(VideoCategory)
+++ /dev/null
-from optparse import make_option
-from django.conf import settings
-from django.core.management.base import BaseCommand, CommandError
-from django.contrib.auth.models import User
-
-
-class Command(BaseCommand):
- help = """Create a default admin user if it doesn't exist.
- you SHOULD change the password and the email afterwards!"""
-
- username = 'admin'
- password = 'admin'
- email = 'root@example.com'
-
- def handle(self, *args, **options):
- admin = User.objects.filter(username=self.username)
- if not admin:
- user = User(username=self.username)
- user.set_password(self.password)
- user.email = self.email
- user.is_superuser = True
- user.is_staff = True
- user.save()
- print('User ' + self.username + ' created')
+++ /dev/null
-from datetime import datetime, timedelta
-from optparse import make_option
-
-from django.conf import settings
-from django.core.management.base import BaseCommand, CommandError
-from django.contrib.auth.models import User
-from django.core.mail import EmailMessage
-
-import mezzanine_agenda.models as ma_models
-from mezzanine.generic.models import AssignedKeyword, Keyword
-
-import eve.models as eve_models
-
-
-class Command(BaseCommand):
- """Synchronize events from E-vement to mezzanine_agenda"""
-
-
- option_list = BaseCommand.option_list + (
- make_option('-m', '--meta_event',
- dest='meta_event',
- help='define eve meta_event'),
- )
-
- default_user = User.objects.get(username='admin')
-
- def cleanup(self):
- # for event in ma_models.Event.objects.all():
- # event.delete()
- # for location in ma_models.EventLocation.objects.all():
- # location.delete()
- for event_price in ma_models.EventPrice.objects.all():
- event_price.delete()
-
- def handle(self, *args, **kwargs):
- # self.cleanup()
- meta_event_name = kwargs.get('meta_event')
- meta_trans_all = eve_models.MetaEventTranslation.objects.all()
- for meta_trans in meta_trans_all:
- if meta_trans.name == meta_event_name:
- break
- eve_events = eve_models.Event.objects.filter(meta_event=meta_trans.id)
- for eve_event in eve_events:
- event_trans = eve_models.EventTranslation.objects.filter(id=eve_event, lang='fr')[0]
- manifestations = eve_event.manifestations.all().order_by('happens_at')
- first = True
- for manifestation in manifestations:
- events = ma_models.Event.objects.filter(external_id=manifestation.id)
- if not events:
- event = ma_models.Event(external_id=manifestation.id)
- else:
- event = events[0]
- event.start = manifestation.happens_at
- event.end = manifestation.happens_at + timedelta(seconds=manifestation.duration)
- event.title = event_trans.name
- event.user = self.default_user
-
- locations = ma_models.EventLocation.objects.filter(title=manifestation.location.name)
- if locations:
- location = locations[0]
- else:
- location = ma_models.EventLocation(title=manifestation.location.name)
- address = '\n'.join([manifestation.location.address, manifestation.location.postalcode + ' ' + manifestation.location.city])
- location.address = address
- location.external_id = manifestation.id
- location.clean()
- location.save()
- event.location = location
- event.save()
- keyword, _ = Keyword.objects.get_or_create(title=eve_event.event_category.name)
- event.keywords.add(AssignedKeyword(keyword=keyword), bulk=False)
-
- eve_prices = eve_models.PriceManifestation.objects.filter(manifestation=manifestation)
- for price in eve_prices:
- event_price, c = ma_models.EventPrice.objects.get_or_create(value=float(price.value))
- if event:
- if not event_price in event.prices.all():
- event.prices.add(event_price)
-
- if not first:
- event.parent = parent
- else:
- parent = event
- first = False
-
- event.save()
+++ /dev/null
-import os, time
-
-from optparse import make_option
-from django.conf import settings
-from django.core.management.base import BaseCommand, CommandError
-from django.db import connections
-
-
-class Command(BaseCommand):
- help = "wait for default DB connection"
-
- db_name = 'default'
- N = 20
-
- def handle(self, *args, **options):
- i = 0
- connected = False
- db_conn = connections[self.db_name]
- while not connected:
- try:
- c = db_conn.cursor()
- connected = True
- except:
- print('error connecting to DB...')
- if i > self.N:
- print('...exiting')
- raise
- print('...retrying')
- i += 1
- time.sleep(1)
# -*- coding: utf-8 -*-
-# Generated by Django 1.9.7 on 2016-07-07 09:13
+# Generated by Django 1.9.7 on 2016-07-07 14:14
from __future__ import unicode_literals
from django.db import migrations, models
dependencies = [
('sites', '0002_alter_domain_unique'),
- ('mezzanine_agenda', '0014_event_brochure'),
- ('blog', '0003_auto_20151223_1313'),
- ('pages', '0004_auto_20151223_1313'),
]
operations = [
('content', mezzanine.core.fields.RichTextField(verbose_name='Content')),
('content_fr', mezzanine.core.fields.RichTextField(null=True, verbose_name='Content')),
('content_en', mezzanine.core.fields.RichTextField(null=True, verbose_name='Content')),
+ ('photo', mezzanine.core.fields.FileField(blank=True, max_length=1024, verbose_name='photo')),
+ ('photo_credits', models.CharField(blank=True, max_length=255, null=True, verbose_name='photo credits')),
+ ('photo_alignment', models.CharField(blank=True, choices=[('left', 'left'), ('center', 'center'), ('right', 'right')], default='left', max_length=32, verbose_name='photo alignment')),
+ ('photo_description', models.TextField(blank=True, verbose_name='photo description')),
+ ('photo_card', mezzanine.core.fields.FileField(blank=True, max_length=1024, verbose_name='card photo')),
+ ('photo_card_credits', models.CharField(blank=True, max_length=255, null=True, verbose_name='photo card credits')),
+ ('photo_slider', mezzanine.core.fields.FileField(blank=True, max_length=1024, verbose_name='slider photo')),
+ ('photo_slider_credits', models.CharField(blank=True, max_length=255, null=True, verbose_name='photo slider credits')),
('first_name', models.CharField(blank=True, max_length=255, null=True, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=255, null=True, verbose_name='last name')),
('bio', mezzanine.core.fields.RichTextField(blank=True, verbose_name='biography')),
('bio_fr', mezzanine.core.fields.RichTextField(blank=True, null=True, verbose_name='biography')),
('bio_en', mezzanine.core.fields.RichTextField(blank=True, null=True, verbose_name='biography')),
- ('photo', mezzanine.core.fields.FileField(blank=True, max_length=1024, verbose_name='photo')),
- ('photo_credits', models.CharField(blank=True, max_length=255, null=True, verbose_name='photo credits')),
- ('photo_alignment', models.CharField(blank=True, choices=[('left', 'left'), ('right', 'right')], default='left', max_length=32, verbose_name='photo alignment')),
- ('photo_description', models.TextField(blank=True, verbose_name='photo description')),
- ('photo_featured', mezzanine.core.fields.FileField(blank=True, max_length=1024, verbose_name='photo featured')),
- ('photo_featured_credits', models.CharField(blank=True, max_length=255, null=True, verbose_name='photo featured credits')),
- ('events', models.ManyToManyField(blank=True, related_name='artists', to='mezzanine_agenda.Event', verbose_name='events')),
('site', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')),
],
options={
- 'verbose_name': 'artist',
'ordering': ['last_name'],
+ 'verbose_name': 'artist',
},
- bases=(models.Model, mezzanine.utils.models.AdminThumbMixin),
- ),
- migrations.CreateModel(
- name='Audio',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('keywords_string', models.CharField(blank=True, editable=False, max_length=500)),
- ('title', models.CharField(max_length=500, verbose_name='Title')),
- ('title_fr', models.CharField(max_length=500, null=True, verbose_name='Title')),
- ('title_en', models.CharField(max_length=500, null=True, verbose_name='Title')),
- ('slug', models.CharField(blank=True, help_text='Leave blank to have the URL auto-generated from the title.', max_length=2000, null=True, verbose_name='URL')),
- ('_meta_title', models.CharField(blank=True, help_text='Optional title to be used in the HTML title tag. If left blank, the main title field will be used.', max_length=500, null=True, verbose_name='Title')),
- ('description', models.TextField(blank=True, verbose_name='Description')),
- ('description_fr', models.TextField(blank=True, null=True, verbose_name='Description')),
- ('description_en', models.TextField(blank=True, null=True, verbose_name='Description')),
- ('gen_description', models.BooleanField(default=True, help_text='If checked, the description will be automatically generated from content. Uncheck if you want to manually set a custom description.', verbose_name='Generate description')),
- ('created', models.DateTimeField(editable=False, null=True)),
- ('updated', models.DateTimeField(editable=False, null=True)),
- ('status', models.IntegerField(choices=[(1, 'Draft'), (2, 'Published')], default=2, help_text='With Draft chosen, will only be shown for admin users on the site.', verbose_name='Status')),
- ('publish_date', models.DateTimeField(blank=True, db_index=True, help_text="With Published chosen, won't be shown until this time", null=True, verbose_name='Published from')),
- ('expiry_date', models.DateTimeField(blank=True, help_text="With Published chosen, won't be shown after this time", null=True, verbose_name='Expires on')),
- ('short_url', models.URLField(blank=True, null=True)),
- ('in_sitemap', models.BooleanField(default=True, verbose_name='Show in sitemap')),
- ('content', mezzanine.core.fields.RichTextField(verbose_name='Content')),
- ('content_fr', mezzanine.core.fields.RichTextField(null=True, verbose_name='Content')),
- ('content_en', mezzanine.core.fields.RichTextField(null=True, verbose_name='Content')),
- ('media_id', models.CharField(max_length=128, verbose_name='media id')),
- ('open_source_url', models.URLField(blank=True, max_length=1024, verbose_name='open source URL')),
- ('closed_source_url', models.URLField(blank=True, max_length=1024, verbose_name='closed source URL')),
- ('poster_url', models.URLField(blank=True, max_length=1024, verbose_name='poster')),
- ('artists', models.ManyToManyField(blank=True, related_name='audios', to='organization festival app.Artist', verbose_name='artists')),
- ('event', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='audios', to='mezzanine_agenda.Event', verbose_name='event')),
- ('site', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')),
- ],
- options={
- 'verbose_name': 'audio',
- },
- ),
- migrations.CreateModel(
- name='Featured',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('name', models.CharField(max_length=512, verbose_name='name')),
- ('description', models.TextField(blank=True, verbose_name='description')),
- ('artists', models.ManyToManyField(blank=True, related_name='featured', to='organization festival app.Artist', verbose_name='artists')),
- ('blogposts', models.ManyToManyField(blank=True, related_name='featured', to='blog.BlogPost', verbose_name='blog posts')),
- ('events', models.ManyToManyField(blank=True, related_name='featured', to='mezzanine_agenda.Event', verbose_name='events')),
- ('pages', models.ManyToManyField(blank=True, related_name='featured', to='pages.Page', verbose_name='pages')),
- ],
- options={
- 'abstract': False,
- },
- ),
- migrations.CreateModel(
- name='Playlist',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('title', models.CharField(max_length=512, verbose_name='title')),
- ('description', models.TextField(blank=True, verbose_name='description')),
- ('audios', models.ManyToManyField(blank=True, related_name='playlists', to='organization festival app.Audio', verbose_name='audios')),
- ('event', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='playlists', to='mezzanine_agenda.Event', verbose_name='event')),
- ],
- options={
- 'abstract': False,
- },
- ),
- migrations.CreateModel(
- name='Video',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('keywords_string', models.CharField(blank=True, editable=False, max_length=500)),
- ('title', models.CharField(max_length=500, verbose_name='Title')),
- ('title_fr', models.CharField(max_length=500, null=True, verbose_name='Title')),
- ('title_en', models.CharField(max_length=500, null=True, verbose_name='Title')),
- ('slug', models.CharField(blank=True, help_text='Leave blank to have the URL auto-generated from the title.', max_length=2000, null=True, verbose_name='URL')),
- ('_meta_title', models.CharField(blank=True, help_text='Optional title to be used in the HTML title tag. If left blank, the main title field will be used.', max_length=500, null=True, verbose_name='Title')),
- ('description', models.TextField(blank=True, verbose_name='Description')),
- ('description_fr', models.TextField(blank=True, null=True, verbose_name='Description')),
- ('description_en', models.TextField(blank=True, null=True, verbose_name='Description')),
- ('gen_description', models.BooleanField(default=True, help_text='If checked, the description will be automatically generated from content. Uncheck if you want to manually set a custom description.', verbose_name='Generate description')),
- ('created', models.DateTimeField(editable=False, null=True)),
- ('updated', models.DateTimeField(editable=False, null=True)),
- ('status', models.IntegerField(choices=[(1, 'Draft'), (2, 'Published')], default=2, help_text='With Draft chosen, will only be shown for admin users on the site.', verbose_name='Status')),
- ('publish_date', models.DateTimeField(blank=True, db_index=True, help_text="With Published chosen, won't be shown until this time", null=True, verbose_name='Published from')),
- ('expiry_date', models.DateTimeField(blank=True, help_text="With Published chosen, won't be shown after this time", null=True, verbose_name='Expires on')),
- ('short_url', models.URLField(blank=True, null=True)),
- ('in_sitemap', models.BooleanField(default=True, verbose_name='Show in sitemap')),
- ('content', mezzanine.core.fields.RichTextField(verbose_name='Content')),
- ('content_fr', mezzanine.core.fields.RichTextField(null=True, verbose_name='Content')),
- ('content_en', mezzanine.core.fields.RichTextField(null=True, verbose_name='Content')),
- ('media_id', models.CharField(max_length=128, verbose_name='media id')),
- ('open_source_url', models.URLField(blank=True, max_length=1024, verbose_name='open source URL')),
- ('closed_source_url', models.URLField(blank=True, max_length=1024, verbose_name='closed source URL')),
- ('poster_url', models.URLField(blank=True, max_length=1024, verbose_name='poster')),
- ('artists', models.ManyToManyField(blank=True, related_name='videos', to='organization festival app.Artist', verbose_name='artists')),
- ],
- options={
- 'verbose_name': 'video',
- },
- ),
- migrations.CreateModel(
- name='VideoCategory',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('title', models.CharField(max_length=500, verbose_name='Title')),
- ('slug', models.CharField(blank=True, help_text='Leave blank to have the URL auto-generated from the title.', max_length=2000, null=True, verbose_name='URL')),
- ('site', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')),
- ],
- options={
- 'verbose_name': 'video category',
- },
- ),
- migrations.AddField(
- model_name='video',
- name='category',
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='videos', to='organization festival app.VideoCategory', verbose_name='category'),
- ),
- migrations.AddField(
- model_name='video',
- name='event',
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='videos', to='mezzanine_agenda.Event', verbose_name='event'),
- ),
- migrations.AddField(
- model_name='video',
- name='site',
- field=models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site'),
- ),
- migrations.AddField(
- model_name='featured',
- name='playlists',
- field=models.ManyToManyField(blank=True, related_name='featured', to='organization festival app.Playlist', verbose_name='playlists'),
- ),
- migrations.AddField(
- model_name='featured',
- name='videos',
- field=models.ManyToManyField(blank=True, related_name='featured', to='organization festival app.Video', verbose_name='videos'),
+ bases=(mezzanine.utils.models.AdminThumbMixin, models.Model),
),
]
from mezzanine.blog.models import BlogPost
from mezzanine.pages.models import Page
-from mezzanine_agenda.models import Event
+from organization.core.models import *
+from organization.media.models import *
import requests
from pyquery import PyQuery as pq
-ALIGNMENT_CHOICES = (('left', _('left')), ('right', _('right')))
-MEDIA_BASE_URL = getattr(settings, 'MEDIA_BASE_URL', 'http://medias.ircam.fr/embed/media/')
-
-
-
-class BaseNameModel(models.Model):
- """Base object with name and description"""
-
- name = models.CharField(_('name'), max_length=512)
- description = models.TextField(_('description'), blank=True)
-
- class Meta:
- abstract = True
-
- def __unicode__(self):
- return self.name
-
-class BaseTitleModel(models.Model):
- """Base object with title and description"""
-
- title = models.CharField(_('title'), max_length=512)
- description = models.TextField(_('description'), blank=True)
-
- class Meta:
- abstract = True
-
- def __unicode__(self):
- return self.title
-
-
-class Artist(Displayable, RichText, AdminThumbMixin):
+class Artist(Displayable, RichText, AdminThumbMixin, Photo):
"""Artist"""
first_name = models.CharField(_('first name'), max_length=255, blank=True, null=True)
last_name = models.CharField(_('last name'), max_length=255, blank=True, null=True)
bio = RichTextField(_('biography'), blank=True)
- photo = FileField(_('photo'), upload_to='images/photos', max_length=1024, blank=True, format="Image")
- photo_credits = models.CharField(_('photo credits'), max_length=255, blank=True, null=True)
- photo_alignment = models.CharField(_('photo alignment'), choices=ALIGNMENT_CHOICES, max_length=32, default="left", blank=True)
- photo_description = models.TextField(_('photo description'), blank=True)
- photo_featured = FileField(_('photo featured'), upload_to='images/photos', max_length=1024, blank=True, format="Image")
- photo_featured_credits = models.CharField(_('photo featured credits'), max_length=255, blank=True, null=True)
- events = models.ManyToManyField(Event, related_name='artists', verbose_name=_('events'), blank=True)
-
search_fields = ("title", "bio")
class Meta:
@property
def name(self):
return self.title
-
- def get_absolute_url(self):
- return reverse("festival-artist-detail", kwargs={'slug': self.slug})
-
- def set_names(self):
- names = self.title.split(' ')
- if len(names) == 1:
- self.first_name = ''
- self.last_name = names[0]
- elif len(names) == 2:
- self.first_name = names[0]
- self.last_name = names[1]
- else:
- self.first_name = names[0]
- self.last_name = ' '.join(names[1:])
-
- def clean(self):
- super(Artist, self).clean()
- self.set_names()
-
- def save(self, *args, **kwargs):
- self.set_names()
- super(Artist, self).save(*args, **kwargs)
-
- @property
- def featured_image(self):
- if self.photo_featured:
- return self.photo_featured
- else:
- return self.photo
-
-
-class Media(Displayable, RichText):
- """Media"""
-
- media_id = models.CharField(_('media id'), max_length=128)
- open_source_url = models.URLField(_('open source URL'), max_length=1024, blank=True)
- closed_source_url = models.URLField(_('closed source URL'), max_length=1024, blank=True)
- poster_url = models.URLField(_('poster'), max_length=1024, blank=True)
-
- class Meta:
- abstract = True
-
- def __unicode__(self):
- return self.title
-
- @property
- def uri(self):
- return MEDIA_BASE_URL + self.media_id
-
- def get_html(self):
- r = requests.get(self.uri)
- return r.content
-
- def clean(self):
- super(Media, self).clean()
- self.q = pq(self.get_html())
- sources = self.q('source')
- for source in sources:
- if self.open_source_mime_type in source.attrib['type']:
- self.open_source_url = source.attrib['src']
- elif self.closed_source_mime_type in source.attrib['type']:
- self.closed_source_url = source.attrib['src']
- video = self.q('video')
- if len(video):
- if 'poster' in video[0].attrib.keys():
- self.poster_url = video[0].attrib['poster']
-
-
-class Audio(Media):
- """Audio"""
-
- open_source_mime_type = 'audio/ogg'
- closed_source_mime_type = 'audio/mp4'
-
- event = models.ForeignKey(Event, related_name='audios', verbose_name=_('event'), blank=True, null=True, on_delete=models.SET_NULL)
- artists = models.ManyToManyField(Artist, verbose_name=_('artists'), related_name='audios', blank=True)
-
- class Meta:
- verbose_name = _('audio')
-
- def get_absolute_url(self):
- return reverse("festival-video-detail", kwargs={"slug": self.slug})
-
-
-class Video(Media):
- """Video"""
-
- open_source_mime_type = 'video/webm'
- closed_source_mime_type = 'video/mp4'
-
- event = models.ForeignKey(Event, related_name='videos', verbose_name=_('event'), blank=True, null=True, on_delete=models.SET_NULL)
- category = models.ForeignKey('VideoCategory', related_name='videos', verbose_name=_('category'), blank=True, null=True, on_delete=models.SET_NULL)
- artists = models.ManyToManyField(Artist, verbose_name=_('artists'), related_name='videos', blank=True)
-
- class Meta:
- verbose_name = _('video')
-
- @property
- def html(self):
- #TODO: get html content from medias.ircam.fr with request module
- pass
-
- def get_absolute_url(self):
- return reverse("festival-video-detail", kwargs={"slug": self.slug})
-
-
-class Playlist(BaseTitleModel):
- """(Playlist description)"""
-
- audios = models.ManyToManyField(Audio, verbose_name=_('audios'), related_name='playlists', blank=True)
- event = models.ForeignKey(Event, related_name='playlists', verbose_name=_('event'), blank=True, null=True, on_delete=models.SET_NULL)
-
- def __str__(self):
- return self.title
-
-
-class Featured(BaseNameModel):
- """(Featured description)"""
-
- artists = models.ManyToManyField(Artist, verbose_name=_('artists'), related_name='featured', blank=True)
- events = models.ManyToManyField(Event, verbose_name=_('events'), related_name='featured', blank=True)
- videos = models.ManyToManyField(Video, verbose_name=_('videos'), related_name='featured', blank=True)
- blogposts = models.ManyToManyField(BlogPost, verbose_name=_('blog posts'), related_name='featured', blank=True)
- pages = models.ManyToManyField(Page, verbose_name=_('pages'), related_name='featured', blank=True)
- playlists = models.ManyToManyField(Playlist, verbose_name=_('playlists'), related_name='featured', blank=True)
-
- def __unicode__(self):
- return self.name
-
-
-class VideoCategory(Slugged):
- """Video Category"""
-
- class Meta:
- verbose_name = _('video category')
-
- def count(self):
- return self.videos.published().count()+1
from random import shuffle
from organization.festival.models import *
+from organization.magazine.models import *
register = Library()
from modeltranslation.translator import register, TranslationOptions
-from mezzanine_agenda.models import Event, EventLocation
from organization.festival.models import *
-
-@register(Event)
-class EventTranslationOptions(TranslationOptions):
-
- fields = ('title', 'description', 'content')
-
-@register(EventLocation)
-class EventLocationTranslationOptions(TranslationOptions):
-
- fields = ('description',)
-
@register(Artist)
class ArtistTranslationOptions(TranslationOptions):
fields = ('title', 'description', 'bio', 'content')
-
-
-@register(Video)
-class VideoTranslationOptions(TranslationOptions):
-
- fields = ('title', 'description', 'content')
-
-
-@register(Audio)
-class AudioTranslationOptions(TranslationOptions):
-
- fields = ('title', 'description', 'content')
urlpatterns = [
url(r'^artists/$', ArtistListView.as_view(), name="festival-artist-list"),
url(r'^artists/detail/(?P<slug>.*)/$', ArtistDetailView.as_view(), name="festival-artist-detail"),
- url(r'^videos/$', VideoListView.as_view(), name="festival-video-list"),
- url(r'^videos/detail/(?P<slug>.*)/$', VideoDetailView.as_view(), name="festival-video-detail"),
- url(r'^videos/category/(?P<slug>.*)/$', VideoListCategoryView.as_view(), name="festival-video-list-category"),
]
from organization.festival.models import *
from mezzanine_agenda.models import EventLocation
-
-class SlugMixin(object):
-
- def get_object(self):
- objects = self.model.objects.all()
- return get_object_or_404(objects, slug=self.kwargs['slug'])
+from organization.core.views import *
class ArtistListView(ListView):
def get_context_data(self, **kwargs):
context = super(ArtistDetailView, self).get_context_data(**kwargs)
return context
-
-
-class VideoListView(ListView):
-
- model = Video
- template_name='festival/video_list.html'
-
- def get_queryset(self, **kwargs):
- return self.model.objects.published()
-
- def get_context_data(self, **kwargs):
- context = super(VideoListView, self).get_context_data(**kwargs)
- context['categories'] = VideoCategory.objects.all()
- return context
-
-
-class VideoDetailView(SlugMixin, DetailView):
-
- model = Video
- template_name='festival/video_detail.html'
- context_object_name = 'video'
-
- def get_context_data(self, **kwargs):
- context = super(VideoDetailView, self).get_context_data(**kwargs)
- return context
-
-
-class VideoListCategoryView(VideoListView):
-
- def get_queryset(self):
- self.category = VideoCategory.objects.get(slug=self.kwargs['slug'])
- return self.model.objects.filter(category=self.category)
-
- def get_context_data(self, **kwargs):
- context = super(VideoListCategoryView, self).get_context_data(**kwargs)
- context['category'] = self.category
- return context
from django.contrib import admin
-# Register your models here.
+from organization.magazine.models import *
from __future__ import unicode_literals
+
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse, reverse_lazy
-from mezzanine.blog.models import BlogPost
-from organization.core.models import Named
+
+from mezzanine.blog.models import *
+
+from mezzanine_agenda.models import Event
+
+from organization.magazine.models import *
+from organization.core.models import *
+
class Article(BlogPost):
class Meta:
verbose_name = _('article')
+
class Category(Named):
"""(Category description)"""
+from copy import deepcopy
from django.contrib import admin
+from mezzanine.core.admin import DisplayableAdmin, OwnableAdmin
+from organization.media.models import *
-# Register your models here.
+
+class VideoAdmin(admin.ModelAdmin):
+
+ model = Video
+
+
+class VideoAdminDisplayable(DisplayableAdmin):
+
+ fieldsets = deepcopy(VideoAdmin.fieldsets)
+ #filter_horizontal = ['artists']
+
+
+class AudioAdmin(admin.ModelAdmin):
+
+ model = Audio
+
+
+class AudioAdminDisplayable(DisplayableAdmin):
+
+ fieldsets = deepcopy(AudioAdmin.fieldsets)
+ # filter_horizontal = ['artists']
+
+
+class PlaylistAdmin(admin.ModelAdmin):
+
+ model = Playlist
+ list_display = ('__unicode__',)
+ filter_horizontal = ['audios']
+
+
+admin.site.register(Video, VideoAdminDisplayable)
+admin.site.register(Audio, AudioAdminDisplayable)
+admin.site.register(Playlist, PlaylistAdmin)
+admin.site.register(VideoCategory)
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-07-07 14:14
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+import mezzanine.core.fields
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ('sites', '0002_alter_domain_unique'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Audio',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('keywords_string', models.CharField(blank=True, editable=False, max_length=500)),
+ ('title', models.CharField(max_length=500, verbose_name='Title')),
+ ('title_fr', models.CharField(max_length=500, null=True, verbose_name='Title')),
+ ('title_en', models.CharField(max_length=500, null=True, verbose_name='Title')),
+ ('slug', models.CharField(blank=True, help_text='Leave blank to have the URL auto-generated from the title.', max_length=2000, null=True, verbose_name='URL')),
+ ('_meta_title', models.CharField(blank=True, help_text='Optional title to be used in the HTML title tag. If left blank, the main title field will be used.', max_length=500, null=True, verbose_name='Title')),
+ ('description', models.TextField(blank=True, verbose_name='Description')),
+ ('description_fr', models.TextField(blank=True, null=True, verbose_name='Description')),
+ ('description_en', models.TextField(blank=True, null=True, verbose_name='Description')),
+ ('gen_description', models.BooleanField(default=True, help_text='If checked, the description will be automatically generated from content. Uncheck if you want to manually set a custom description.', verbose_name='Generate description')),
+ ('created', models.DateTimeField(editable=False, null=True)),
+ ('updated', models.DateTimeField(editable=False, null=True)),
+ ('status', models.IntegerField(choices=[(1, 'Draft'), (2, 'Published')], default=2, help_text='With Draft chosen, will only be shown for admin users on the site.', verbose_name='Status')),
+ ('publish_date', models.DateTimeField(blank=True, db_index=True, help_text="With Published chosen, won't be shown until this time", null=True, verbose_name='Published from')),
+ ('expiry_date', models.DateTimeField(blank=True, help_text="With Published chosen, won't be shown after this time", null=True, verbose_name='Expires on')),
+ ('short_url', models.URLField(blank=True, null=True)),
+ ('in_sitemap', models.BooleanField(default=True, verbose_name='Show in sitemap')),
+ ('content', mezzanine.core.fields.RichTextField(verbose_name='Content')),
+ ('content_fr', mezzanine.core.fields.RichTextField(null=True, verbose_name='Content')),
+ ('content_en', mezzanine.core.fields.RichTextField(null=True, verbose_name='Content')),
+ ('media_id', models.CharField(max_length=128, verbose_name='media id')),
+ ('open_source_url', models.URLField(blank=True, max_length=1024, verbose_name='open source URL')),
+ ('closed_source_url', models.URLField(blank=True, max_length=1024, verbose_name='closed source URL')),
+ ('poster_url', models.URLField(blank=True, max_length=1024, verbose_name='poster')),
+ ('site', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')),
+ ],
+ options={
+ 'verbose_name': 'audio',
+ },
+ ),
+ migrations.CreateModel(
+ name='Playlist',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('title', models.CharField(max_length=512, verbose_name='title')),
+ ('description', models.TextField(blank=True, verbose_name='description')),
+ ('audios', models.ManyToManyField(blank=True, related_name='playlists', to='organization media.Audio', verbose_name='audios')),
+ ],
+ options={
+ 'abstract': False,
+ },
+ ),
+ migrations.CreateModel(
+ name='Video',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('keywords_string', models.CharField(blank=True, editable=False, max_length=500)),
+ ('title', models.CharField(max_length=500, verbose_name='Title')),
+ ('title_fr', models.CharField(max_length=500, null=True, verbose_name='Title')),
+ ('title_en', models.CharField(max_length=500, null=True, verbose_name='Title')),
+ ('slug', models.CharField(blank=True, help_text='Leave blank to have the URL auto-generated from the title.', max_length=2000, null=True, verbose_name='URL')),
+ ('_meta_title', models.CharField(blank=True, help_text='Optional title to be used in the HTML title tag. If left blank, the main title field will be used.', max_length=500, null=True, verbose_name='Title')),
+ ('description', models.TextField(blank=True, verbose_name='Description')),
+ ('description_fr', models.TextField(blank=True, null=True, verbose_name='Description')),
+ ('description_en', models.TextField(blank=True, null=True, verbose_name='Description')),
+ ('gen_description', models.BooleanField(default=True, help_text='If checked, the description will be automatically generated from content. Uncheck if you want to manually set a custom description.', verbose_name='Generate description')),
+ ('created', models.DateTimeField(editable=False, null=True)),
+ ('updated', models.DateTimeField(editable=False, null=True)),
+ ('status', models.IntegerField(choices=[(1, 'Draft'), (2, 'Published')], default=2, help_text='With Draft chosen, will only be shown for admin users on the site.', verbose_name='Status')),
+ ('publish_date', models.DateTimeField(blank=True, db_index=True, help_text="With Published chosen, won't be shown until this time", null=True, verbose_name='Published from')),
+ ('expiry_date', models.DateTimeField(blank=True, help_text="With Published chosen, won't be shown after this time", null=True, verbose_name='Expires on')),
+ ('short_url', models.URLField(blank=True, null=True)),
+ ('in_sitemap', models.BooleanField(default=True, verbose_name='Show in sitemap')),
+ ('content', mezzanine.core.fields.RichTextField(verbose_name='Content')),
+ ('content_fr', mezzanine.core.fields.RichTextField(null=True, verbose_name='Content')),
+ ('content_en', mezzanine.core.fields.RichTextField(null=True, verbose_name='Content')),
+ ('media_id', models.CharField(max_length=128, verbose_name='media id')),
+ ('open_source_url', models.URLField(blank=True, max_length=1024, verbose_name='open source URL')),
+ ('closed_source_url', models.URLField(blank=True, max_length=1024, verbose_name='closed source URL')),
+ ('poster_url', models.URLField(blank=True, max_length=1024, verbose_name='poster')),
+ ],
+ options={
+ 'verbose_name': 'video',
+ },
+ ),
+ migrations.CreateModel(
+ name='VideoCategory',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('title', models.CharField(max_length=500, verbose_name='Title')),
+ ('slug', models.CharField(blank=True, help_text='Leave blank to have the URL auto-generated from the title.', max_length=2000, null=True, verbose_name='URL')),
+ ('site', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')),
+ ],
+ options={
+ 'verbose_name': 'video category',
+ },
+ ),
+ migrations.AddField(
+ model_name='video',
+ name='category',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='videos', to='organization media.VideoCategory', verbose_name='category'),
+ ),
+ migrations.AddField(
+ model_name='video',
+ name='site',
+ field=models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site'),
+ ),
+ ]
from mezzanine.core.fields import RichTextField, OrderField, FileField
from mezzanine.utils.models import AdminThumbMixin, upload_to
+from mezzanine_agenda.models import Event
+from organization.core.models import *
+
+
ALIGNMENT_CHOICES = (('left', _('left')), ('center', _('center')), ('right', _('right')))
+MEDIA_BASE_URL = getattr(settings, 'MEDIA_BASE_URL', 'http://medias.ircam.fr/embed/media/')
-class Photos(models.Model):
+class Photo(models.Model):
"""Photo bundle with credits"""
photo = FileField(_('photo'), upload_to='images/photos', max_length=1024, blank=True, format="Image")
class Meta:
abstract = True
+
+ @property
+ def card(self):
+ if self.photo_card:
+ return self.photo_card
+ else:
+ return self.photo
+
+
+class Media(Displayable, RichText):
+ """Media"""
+
+ media_id = models.CharField(_('media id'), max_length=128)
+ open_source_url = models.URLField(_('open source URL'), max_length=1024, blank=True)
+ closed_source_url = models.URLField(_('closed source URL'), max_length=1024, blank=True)
+ poster_url = models.URLField(_('poster'), max_length=1024, blank=True)
+
+ class Meta:
+ abstract = True
+
+ def __unicode__(self):
+ return self.title
+
+ @property
+ def uri(self):
+ return MEDIA_BASE_URL + self.media_id
+
+ def get_html(self):
+ r = requests.get(self.uri)
+ return r.content
+
+ def clean(self):
+ super(Media, self).clean()
+ self.q = pq(self.get_html())
+ sources = self.q('source')
+ for source in sources:
+ if self.open_source_mime_type in source.attrib['type']:
+ self.open_source_url = source.attrib['src']
+ elif self.closed_source_mime_type in source.attrib['type']:
+ self.closed_source_url = source.attrib['src']
+ video = self.q('video')
+ if len(video):
+ if 'poster' in video[0].attrib.keys():
+ self.poster_url = video[0].attrib['poster']
+
+
+class Audio(Media):
+ """Audio"""
+
+ open_source_mime_type = 'audio/ogg'
+ closed_source_mime_type = 'audio/mp4'
+
+ class Meta:
+ verbose_name = _('audio')
+
+ def get_absolute_url(self):
+ return reverse("festival-video-detail", kwargs={"slug": self.slug})
+
+
+class Video(Media):
+ """Video"""
+
+ open_source_mime_type = 'video/webm'
+ closed_source_mime_type = 'video/mp4'
+ category = models.ForeignKey('VideoCategory', related_name='videos', verbose_name=_('category'), blank=True, null=True, on_delete=models.SET_NULL)
+
+ class Meta:
+ verbose_name = _('video')
+
+ @property
+ def html(self):
+ #TODO: get html content from medias.ircam.fr with request module
+ pass
+
+ def get_absolute_url(self):
+ return reverse("festival-video-detail", kwargs={"slug": self.slug})
+
+
+class VideoCategory(Slugged):
+ """Video Category"""
+
+ class Meta:
+ verbose_name = _('video category')
+
+ def count(self):
+ return self.videos.published().count()+1
+
+
+class Playlist(Titled):
+ """(Playlist description)"""
+
+ audios = models.ManyToManyField('Audio', verbose_name=_('audios'), related_name='playlists', blank=True)
+
+ def __str__(self):
+ return self.title
--- /dev/null
+from modeltranslation.translator import translator, register, TranslationOptions
+
+from organization.media.models import *
+
+
+@register(Video)
+class VideoTranslationOptions(TranslationOptions):
+
+ fields = ('title', 'description', 'content')
+
+
+@register(Audio)
+class AudioTranslationOptions(TranslationOptions):
+
+ fields = ('title', 'description', 'content')
--- /dev/null
+from __future__ import unicode_literals
+
+from django.conf.urls import patterns, include, url
+from django.conf.urls.i18n import i18n_patterns
+from django.contrib import admin
+
+from mezzanine.core.views import direct_to_template
+from mezzanine.conf import settings
+
+from organization.festival.views import *
+
+
+urlpatterns = [
+ url(r'^videos/$', VideoListView.as_view(), name="festival-video-list"),
+ url(r'^videos/detail/(?P<slug>.*)/$', VideoDetailView.as_view(), name="festival-video-detail"),
+ url(r'^videos/category/(?P<slug>.*)/$', VideoListCategoryView.as_view(), name="festival-video-list-category"),
+]
from django.shortcuts import render
-# Create your views here.
+from organization.media.models import *
+from organization.core.views import *
+
+
+class VideoListView(ListView):
+
+ model = Video
+ template_name='festival/video_list.html'
+
+ def get_queryset(self, **kwargs):
+ return self.model.objects.published()
+
+ def get_context_data(self, **kwargs):
+ context = super(VideoListView, self).get_context_data(**kwargs)
+ context['categories'] = VideoCategory.objects.all()
+ return context
+
+
+class VideoDetailView(SlugMixin, DetailView):
+
+ model = Video
+ template_name='festival/video_detail.html'
+ context_object_name = 'video'
+
+ def get_context_data(self, **kwargs):
+ context = super(VideoDetailView, self).get_context_data(**kwargs)
+ return context
+
+
+class VideoListCategoryView(VideoListView):
+
+ def get_queryset(self):
+ self.category = VideoCategory.objects.get(slug=self.kwargs['slug'])
+ return self.model.objects.filter(category=self.category)
+
+ def get_context_data(self, **kwargs):
+ context = super(VideoListCategoryView, self).get_context_data(**kwargs)
+ context['category'] = self.category
+ return context
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-07-07 14:14
+from __future__ import unicode_literals
+
+from django.db import migrations
+import mezzanine.core.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('organization structure', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.DeleteModel(
+ name='Modelname',
+ ),
+ migrations.AlterModelOptions(
+ name='person',
+ options={'ordering': ['last_name'], 'verbose_name': 'person'},
+ ),
+ migrations.AddField(
+ model_name='person',
+ name='bio',
+ field=mezzanine.core.fields.RichTextField(blank=True, verbose_name='biography'),
+ ),
+ ]
from django_countries.fields import CountryField
-from organization.media.models import Photos
+from organization.media.models import Photo
from organization.core.models import Named
# Hack to have these strings translated
return u"Team"
-class Person(Displayable, RichText, AdminThumbMixin, Photos):
+class Person(Displayable, RichText, AdminThumbMixin, Photo):
"""(Person description)"""
user = models.ForeignKey(User, verbose_name=_('user'), blank=True, null=True, on_delete=models.SET_NULL)
last_name = models.CharField(_('last name'), max_length=255, blank=True, null=True)
birthday = models.DateField(_('birthday'), blank=True)
organization = models.ForeignKey('Organization', verbose_name=_('organization'), blank=True, null=True, on_delete=models.SET_NULL)
+ bio = RichTextField(_('biography'), blank=True)
+
+ class Meta:
+ verbose_name = _('person')
+ ordering = ['last_name',]
def __unicode__(self):
return ' '.join((self.user.first_name, self.user.last_name))
+ # def get_absolute_url(self):
+ # return reverse("festival-artist-detail", kwargs={'slug': self.slug})
+
+ def set_names(self):
+ names = self.title.split(' ')
+ if len(names) == 1:
+ self.first_name = ''
+ self.last_name = names[0]
+ elif len(names) == 2:
+ self.first_name = names[0]
+ self.last_name = names[1]
+ else:
+ self.first_name = names[0]
+ self.last_name = ' '.join(names[1:])
+
+ def clean(self):
+ super(Person, self).clean()
+ self.set_names()
+
+ def save(self, *args, **kwargs):
+ self.set_names()
+ super(Person, self).save(*args, **kwargs)
+
class Nationality(models.Model):
"""(Nationality description)"""
def __unicode__(self):
return ' - '.join((self.person, self.role, self.date_begin, self.date_end))
-
-
-class Modelname(models.Model):
- """( description)"""
-
-
- def __unicode__(self):
- return u""
"organization.magazine",
"organization.media",
"organization.project",
+ "organization.featured",
]
{% extends "agenda/event_detail.html" %}
-{% load mezzanine_tags comment_tags keyword_tags rating_tags i18n future disqus_tags event_tags festival_tags %}
+{% load mezzanine_tags comment_tags keyword_tags rating_tags i18n future disqus_tags event_tags featured_tags %}
{% block event_detail_postedby %}
{% endblock %}
{% extends "agenda/event_list.html" %}
-{% load mezzanine_tags comment_tags keyword_tags rating_tags i18n future disqus_tags event_tags festival_tags %}
+{% load mezzanine_tags comment_tags keyword_tags rating_tags i18n future disqus_tags event_tags featured_tags %}
{% block meta_title %}{{ event.meta_title }}{% endblock %}
{% extends "agenda/event_detail.html" %}
-{% load mezzanine_tags comment_tags keyword_tags rating_tags i18n future disqus_tags event_tags festival_tags %}
+{% load mezzanine_tags comment_tags keyword_tags rating_tags i18n future disqus_tags event_tags featured_tags %}
{% block title %}
{{ title }}
-{% load i18n mezzanine_tags event_tags festival_tags %}
+{% load i18n mezzanine_tags event_tags featured_tags %}
<div class="event__meta">
<div class="event__meta__inner">
{{ event.start }}
-{% load i18n mezzanine_tags event_tags festival_tags %}
+{% load i18n mezzanine_tags event_tags featured_tags %}
<div class="event__meta--alt">
<div class="event__meta__inner">
<div class="split-container">
<!doctype html>
<html lang="{{ LANGUAGE_CODE }}"{% if LANGUAGE_BIDI %} dir="rtl"{% endif %}>
-{% load i18n pages_tags mezzanine_tags staticfiles keyword_tags event_tags festival_tags %}
+{% load i18n pages_tags mezzanine_tags staticfiles keyword_tags event_tags featured_tags %}
{% get_language_info_list for LANGUAGES as languages %}
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
{% extends "blog/blog_post_list.html" %}
-{% load mezzanine_tags comment_tags keyword_tags rating_tags i18n disqus_tags festival_tags %}
+{% load mezzanine_tags comment_tags keyword_tags rating_tags i18n disqus_tags featured_tags %}
{% block meta_title %}{{ blog_post.meta_title }}{% endblock %}
-{% load i18n event_tags festival_tags mezzanine_tags %}
+{% load i18n event_tags featured_tags mezzanine_tags %}
<div class="hero__slider">
<ul id="lightSlider">
{% featured_events as events %}
{% extends "base.html" %}
-{% load i18n festival_tags %}
+{% load i18n featured_tags %}
{% block meta_title %}{% trans "Home" %}{% endblock %}
{% extends "base.html" %}
-{% load i18n mezzanine_tags keyword_tags festival_tags %}
+{% load i18n mezzanine_tags keyword_tags featured_tags %}
{% block meta_title %}{{ page.meta_title }}{% endblock %}
{% extends "base.html" %}
-{% load i18n mezzanine_tags keyword_tags festival_tags %}
+{% load i18n mezzanine_tags keyword_tags featured_tags %}
{% block meta_title %}{{ page.meta_title }}{% endblock %}
{% extends "base.html" %}
-{% load i18n festival_tags %}
+{% load i18n featured_tags %}
{% block meta_title %}{% trans "Styles" %}{% endblock %}
{% extends "base.html" %}
{% load i18n %}
-{% load mezzanine_tags keyword_tags festival_tags %}
+{% load mezzanine_tags keyword_tags featured_tags %}
{% block title %}
{{ artist.name }}
{% extends "base.html" %}
{% load i18n %}
-{% load mezzanine_tags keyword_tags festival_tags %}
+{% load mezzanine_tags keyword_tags featured_tags %}
{% block title %}
{% trans "Videos" %}