wsgi=$app'/wsgi.py'
static='/srv/static/'
media='/srv/media/'
+src='/srv/src/'
# uwsgi params
port=8000
gid='www-data'
# Staging
-pip install psycopg2
+# pip install psycopg2
chown -R $uid:$gid $media
sh $app/deploy/wait.sh
# waiting for available database
-python $app/wait.py
+# python $app/wait.py
# python $manage wait-for-db-connection
# django init
# static files auto update
watchmedo shell-command --patterns="*.js;*.css" --recursive \
- --command='python '$manage' collectstatic --noinput' $static &
+ --command='python '$manage' collectstatic --noinput' $src &
# app start
-uwsgi --socket :$port --wsgi-file $wsgi --chdir $app --master \
+if [ $1 = "--runserver" ]
+then
+ python $manage runserver 0.0.0.0:9000
+else
+ uwsgi --socket :$port --wsgi-file $wsgi --chdir $app --master \
--processes $processes --threads $threads \
--uid $uid --gid $gid \
--py-autoreload $autoreload
+fi
+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 festival.models import *
-admin.site.register(Event)
-admin.site.register(Artist)
-admin.site.register(Location)
-admin.site.register(Video)
+
+class FestivalEventInline(admin.StackedInline):
+ model = FestivalEvent
+ extra = 1
+
+
+class FestivalEventAdmin(EventAdmin):
+ """
+ Admin class for events.
+ """
+
+ inlines = [FestivalEventInline, ]
+
+
+class ArtistAdmin(admin.ModelAdmin):
+
+ model = Artist
+
+
+class VideoAdmin(admin.ModelAdmin):
+
+ model = Video
+
+
+class VideoAdminDisplayable(DisplayableAdmin):
+
+ fieldsets = deepcopy(VideoAdmin.fieldsets)
+
+
+class ArtistAdminDisplayable(DisplayableAdmin):
+ """
+ Admin class for artists.
+ """
+
+ fieldsets = deepcopy(ArtistAdmin.fieldsets)
+
+
+ def save_form(self, request, form, change):
+ """
+ Super class ordering is important here - user must get saved first.
+ """
+ return DisplayableAdmin.save_form(self, request, form, change)
+
+
+admin.site.unregister(Event)
+admin.site.register(Event, FestivalEventAdmin)
+
+admin.site.register(Artist, ArtistAdminDisplayable)
+admin.site.register(Video, VideoAdminDisplayable)
+++ /dev/null
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('sites', '0001_initial'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='Artist',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('name', models.CharField(max_length=255, verbose_name='name')),
- ('photo', models.ImageField(upload_to=b'photos/%Y/%m/%d', max_length=1024, verbose_name='photo')),
- ],
- ),
- migrations.CreateModel(
- name='Event',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('keywords_string', models.CharField(max_length=500, editable=False, blank=True)),
- ('title', models.CharField(max_length=500, verbose_name='Title')),
- ('slug', models.CharField(help_text='Leave blank to have the URL auto-generated from the title.', max_length=2000, null=True, verbose_name='URL', blank=True)),
- ('_meta_title', models.CharField(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', blank=True)),
- ('description', models.TextField(verbose_name='Description', blank=True)),
- ('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(null=True, editable=False)),
- ('updated', models.DateTimeField(null=True, editable=False)),
- ('status', models.IntegerField(default=2, help_text='With Draft chosen, will only be shown for admin users on the site.', verbose_name='Status', choices=[(1, 'Draft'), (2, 'Published')])),
- ('publish_date', models.DateTimeField(help_text="With Published chosen, won't be shown until this time", null=True, verbose_name='Published from', db_index=True, blank=True)),
- ('expiry_date', models.DateTimeField(help_text="With Published chosen, won't be shown after this time", null=True, verbose_name='Expires on', blank=True)),
- ('short_url', models.URLField(null=True, blank=True)),
- ('in_sitemap', models.BooleanField(default=True, verbose_name='Show in sitemap')),
- ('event_id', models.IntegerField()),
- ('artists', models.ManyToManyField(related_name='events', null=True, verbose_name='events', to='festival.Artist', blank=True)),
- ('site', models.ForeignKey(editable=False, to='sites.Site')),
- ],
- options={
- 'db_table': 'event',
- 'verbose_name': 'event',
- },
- ),
- migrations.CreateModel(
- name='Location',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('location_id', models.IntegerField()),
- ],
- ),
- migrations.CreateModel(
- name='Video',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('keywords_string', models.CharField(max_length=500, editable=False, blank=True)),
- ('title', models.CharField(max_length=500, verbose_name='Title')),
- ('slug', models.CharField(help_text='Leave blank to have the URL auto-generated from the title.', max_length=2000, null=True, verbose_name='URL', blank=True)),
- ('_meta_title', models.CharField(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', blank=True)),
- ('description', models.TextField(verbose_name='Description', blank=True)),
- ('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(null=True, editable=False)),
- ('updated', models.DateTimeField(null=True, editable=False)),
- ('status', models.IntegerField(default=2, help_text='With Draft chosen, will only be shown for admin users on the site.', verbose_name='Status', choices=[(1, 'Draft'), (2, 'Published')])),
- ('publish_date', models.DateTimeField(help_text="With Published chosen, won't be shown until this time", null=True, verbose_name='Published from', db_index=True, blank=True)),
- ('expiry_date', models.DateTimeField(help_text="With Published chosen, won't be shown after this time", null=True, verbose_name='Expires on', blank=True)),
- ('short_url', models.URLField(null=True, blank=True)),
- ('in_sitemap', models.BooleanField(default=True, verbose_name='Show in sitemap')),
- ('media_id', models.IntegerField(verbose_name='media ID')),
- ('artists', models.ManyToManyField(related_name='videos', null=True, verbose_name='artists', to='festival.Artist', blank=True)),
- ('site', models.ForeignKey(editable=False, to='sites.Site')),
- ],
- options={
- 'abstract': False,
- },
- ),
- ]
+++ /dev/null
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('festival', '0001_initial'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='event',
- name='artists',
- field=models.ManyToManyField(related_name='events', verbose_name='events', to='festival.Artist', blank=True),
- ),
- migrations.AlterField(
- model_name='video',
- name='artists',
- field=models.ManyToManyField(related_name='videos', verbose_name='artists', to='festival.Artist', blank=True),
- ),
- ]
+++ /dev/null
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-import mezzanine.core.fields
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('festival', '0002_auto_20160201_2339'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='artist',
- name='content',
- field=mezzanine.core.fields.RichTextField(default='', verbose_name='Content'),
- preserve_default=False,
- ),
- ]
+++ /dev/null
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-import mezzanine.core.fields
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('festival', '0003_artist_content'),
- ]
-
- operations = [
- migrations.RemoveField(
- model_name='artist',
- name='content',
- ),
- migrations.AddField(
- model_name='artist',
- name='bio',
- field=mezzanine.core.fields.RichTextField(null=True, verbose_name='bio', blank=True),
- ),
- ]
+++ /dev/null
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('festival', '0004_auto_20160202_0002'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='artist',
- name='photo_credits',
- field=models.CharField(max_length=255, null=True, verbose_name='photo credits', blank=True),
- ),
- migrations.AlterField(
- model_name='event',
- name='artists',
- field=models.ManyToManyField(related_name='events', verbose_name='artists', to='festival.Artist', blank=True),
- ),
- ]
from django.utils.translation import ugettext_lazy as _
from mezzanine.core.models import RichText, Displayable
-from mezzanine.core.fields import RichTextField, OrderField
+from mezzanine.core.fields import RichTextField, OrderField, FileField
+from mezzanine.utils.models import AdminThumbMixin, upload_to
-import eve.models
+from mezzanine_agenda.models import Event
+
+# import eve.models
from .related import SpanningForeignKey
+app_label = 'festival'
+
class MetaCore:
app_label = 'festival'
-class Event(Displayable):
- """(Event description)"""
+class BaseNameModel(models.Model):
+ """Base object with name and description"""
- event_id = models.IntegerField()
- # event = SpanningForeignKey(eve.models.EventVersion, related_name='festival_events', verbose_name=_('E-venement event'), blank=True, null=True, default=None)
- rich_description = RichText(_('rich description'))
- artists = models.ManyToManyField('Artist', related_name='events', verbose_name=_('artists'), blank=True)
+ name = models.CharField(_('name'), max_length=512)
+ description = models.TextField(_('description'), blank=True)
class Meta(MetaCore):
- verbose_name = _('event')
- db_table = 'event'
+ 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(MetaCore):
+ abstract = True
def __unicode__(self):
return self.title
-class Artist(models.Model):
- """(Artist description)"""
+class FestivalEvent(models.Model):
+ """Extensible event metadata"""
+
+ event = models.ForeignKey(Event, related_name='festival_events', verbose_name=_('festival event'), blank=True, null=True, on_delete=models.SET_NULL)
+ #eve_event = SpanningForeignKey(eve.models.EventVersion, related_name='festival_events', verbose_name=_('E-venement event'), blank=True, null=True, default=None)
+ eve_event_id = models.IntegerField(_('eve id'), blank=True)
+ category = models.ForeignKey('EventCategory', related_name='festival_events', verbose_name=_('category'), blank=True, null=True, on_delete=models.SET_NULL)
+ artists = models.ManyToManyField('Artist', related_name='metaevents', verbose_name=_('artists'), blank=True)
+ featured = models.BooleanField(_('featured'), default=False)
+ featured_image = FileField(_('featured image'), upload_to='images/%Y/%m/%d', max_length=1024, blank=True, format="Image")
+ featured_image_header = FileField(_('featured image header'), upload_to='images/%Y/%m/%d', max_length=1024, blank=True, format="Image")
+
+ class Meta(MetaCore):
+ verbose_name = _('festival event')
+ db_table = app_label + '_events'
+
+ def __unicode__(self):
+ return self.event.title
+
+
+class Artist(Displayable, RichText, AdminThumbMixin):
+ """Artist"""
- name = models.CharField(_('name'), max_length=255)
- photo = models.ImageField(_('photo'), upload_to='photos/%Y/%m/%d', max_length=1024)
+ bio = RichTextField(_('biography'), blank=True)
+ photo = FileField(_('photo'), upload_to='images/%Y/%m/%d', max_length=1024, blank=True, format="Image")
photo_credits = models.CharField(_('photo credits'), max_length=255, blank=True, null=True)
- bio = RichTextField(_("bio"), blank=True, null=True)
+ featured = models.BooleanField(_('featured'), default=False)
search_fields = ("name", "bio")
def __unicode__(self):
return self.name
+ class Meta(MetaCore):
+ verbose_name = _('artist')
+ db_table = app_label + '_artists'
-class Video(Displayable):
- """(Video description)"""
- media_id = models.IntegerField(_('media ID'))
- artists = models.ManyToManyField('Artist', related_name='videos', verbose_name=_('artists'), blank=True)
+class Video(Displayable, RichText):
+ """Video"""
+
+ event = models.ForeignKey(Event, related_name='videos', verbose_name=_('event'), blank=True, null=True, on_delete=models.SET_NULL)
+ media_id = models.IntegerField(_('media id'))
def __unicode__(self):
- return u"Video"
+ return
-class Location(models.Model):
- """(Location description)"""
+class EventCategory(BaseNameModel):
+ """Event Category"""
- location_id = models.IntegerField()
+ class Meta(MetaCore):
+ verbose_name = _('event category')
- def __unicode__(self):
- return u"Location"
+
+class PageCategory(BaseNameModel):
+ """Page Category"""
+
+ class Meta(MetaCore):
+ verbose_name = _('page category')
+
+
+
+#class Article ?
import os
+from django.utils.translation import ugettext_lazy as _
DEBUG = True
NEVERCACHE_KEY = "l11tr%#!uc@+%$51(&+%=&z6h9yrw42(jpcj$3_&6evtu6hl%z"
# DATABASE_ROUTERS = ['eve.routers.EveRouter', 'festival.routers.FestivalRouter',]
-DATABASE_ROUTERS = ['eve.routers.EveRouter',]
+# DATABASE_ROUTERS = ['eve.routers.EveRouter',]
DATABASES = {
'default': {
SITE_TAGLINE = 'Festival 2 juin | 2 juillet 2016'
SILENCED_SYSTEM_CHECKS = ['fields.W342',]
+
+EVENT_USE_FEATURED_IMAGE = True
+
+ADMIN_MENU_ORDER = (
+ (_("Content"), ("pages.Page", "blog.BlogPost", "mezzanine_agenda.Event",
+ "festival.Artist", "festival.Video",
+ "generic.ThreadedComment", (_("Media Library"), "fb_browse"),)),
+ (_("Site"), ("sites.Site", "redirects.Redirect", "conf.Setting")),
+ (_("Users"), ("auth.User", "auth.Group",)),
+)
# MAX_UPLOAD_SIZE = 429916160
+EVENT_SLUG = 'events'
+
#############
# DATABASES #
#############
################
INSTALLED_APPS = [
+ "modeltranslation",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
# "eve",
"festival",
"meta",
+ 'mezzanine_agenda',
]
# Add Migration Module path see : https://github.com/stephenmcd/mezzanine/blob/master/docs/model-customization.rst#field-injection-caveats
"galleries": "migrations.galleries",
"pages": "migrations.pages",
"conf": "migrations.conf",
+ "mezzanine_agenda": "migrations.mezzanine_agenda",
}
+MODELTRANSLATION_TRANSLATION_FILES = (
+ 'translations',
+)
+
# List of processors used by RequestContext to populate the context.
# Each one should be a callable that takes the request object as its
# only parameter and returns a dictionary to add to the context.
)
urlpatterns += patterns('',
- (r'^festival/', include('festival.urls')),
+ url(r'^festival/', include('festival.urls')),
+ url("^%s/" % settings.EVENT_SLUG, include("mezzanine_agenda.urls")),
# We don't want to presume how your homepage works, so here are a
# few patterns you can use to set it up.
<div class="container">
<div class="row">
-<div class="col-md-2 left">
- {% block left_panel %}
- <div class="panel panel-default tree">{% page_menu "pages/menus/tree.html" %}</div>
- {% endblock %}
-</div>
-
-<div class="col-md-7 middle">
+<div class="col-md-9 left">
{% block main %}{% endblock %}
</div>
except:
print 'waiting...'
time.sleep(10)
- call_command('syncdb', interactive=False)
app:
build: .
- command: /bin/sh deploy/start_app.sh
+ command: /bin/sh deploy/start_app.sh --runserver
+ ports:
+ - "9000:9000"
volumes:
- ./app/:/srv/app
volumes_from:
-mezzanine-agenda
-mezzanine_people
---index-url https://pypi.python.org/simple/
-
setuptools
uwsgi
watchdog
MySQL-python==1.2.5
-Django==1.8.7
+Django==1.8.9
+
mezzanine==4.0.1
django-modeltranslation
django-meta
psycopg2
+mezzanine-agenda