*.directory
var
data/static
+data/mysql
+data/postgresql
.thumbnails
# Installer logs
DATABASES = {
'default': {
- 'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
- 'USER': os.environ.get('DB_ENV_MYSQL_USER'), # Not used with sqlite3.
- 'PASSWORD': os.environ.get('DB_ENV_MYSQL_PASSWORD'), # Not used with sqlite3.
- 'NAME': os.environ.get('DB_ENV_MYSQL_DATABASE'),
- 'HOST': 'db', # Set to empty string for localhost. Not used with sqlite3.
- 'PORT': '3306', # Set to empty string for default. Not used with sqlite3.
+ 'ENGINE': 'django.db.backends.postgresql_psycopg2',
+ 'NAME': 'postgres',
+ 'USER': 'postgres',
+ 'PASSWORD': os.environ.get('DB_ENV_POSTGRES_PASSWORD'),
+ 'HOST': 'db',
+ 'PORT': '5432',
},
'eve': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'HOST': 'pgdb',
'PORT': '5432',
},
- #'eve': {
- # 'ENGINE': 'django.db.backends.postgresql_psycopg2',
- # 'NAME': 'eve',
- # 'USER': 'django',
- # 'PASSWORD': 'q2nqzt0WGnwWé,256',
- # 'HOST': 'eve.ircam.fr',
- # 'PORT': '5432',
- #},
-
}
# DATABASE_ROUTERS = ['eve.routers.EveRouter',]
EMAIL_HOST = 'smtp.ircam.fr'
EMAIL_PORT = '25'
-DEFAULT_FROM_EMAIL = 'manifeste2016@ircam.fr'
-EMAIL_SUBJECT_PREFIX = "IRCAM Manifeste 2016"
+DEFAULT_FROM_EMAIL = 'www@ircam.fr'
+EMAIL_SUBJECT_PREFIX = "[IRCAM WWW]"
-SITE_TITLE = 'Manifeste 2016'
-SITE_TAGLINE = 'Festival 2 juin | 2 juillet 2016'
+SITE_TITLE = 'IRCAM'
+SITE_TAGLINE = 'Institut de Recherche et de Coordination Acoustique et Musique'
SILENCED_SYSTEM_CHECKS = ['fields.W342',]
ADMIN_MENU_ORDER = (
- (_("Content"), ("pages.Page", "blog.BlogPost", "mezzanine_agenda.Event",
- "festival.Artist", "festival.Video", "festival.Audio", "festival.Playlist",
- "festival.Featured",
- "generic.ThreadedComment", (_("Media Library"), "fb_browse"),)),
- (_("Site"), ("sites.Site", "redirects.Redirect", "conf.Setting")),
- (_("Users"), ("auth.User", "auth.Group",)),
- (_("Festival"), ("mezzanine_agenda.EventLocation",
- "mezzanine_agenda.EventCategory", "mezzanine_agenda.EventPrice",
- "festival.PageCategory",)),
+ (_('Content'), ('pages.Page', 'blog.BlogPost', 'mezzanine_agenda.Event',
+ 'generic.ThreadedComment', (_('Media Library'), 'fb_browse'),)),
+ (_("Magazine"), ("magazine.Article",)),
+ (_('team'), ('organization.team.Organization', 'organization.team.Team',
+ 'organization.team.Department', 'organization.team.Person',
+ 'organization.team.Activity')),
+ (_('Projects'), ('organization.project.Project')),
+ (_('Festival'), ('organization.festival.Artist', 'organization.festival.Video',
+ 'organization.festival.Audio', 'organization.festival.Playlist',
+ 'organization.festival.Featured', 'mezzanine_agenda.EventLocation',
+ 'mezzanine_agenda.EventCategory', 'mezzanine_agenda.EventPrice',
+ 'festival.PageCategory',)),
+ (_('Users'), ('auth.User', 'auth.Group',)),
+ (_('Site'), ('sites.Site', 'redirects.Redirect', 'conf.Setting')),
)
GRAPPELLI_ADMIN_TITLE = 'IRCAM Admin'
BLOG_POST_PER_PAGE = 200
+# The numeric mode to set newly-uploaded files to. The value should be
+# a mode you'd pass directly to os.chmod.
+FILE_UPLOAD_PERMISSIONS = 0o664
+FILE_UPLOAD_TEMP_DIR = '/srv/media/uploads/tmp/'
FILEBROWSER_MAX_UPLOAD_SIZE = 512000000
if DEBUG:
'debug_toolbar.panels.logging.LoggingPanel',
'debug_toolbar.panels.redirects.RedirectsPanel',
]
+
+# slug
+BLOG_SLUG = 'article'
--- /dev/null
+"""
+Provides abstract models and admin features used throughout the various
+Mezzanine apps.
+"""
+from __future__ import unicode_literals
+
+default_app_config = 'organization.core.apps.CoreConfig'
--- /dev/null
+from django.contrib import admin
+from copy import deepcopy
+from mezzanine.pages.models import Page
+from mezzanine.pages.admin import PageAdmin
+from mezzanine.pages.models import RichTextPage
+from organization.core.models import BasicPage
+
+
+admin.site.register(BasicPage, PageAdmin)
--- /dev/null
+from django.apps import AppConfig
+
+from django.core.checks import register
+
+
+class CoreConfig(AppConfig):
+
+ name = 'organization.core'
+ label = 'organization core'
--- /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-06 16:48
+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 = [
+ ('pages', '0004_auto_20151223_1313'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='BasicPage',
+ fields=[
+ ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='pages.Page')),
+ ('content', mezzanine.core.fields.RichTextField(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')),
+ ('sub_title', models.TextField(blank=True, max_length=1024, verbose_name='sub title')),
+ ('sub_title_fr', models.TextField(blank=True, max_length=1024, null=True, verbose_name='sub title')),
+ ('sub_title_en', models.TextField(blank=True, max_length=1024, null=True, verbose_name='sub title')),
+ ],
+ options={
+ 'verbose_name': 'basic page',
+ 'ordering': ('_order',),
+ },
+ bases=('pages.page', models.Model),
+ ),
+ ]
--- /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',
+ ),
+ ]
--- /dev/null
+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
+
+
+class Named(models.Model):
+ """Named object with description"""
+
+ name = models.CharField(_('name'), max_length=512)
+ description = models.TextField(_('description'), blank=True)
+
+ class Meta:
+ abstract = True
+
+ def __unicode__(self):
+ return self.name
+
+ @property
+ def slug(self):
+ 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)
+
+ class Meta:
+ abstract = True
+
+
+class BasicPage(Page, RichText, SubTitle):
+
+ class Meta:
+ verbose_name = 'basic page'
--- /dev/null
+from django.core import exceptions
+from django.db.models.fields.related import ForeignKey
+from django.db.utils import ConnectionHandler, ConnectionRouter
+
+connections = ConnectionHandler()
+router = ConnectionRouter()
+
+
+class SpanningForeignKey(ForeignKey):
+
+ def validate(self, value, model_instance):
+ if self.rel.parent_link:
+ return
+ # Call the grandparent rather than the parent to skip validation
+ super(ForeignKey, self).validate(value, model_instance)
+ if value is None:
+ return
+
+ using = router.db_for_read(self.rel.to, instance=model_instance)
+ qs = self.rel.to._default_manager.using(using).filter(
+ **{self.rel.field_name: value}
+ )
+ qs = qs.complex_filter(self.get_limit_choices_to())
+ if not qs.exists():
+ raise exceptions.ValidationError(
+ self.error_messages['invalid'],
+ code='invalid',
+ params={
+ 'model': self.rel.to._meta.verbose_name, 'pk': value,
+ 'field': self.rel.field_name, 'value': value,
+ }, # 'pk' is included for backwards compatibility
+ )
--- /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)
--- /dev/null
+from django.test import TestCase
+
+# Create your tests here.
--- /dev/null
+from modeltranslation.translator import translator, register, TranslationOptions
+from mezzanine.pages.models import Page, RichText
+from mezzanine.pages.translation import TranslatedRichText
+
+from organization.core.models import BasicPage
+
+# @register(SubTitle)
+# class SubTitleTranslationOptions(TranslationOptions):
+#
+# fields = ('sub_title',)
+
+@register(BasicPage)
+class BasicPageTranslationOptions(TranslationOptions):
+
+ fields = ('sub_title',)
--- /dev/null
+from __future__ import unicode_literals
+
+import django.views.i18n
+from django.conf.urls import patterns, include, url
+from django.conf.urls.i18n import i18n_patterns
+
+from mezzanine.core.views import direct_to_template
+from mezzanine.conf import settings
+
+from organization.core.views import HomeView
+
+
+urlpatterns = [
+ url("^$", HomeView.as_view(), name="home"),
+]
--- /dev/null
+from django.shortcuts import render, get_object_or_404
+from django.http import Http404
+from django.views.generic.base import View
+from django.views.generic import DetailView, ListView, TemplateView
+
+
+class SlugMixin(object):
+
+ def get_object(self):
+ objects = self.model.objects.all()
+ return get_object_or_404(objects, slug=self.kwargs['slug'])
+
+
+class HomeView(TemplateView):
+
+ template_name = 'index.html'
+
+ def get_context_data(self, **kwargs):
+ context = super(HomeView, self).get_context_data(**kwargs)
+ return context
--- /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 __future__ import unicode_literals
+
+import django.views.i18n
+from django.conf.urls import patterns, include, url
+from django.conf.urls.i18n import i18n_patterns
+
+from mezzanine.core.views import direct_to_template
+from mezzanine.conf import settings
+
+
+urlpatterns = [
+
+]
--- /dev/null
+from django.shortcuts import render
+
+# Create your views here.
--- /dev/null
+"""
+Provides abstract models and admin features used throughout the various
+Mezzanine apps.
+"""
+from __future__ import unicode_literals
+
+default_app_config = 'organization.festival.apps.FestivalConfig'
--- /dev/null
+from __future__ import unicode_literals
+
+from copy import deepcopy
+
+from django.contrib import admin
+from django.utils.translation import ugettext_lazy as _
+
+from mezzanine_agenda.models import Event, EventLocation
+from mezzanine_agenda.admin import *
+
+from mezzanine.conf import settings
+from mezzanine.core.admin import DisplayableAdmin, OwnableAdmin
+
+from organization.festival.models import *
+
+
+class ArtistAdmin(admin.ModelAdmin):
+
+ model = Artist
+
+
+class ArtistAdminDisplayable(DisplayableAdmin):
+
+ fieldsets = deepcopy(ArtistAdmin.fieldsets)
+
+
+admin.site.register(Artist, ArtistAdminDisplayable)
--- /dev/null
+from django.apps import AppConfig
+
+
+class FestivalConfig(AppConfig):
+
+ name = 'organization.festival'
+ label = 'organization festival app'
--- /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
+import mezzanine.utils.models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ('sites', '0002_alter_domain_unique'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Artist',
+ 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')),
+ ('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')),
+ ('site', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')),
+ ],
+ options={
+ 'ordering': ['last_name'],
+ 'verbose_name': 'artist',
+ },
+ bases=(mezzanine.utils.models.AdminThumbMixin, models.Model),
+ ),
+ ]
--- /dev/null
+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 mezzanine.core.models import RichText, Displayable, Slugged
+from mezzanine.core.fields import RichTextField, OrderField, FileField
+from mezzanine.utils.models import AdminThumbMixin, upload_to
+from mezzanine.blog.models import BlogPost
+from mezzanine.pages.models import Page
+
+from organization.core.models import *
+from organization.media.models import *
+
+import requests
+from pyquery import PyQuery as pq
+
+
+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)
+ search_fields = ("title", "bio")
+
+ class Meta:
+ verbose_name = _('artist')
+ ordering = ['last_name',]
+
+ def __unicode__(self):
+ return self.title
+
+ @property
+ def name(self):
+ return self.title
--- /dev/null
+
+class FestivalRouter(object):
+ """
+ A router to control all database operations on models in festival
+ """
+
+ def db_for_read(self, model, **hints):
+ if model._meta.app_label == 'festival':
+ return 'default'
+ return None
+
+ def db_for_write(self, model, **hints):
+ if model._meta.app_label == 'festival':
+ return 'default'
+ return None
+
+ def allow_relation(self, obj1, obj2, **hints):
+ if obj1._meta.app_label == 'festival' or \
+ obj2._meta.app_label == 'festival':
+ return True
+ return None
+
+ # def allow_migrate(self, db, app_label, model=None, **hints):
+ # if app_label == 'festival':
+ # return db == 'default'
+ # return None
+
+ def allow_migrate(self, db, app_label, model_name=None, **hints):
+ if 'target_db' in hints:
+ return db == hints['target_db']
+ return True
--- /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)
--- /dev/null
+from django.test import TestCase
+
+# Create your tests here.
--- /dev/null
+from modeltranslation.translator import register, TranslationOptions
+
+from organization.festival.models import *
+
+@register(Artist)
+class ArtistTranslationOptions(TranslationOptions):
+
+ fields = ('title', 'description', 'bio', 'content')
--- /dev/null
+from __future__ import unicode_literals
+
+import django.views.i18n
+from django.conf.urls import patterns, include, url
+from django.conf.urls.i18n import i18n_patterns
+
+from mezzanine.core.views import direct_to_template
+from mezzanine.conf import settings
+
+from organization.festival.views import *
+
+
+urlpatterns = [
+ url(r'^artists/$', ArtistListView.as_view(), name="festival-artist-list"),
+ url(r'^artists/detail/(?P<slug>.*)/$', ArtistDetailView.as_view(), name="festival-artist-detail"),
+]
--- /dev/null
+from django.shortcuts import render
+from django.views.generic import *
+from django.views.generic.base import *
+from django.shortcuts import get_object_or_404
+
+from organization.festival.models import *
+from mezzanine_agenda.models import EventLocation
+
+from organization.core.views import *
+
+
+class ArtistListView(ListView):
+
+ model = Artist
+ template_name='festival/artist_list.html'
+
+ def get_queryset(self, **kwargs):
+ return self.model.objects.published()
+
+ def get_context_data(self, **kwargs):
+ context = super(ArtistListView, self).get_context_data(**kwargs)
+ return context
+
+
+class ArtistDetailView(SlugMixin, DetailView):
+
+ model = Artist
+ template_name='festival/artist_detail.html'
+ context_object_name = 'artist'
+
+ def get_context_data(self, **kwargs):
+ context = super(ArtistDetailView, self).get_context_data(**kwargs)
+ return context
--- /dev/null
+"""
+Provides abstract models and admin features used throughout the various
+Mezzanine apps.
+"""
+from __future__ import unicode_literals
+
+from mezzanine import __version__ # noqa
+
+
+default_app_config = 'organization.magazine.apps.MagazineConfig'
--- /dev/null
+from django.contrib import admin
+
+from organization.magazine.models import *
--- /dev/null
+from __future__ import unicode_literals
+
+from django.apps import AppConfig
+
+
+class MagazineConfig(AppConfig):
+
+ name = 'organization.magazine'
+ label = 'organization magazine'
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-07-06 16:48
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Category',
+ 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')),
+ ],
+ options={
+ 'verbose_name': 'category',
+ },
+ ),
+ migrations.CreateModel(
+ name='Topic',
+ 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')),
+ ],
+ options={
+ 'verbose_name': 'topic',
+ },
+ ),
+ ]
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-07-07 10:01
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('blog', '0003_auto_20151223_1313'),
+ ('organization magazine', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Article',
+ fields=[
+ ('blogpost_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='blog.BlogPost')),
+ ('sub_title', models.CharField(blank=True, max_length=1000, verbose_name='sub title')),
+ ('sub_title_fr', models.CharField(blank=True, max_length=1000, null=True, verbose_name='sub title')),
+ ('sub_title_en', models.CharField(blank=True, max_length=1000, null=True, verbose_name='sub title')),
+ ],
+ options={
+ 'verbose_name': 'article',
+ },
+ bases=('blog.blogpost',),
+ ),
+ ]
--- /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 mezzanine.blog.models import *
+
+from mezzanine_agenda.models import Event
+
+from organization.magazine.models import *
+from organization.core.models import *
+
+
+class Article(BlogPost):
+
+ sub_title = models.CharField(_('sub title'), blank=True, max_length=1000)
+
+ class Meta:
+ verbose_name = _('article')
+
+
+class Category(Named):
+ """(Category description)"""
+
+ class Meta:
+ verbose_name = _('category')
+
+ def __unicode__(self):
+ return self.name
+
+
+class Topic(Named):
+ """(Topic description)"""
+
+ class Meta:
+ verbose_name = _('topic')
+
+ def __unicode__(self):
+ return self.name
--- /dev/null
+from django.test import TestCase
+
+# Create your tests here.
--- /dev/null
+from modeltranslation.translator import translator, register, TranslationOptions
+from mezzanine.pages.models import Page, RichText
+from modeltranslation.translator import TranslationOptions
+from mezzanine.core.translation import (TranslatedSlugged,
+ TranslatedDisplayable,
+ TranslatedRichText)
+from organization.magazine.models import Article
+
+@register(Article)
+#class ArticleTranslationOptions(TranslatedDisplayable, TranslatedRichText):
+class ArticleTranslationOptions(TranslationOptions):
+
+ fields = ('sub_title',)
--- /dev/null
+from __future__ import unicode_literals
+
+import django.views.i18n
+from django.conf.urls import patterns, include, url
+from django.conf.urls.i18n import i18n_patterns
+
+from mezzanine.core.views import direct_to_template
+from mezzanine.conf import settings
+
+
+urlpatterns = [
+
+]
--- /dev/null
+from django.shortcuts import render
+
+# Create your views here.
--- /dev/null
+"""
+Provides abstract models and admin features used throughout the various
+Mezzanine apps.
+"""
+from __future__ import unicode_literals
+
+from mezzanine import __version__ # noqa
+
+
+default_app_config = 'organization.media.apps.MediaConfig'
--- /dev/null
+from copy import deepcopy
+from django.contrib import admin
+from mezzanine.core.admin import DisplayableAdmin, OwnableAdmin
+from organization.media.models import *
+
+
+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
+from __future__ import unicode_literals
+
+from django.apps import AppConfig
+
+
+class MediaConfig(AppConfig):
+
+ name = 'organization.media'
+ label = 'organization media'
--- /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'),
+ ),
+ ]
--- /dev/null
+from __future__ import unicode_literals
+
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+
+from mezzanine.core.models import RichText, Displayable, Slugged
+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 Photo(models.Model):
+ """Photo bundle with credits"""
+
+ 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_card = FileField(_('card photo'), upload_to='images/photos/card', max_length=1024, blank=True, format="Image")
+ photo_card_credits = models.CharField(_('photo card credits'), max_length=255, blank=True, null=True)
+
+ photo_slider = FileField(_('slider photo'), upload_to='images/photos/slider', max_length=1024, blank=True, format="Image")
+ photo_slider_credits = models.CharField(_('photo slider credits'), max_length=255, blank=True, null=True)
+
+ 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 django.test import TestCase
+
+# Create your tests here.
--- /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
+
+import django.views.i18n
+from django.conf.urls import patterns, include, url
+from django.conf.urls.i18n import i18n_patterns
+
+from mezzanine.core.views import direct_to_template
+from mezzanine.conf import settings
+
+from organization.media.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"),
+]
--- /dev/null
+from django.shortcuts import render
+
+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
+"""
+Provides abstract models and admin features used throughout the various
+Mezzanine apps.
+"""
+from __future__ import unicode_literals
+
+from mezzanine import __version__ # noqa
+
+
+default_app_config = 'organization.project.apps.ProjectConfig'
--- /dev/null
+from django.contrib import admin
+from mezzanine.blog.admin import BlogPostAdmin
+from organization.magazine.models import Article
+#from custom.admin import SubTitleAdmin
+from copy import deepcopy
+
+from django.contrib import admin
+from django.utils.translation import ugettext_lazy as _
+from mezzanine.core.admin import DisplayableAdmin, OwnableAdmin
+
+# class ArticleAdmin(BlogPostAdmin, SubTitleAdmin):
+#
+# model = Article
+
+#admin.site.register(Article, BlogPostAdmin)
+class ArticleAdmin(admin.ModelAdmin):
+
+ model = Article
+
+
+class ArticleAdminDisplayable(DisplayableAdmin):
+
+ fieldsets = deepcopy(ArticleAdmin.fieldsets)
+
+admin.site.register(Article, ArticleAdminDisplayable)
--- /dev/null
+from __future__ import unicode_literals
+
+from django.apps import AppConfig
+
+
+class ProjectConfig(AppConfig):
+
+ name = 'organization.project'
+ label = 'organization project'
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-07-07 08:53
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import mezzanine.core.fields
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Project',
+ 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')),
+ ('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')),
+ ('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')),
+ ],
+ options={
+ 'abstract': False,
+ },
+ ),
+ ]
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-07-07 08:53
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ('sites', '0002_alter_domain_unique'),
+ ('organization project', '0001_initial'),
+ ('organization team', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='project',
+ name='partners',
+ field=models.ManyToManyField(to='organization team.Organization', verbose_name='organizations'),
+ ),
+ migrations.AddField(
+ model_name='project',
+ name='persons',
+ field=models.ManyToManyField(to='organization team.Person', verbose_name='persons'),
+ ),
+ migrations.AddField(
+ model_name='project',
+ name='site',
+ field=models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site'),
+ ),
+ ]
--- /dev/null
+from __future__ import unicode_literals
+
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+
+from mezzanine.core.models import RichText, Displayable, Slugged
+
+from organization.team.models import Person, Organization
+
+
+class Project(Displayable, RichText):
+ """(Project description)"""
+
+ persons = models.ManyToManyField(Person, verbose_name=_('persons'))
+ partners = models.ManyToManyField(Organization, verbose_name=_('organizations'))
+
+ def __unicode__(self):
+ return self.title
--- /dev/null
+from django.test import TestCase
+
+# Create your tests here.
--- /dev/null
+from __future__ import unicode_literals
+
+import django.views.i18n
+from django.conf.urls import patterns, include, url
+from django.conf.urls.i18n import i18n_patterns
+
+from mezzanine.core.views import direct_to_template
+from mezzanine.conf import settings
+
+
+urlpatterns = [
+
+]
--- /dev/null
+from django.shortcuts import render
+
+# Create your views here.
--- /dev/null
+"""
+Provides abstract models and admin features used throughout the various
+Mezzanine apps.
+"""
+from __future__ import unicode_literals
+
+from mezzanine import __version__ # noqa
+
+
+default_app_config = 'organization.team.apps.teamConfig'
--- /dev/null
+from django.contrib import admin
+
+# Register your models here.
--- /dev/null
+from __future__ import unicode_literals
+
+from django.apps import AppConfig
+
+
+class teamConfig(AppConfig):
+
+ name = 'organization.team'
+ label = 'organization team'
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-07-07 08:53
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+import django_countries.fields
+import mezzanine.core.fields
+import mezzanine.utils.models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ('sites', '0002_alter_domain_unique'),
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Activity',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('date_begin', models.DateField(blank=True, null=True, verbose_name='begin date')),
+ ('date_end', models.DateField(blank=True, null=True, verbose_name='end date')),
+ ('role', models.CharField(blank=True, max_length=512, verbose_name='role')),
+ ('work', models.TextField(blank=True, verbose_name='work')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Address',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('address', models.TextField(blank=True, verbose_name='description')),
+ ('postal_code', models.CharField(blank=True, max_length=16, verbose_name='postal code')),
+ ('country', django_countries.fields.CountryField(max_length=2, verbose_name='country')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Department',
+ 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')),
+ ('url', models.URLField(blank=True, max_length=512, verbose_name='URL')),
+ ('weaving_class', models.CharField(blank=True, max_length=64, verbose_name='weaving class')),
+ ],
+ options={
+ 'verbose_name': 'department',
+ },
+ ),
+ migrations.CreateModel(
+ name='Link',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('url', models.URLField(verbose_name='URL')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='LinkType',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=256, verbose_name='Name')),
+ ('slug', models.SlugField(blank=True, help_text='Use this field to define a simple identifier that can be used to style the different link types (i.e. assign social media icons to them)', max_length=256, verbose_name='Slug')),
+ ('ordering', models.PositiveIntegerField(blank=True, null=True, verbose_name='Ordering')),
+ ],
+ options={
+ 'ordering': ['ordering'],
+ },
+ ),
+ migrations.CreateModel(
+ name='Modelname',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Nationality',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=128, verbose_name='name')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='OrganizationType',
+ 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')),
+ ],
+ options={
+ 'verbose_name': 'organization type',
+ },
+ ),
+ migrations.CreateModel(
+ name='Person',
+ 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')),
+ ('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')),
+ ('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')),
+ ('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')),
+ ('person_title', models.CharField(blank=True, choices=[('Dr', 'Dr'), ('Prof', 'Prof'), ('Prof Dr', 'Prof Dr')], max_length=16, verbose_name='title')),
+ ('gender', models.CharField(blank=True, choices=[('male', 'male'), ('female', 'female')], max_length=16, verbose_name='gender')),
+ ('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')),
+ ('birthday', models.DateField(blank=True, verbose_name='birthday')),
+ ('site', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')),
+ ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='user')),
+ ],
+ options={
+ 'abstract': False,
+ },
+ bases=(mezzanine.utils.models.AdminThumbMixin, models.Model),
+ ),
+ migrations.CreateModel(
+ name='Team',
+ 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')),
+ ('department', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='organization team.Department', verbose_name='department')),
+ ],
+ options={
+ 'abstract': False,
+ },
+ ),
+ migrations.CreateModel(
+ name='Organization',
+ fields=[
+ ('address_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='organization team.Address')),
+ ('name', models.CharField(max_length=512, verbose_name='name')),
+ ('description', models.TextField(blank=True, verbose_name='description')),
+ ('url', models.URLField(blank=True, max_length=512, verbose_name='URL')),
+ ('type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='organization team.OrganizationType', verbose_name='organization type')),
+ ],
+ options={
+ 'verbose_name': 'organization',
+ },
+ bases=('organization team.address', models.Model),
+ ),
+ migrations.AddField(
+ model_name='link',
+ name='link_type',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organization team.LinkType', verbose_name='Link type'),
+ ),
+ migrations.AddField(
+ model_name='link',
+ name='person',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organization team.Person', verbose_name='Person'),
+ ),
+ migrations.AddField(
+ model_name='activity',
+ name='person',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organization team.Person', verbose_name='person'),
+ ),
+ migrations.AddField(
+ model_name='activity',
+ name='teams',
+ field=models.ManyToManyField(to='organization team.Team', verbose_name='teams'),
+ ),
+ migrations.AddField(
+ model_name='person',
+ name='organization',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='organization team.Organization', verbose_name='organization'),
+ ),
+ migrations.AddField(
+ model_name='department',
+ name='organization',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organization team.Organization', verbose_name='organization'),
+ ),
+ ]
--- /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 team', '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'),
+ ),
+ ]
--- /dev/null
+from __future__ import unicode_literals
+
+import os
+import re
+import pwd
+import time
+import urllib
+import string
+import datetime
+import mimetypes
+
+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 django.contrib.auth.models import User
+
+from mezzanine.core.models import RichText, Displayable, Slugged
+from mezzanine.core.fields import RichTextField, OrderField, FileField
+from mezzanine.utils.models import AdminThumbMixin, upload_to
+
+from django_countries.fields import CountryField
+
+from organization.media.models import Photo
+from organization.core.models import Named
+
+# Hack to have these strings translated
+mr = _('Mr')
+mrs = _('Ms')
+
+GENDER_CHOICES = [
+ ('male', _('male')),
+ ('female', _('female')),
+]
+
+TITLE_CHOICES = [
+ ('Dr', _('Dr')),
+ ('Prof', _('Prof')),
+ ('Prof Dr', _('Prof Dr')),
+]
+
+ALIGNMENT_CHOICES = (('left', _('left')), ('right', _('right')))
+
+
+
+class Address(models.Model):
+ """(Address description)"""
+
+ address = models.TextField(_('description'), blank=True)
+ postal_code = models.CharField(_('postal code'), max_length=16, blank=True)
+ country = CountryField(_('country'))
+
+ def __unicode__(self):
+ return u"Address"
+
+ class Meta:
+ abstract = True
+
+
+class Organization(Named, Address):
+ """(Organization description)"""
+
+ type = models.ForeignKey('OrganizationType', verbose_name=_('organization type'), blank=True, null=True, on_delete=models.SET_NULL)
+ url = models.URLField(_('URL'), max_length=512, blank=True)
+
+ def __unicode__(self):
+ return self.name
+
+ class Meta:
+ verbose_name = _('organization')
+
+
+class OrganizationType(Named):
+ """(OrganizationType description)"""
+
+ class Meta:
+ verbose_name = _('organization type')
+
+
+class Department(Named):
+ """(Department description)"""
+
+ organization = models.ForeignKey('Organization', verbose_name=_('organization'))
+ url = models.URLField(_('URL'), max_length=512, blank=True)
+ weaving_class = models.CharField(_('weaving class'), max_length=64, blank=True)
+
+ def __unicode__(self):
+ return self.name
+
+ class Meta:
+ verbose_name = _('department')
+
+
+class Team(Named):
+ """(Team description)"""
+
+ department = models.ForeignKey('Department', verbose_name=_('department'), blank=True, null=True, on_delete=models.SET_NULL)
+
+ def __unicode__(self):
+ return u"Team"
+
+
+class Person(Displayable, RichText, AdminThumbMixin, Photo):
+ """(Person description)"""
+
+ user = models.ForeignKey(User, verbose_name=_('user'), blank=True, null=True, on_delete=models.SET_NULL)
+ person_title = models.CharField(_('title'), max_length=16, choices=TITLE_CHOICES, blank=True)
+ gender = models.CharField(_('gender'), max_length=16, choices=GENDER_CHOICES, blank=True)
+ 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)
+ 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)"""
+
+ name = models.CharField(_('name'), max_length=128)
+
+ def __unicode__(self):
+ return self.name
+
+
+class Link(models.Model):
+ """A person can have many links."""
+
+ person = models.ForeignKey('Person', verbose_name=_('Person'))
+ link_type = models.ForeignKey('LinkType', verbose_name=_('Link type'))
+ url = models.URLField(verbose_name=_('URL'))
+
+ def __str__(self):
+ return self.url
+
+
+class LinkType(models.Model):
+ """
+ A link type could be ``Facebook`` or ``Twitter`` or ``Website``.
+ This is masterdata that should be created by the admins when the site is
+ deployed for the first time.
+ :ordering: Enter numbers here if you want links to be displayed in a
+ special order.
+ """
+
+ name = models.CharField(max_length=256, verbose_name=_('Name'))
+ slug = models.SlugField(max_length=256, verbose_name=_('Slug'), help_text=_(
+ 'Use this field to define a simple identifier that can be used'
+ ' to style the different link types (i.e. assign social media'
+ ' icons to them)'),
+ blank=True,
+ )
+ ordering = models.PositiveIntegerField(verbose_name=_('Ordering'), null=True, blank=True)
+
+ class Meta:
+ ordering = ['ordering', ]
+
+ def __str__(self):
+ return self.name
+
+
+class Activity(models.Model):
+ """(Activity description)"""
+
+ person = models.ForeignKey('Person', verbose_name=_('person'))
+ teams = models.ManyToManyField('Team', verbose_name=_('teams'))
+ date_begin = models.DateField(_('begin date'), null=True, blank=True)
+ date_end = models.DateField(_('end date'), null=True, blank=True)
+ role = models.CharField(_('role'), blank=True, max_length=512)
+ work = models.TextField(_('work'), blank=True)
+
+ def __unicode__(self):
+ return ' - '.join((self.person, self.role, self.date_begin, self.date_end))
--- /dev/null
+from django.test import TestCase
+
+# Create your tests here.
--- /dev/null
+from __future__ import unicode_literals
+
+import django.views.i18n
+from django.conf.urls import patterns, include, url
+from django.conf.urls.i18n import i18n_patterns
+
+from mezzanine.core.views import direct_to_template
+from mezzanine.conf import settings
+
+from organization.team.views import *
+
+
+urlpatterns = [
+
+]
--- /dev/null
+from django.shortcuts import render
+
+# Create your views here.
--- /dev/null
+from __future__ import unicode_literals
+
+import django.views.i18n
+from django.conf.urls import patterns, include, url
+from django.conf.urls.i18n import i18n_patterns
+from django.contrib import admin
+
+admin.autodiscover()
+
+from mezzanine.core.views import direct_to_template
+from mezzanine.conf import settings
+
+
+urlpatterns = [
+ url("^", include('organization.core.urls')),
+ url("^festival/", include('organization.festival.urls')),
+ url("^magazine/", include('organization.magazine.urls')),
+ url("^media/", include('organization.media.urls')),
+ url("^project/", include('organization.project.urls')),
+ url("^team/", include('organization.team.urls')),
+]
AUTHENTICATION_BACKENDS = ("mezzanine.core.auth_backends.MezzanineBackend",)
-# The numeric mode to set newly-uploaded files to. The value should be
-# a mode you'd pass directly to os.chmod.
-FILE_UPLOAD_PERMISSIONS = 0o644
-
-# MAX_UPLOAD_SIZE = 429916160
#############
# DATABASES #
"mezzanine.core",
"mezzanine.generic",
"mezzanine.pages",
- "custom",
"mezzanine.blog",
"mezzanine.forms",
"mezzanine.galleries",
'djangobower',
"meta",
"mezzanine_agenda",
- "festival",
- "organization"
+ "organization.core",
+ "organization.team",
+ "organization.festival",
+ "organization.magazine",
+ "organization.media",
+ "organization.project",
+ "organization.featured",
]
}
MODELTRANSLATION_TRANSLATION_FILES = (
- 'custom.translations',
- 'translations',
+ 'organization.core.translation',
+ 'organization.festival.translation',
+ 'organization.magazine.translation'
)
TEMPLATES = [{'APP_DIRS': True,
# Uncomment the following if using any of the SSL settings:
# "mezzanine.core.middleware.SSLRedirectMiddleware",
"mezzanine.pages.middleware.PageMiddleware",
- "mezzanine.core.middleware.FetchFromCacheMiddleware",
+ # "mezzanine.core.middleware.FetchFromCacheMiddleware",
)
# Store these package names here as they may change in the future since
{% 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 %}
--- /dev/null
+{% extends "base.html" %}
+{% load i18n mezzanine_tags keyword_tags featured_tags %}
+
+{% block meta_title %}{{ page.meta_title }}{% endblock %}
+
+{% block meta_keywords %}{% metablock %}
+{% keywords_for page as keywords %}
+{% for keyword in keywords %}
+ {% if not forloop.first %}, {% endif %}
+ {{ keyword }}
+{% endfor %}
+{% endmetablock %}{% endblock %}
+
+{% block meta_description %}{% metablock %}
+{{ page.description }}
+{% endmetablock %}{% endblock %}
+
+{% block title %}
+ {% editable page.title %}
+ {{ page.title }}
+ {% endeditable %}
+
+ {% editable page.basicpage.sub_title %}
+ {{ page.basicpage.sub_title }}
+ {% endeditable %}
+{% endblock %}
+
+{% block main %}
+
+ {% editable page.basicpage.content %}
+ {{ page.basicpage.content|richtext_filters|safe }}
+ {% endeditable %}
+
+ <br/>
+ <br/>
+ <br/>
+ <br/>
+
+ {{ page.basicpage.photo }}<br/>
+ {{ page.basicpage.photo_credits }}<br/>
+ {{ page.basicpage.photo_alignment }}<br/>
+ {{ page.basicpage.photo_description }}<br/>
+ {{ page.basicpage.photo_featured }}<br/>
+ {{ page.basicpage.photo_featured_credits }}<br/>
+{% 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" %}
urlpatterns += [
- url(r'^festival/', include('festival.urls')),
+ # App urls
+
+ url("^", include('organization.urls')),
url("^%s/" % settings.EVENT_SLUG, include("mezzanine_agenda.urls")),
+ url("^styles/$", direct_to_template, {"template": "styles.html"}, name="styles"),
# We don't want to presume how your homepage works, so here are a
# few patterns you can use to set it up.
# one homepage pattern, so if you use a different one, comment this
# one out.
- url("^styles/$", direct_to_template, {"template": "styles.html"}, name="styles"),
- url("^$", direct_to_template, {"template": "index.html"}, name="home"),
+ # url("^$", direct_to_template, {"template": "index.html"}, name="home"),
# HOMEPAGE AS AN EDITABLE PAGE IN THE PAGE TREE
# ---------------------------------------------
-e git+https://github.com/yomguy/mezzanine-agenda.git#egg=mezzanine-agenda-0.2.2
-e git+https://github.com/stephenmcd/mezzanine.git#egg=mezzanine-4.1-dev
+-e git+https://github.com/stephenmcd/grappelli-safe#egg=grappelli-safe-0.4.2
#https://forge.ircam.fr/p/django-eve/source/download/dev/
#
#
django-bower
django-debug-toolbar
django-extensions
+django-countries
#!/bin/bash
-mysqldump -hdb -uroot -phyRob0otlaz4 ircam-www | gzip > /srv/backup/ircam-www.sql.gz
+export PGPASSWORD=$POSTGRES_PASSWORD
+
+pg_dump -Fc -hdb -Upostgres -dpostgres > /srv/backup/ircam-www.dump
+
echo "Backup done!"
--- /dev/null
+#!/bin/sh
+
+docker-compose run app /srv/app/manage.py makemigrations
--- /dev/null
+#!/bin/sh
+
+docker-compose run app /srv/app/manage.py migrate
#!/bin/bash
-gunzip < /srv/backup/ircam-www.sql.gz | mysql -hdb -uroot -phyRob0otlaz4 ircam-www
+export PGPASSWORD=$POSTGRES_PASSWORD
+
+pg_restore --clean -Fc -hdb -Upostgres -d postgres /srv/backup/ircam-www.dump
+
echo "Restore done!"