From: Guillaume Pellerin Date: Tue, 22 Dec 2015 18:46:35 +0000 (+0100) Subject: first build and import X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=af457191c59eee8ddeee9c917d5072359166a471;p=mezzo.git first build and import --- af457191c59eee8ddeee9c917d5072359166a471 diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..45ccb85f --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +*.py[co] +*~ + +# Packages +*.egg +*.egg-info +#dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg +*.directory +data + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +#*.mo + +#Mr Developer +.mr.developer.cfg diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..ddcf70c0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +FROM python:2.7 + +ENV PYTHONUNBUFFERED 1 + +RUN apt-get update &&\ + apt-get -y install locales netcat && \ + echo fr_FR.UTF-8 UTF-8 >> /etc/locale.gen &&\ + locale-gen + +ENV LANG fr_FR.UTF-8 +ENV LANGUAGE fr_FR:fr +ENV LC_ALL fr_FR.UTF-8 + +RUN mkdir /srv/app +RUN mkdir /srv/src +WORKDIR /srv/app + +ADD requirements.txt /srv/app/ +RUN pip install -r requirements.txt + +ADD requirements-dev.txt /srv/app/ +# RUN pip install -r requirements-dev.txt --src /srv/src diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/app/deploy/crontab.template b/app/deploy/crontab.template new file mode 100644 index 00000000..c4af8cf2 --- /dev/null +++ b/app/deploy/crontab.template @@ -0,0 +1,3 @@ +# Poll Twitter every 5 minutes +# Comment-out if you don't use Mezzanine's Twitter app +*/5 * * * * %(user)s %(manage)s poll_twitter diff --git a/app/deploy/gunicorn.conf.py.template b/app/deploy/gunicorn.conf.py.template new file mode 100644 index 00000000..257bb979 --- /dev/null +++ b/app/deploy/gunicorn.conf.py.template @@ -0,0 +1,8 @@ +from __future__ import unicode_literals +import multiprocessing + +bind = "unix:%(proj_path)s/gunicorn.sock" +workers = %(num_workers)s +errorlog = "/home/%(user)s/logs/%(proj_name)s_error.log" +loglevel = "error" +proc_name = "%(proj_name)s" diff --git a/app/deploy/local_settings.py.template b/app/deploy/local_settings.py.template new file mode 100644 index 00000000..d8dc9a06 --- /dev/null +++ b/app/deploy/local_settings.py.template @@ -0,0 +1,37 @@ +from __future__ import unicode_literals + +SECRET_KEY = "%(secret_key)s" +NEVERCACHE_KEY = "%(nevercache_key)s" +ALLOWED_HOSTS = [%(domains_python)s] + +DATABASES = { + "default": { + # Ends with "postgresql_psycopg2", "mysql", "sqlite3" or "oracle". + "ENGINE": "django.db.backends.postgresql_psycopg2", + # DB name or path to database file if using sqlite3. + "NAME": "%(proj_name)s", + # Not used with sqlite3. + "USER": "%(proj_name)s", + # Not used with sqlite3. + "PASSWORD": "%(db_pass)s", + # Set to empty string for localhost. Not used with sqlite3. + "HOST": "127.0.0.1", + # Set to empty string for default. Not used with sqlite3. + "PORT": "", + } +} + +SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTOCOL", "https") + +CACHE_MIDDLEWARE_SECONDS = 60 + +CACHE_MIDDLEWARE_KEY_PREFIX = "%(proj_name)s" + +CACHES = { + "default": { + "BACKEND": "django.core.cache.backends.memcached.MemcachedCache", + "LOCATION": "127.0.0.1:11211", + } +} + +SESSION_ENGINE = "django.contrib.sessions.backends.cache" diff --git a/app/deploy/nginx-app.conf b/app/deploy/nginx-app.conf new file mode 100644 index 00000000..4aaec53a --- /dev/null +++ b/app/deploy/nginx-app.conf @@ -0,0 +1,27 @@ +server_tokens off; + +server { + listen 80; + server_name nginx; + charset utf-8; + + access_log /var/log/nginx/app-access.log; + error_log /var/log/nginx/app-error.log; + + # max upload size + client_max_body_size 4096M; # adjust to taste + + # Django media + location /media { + alias /srv/media; # your Django project's media files - amend as required + } + # Django static + location /static { + alias /srv/static; # your Django project's static files - amend as required + } + + location / { + uwsgi_pass app:8000; + include /etc/nginx/uwsgi_params; + } +} diff --git a/app/deploy/nginx.conf.template b/app/deploy/nginx.conf.template new file mode 100644 index 00000000..f99430af --- /dev/null +++ b/app/deploy/nginx.conf.template @@ -0,0 +1,55 @@ + +upstream %(proj_name)s { + server unix:%(proj_path)s/gunicorn.sock fail_timeout=0; +} + +server { + + listen 80; + %(ssl_disabled)s listen 443 ssl; + server_name %(domains_nginx)s; + client_max_body_size 10M; + keepalive_timeout 15; + error_log /home/%(user)s/logs/%(proj_name)s_error_nginx.log info; + + %(ssl_disabled)s ssl_certificate conf/%(proj_name)s.crt; + %(ssl_disabled)s ssl_certificate_key conf/%(proj_name)s.key; + %(ssl_disabled)s ssl_session_cache shared:SSL:10m; + %(ssl_disabled)s ssl_session_timeout 10m; + %(ssl_disabled)s ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA; + %(ssl_disabled)s ssl_prefer_server_ciphers on; + + # Deny illegal Host headers + if ($host !~* ^(%(domains_regex)s)$) { + return 444; + } + + location / { + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_pass http://%(proj_name)s; + } + + location /static/ { + root %(proj_path)s; + access_log off; + log_not_found off; + expires 30d; + } + + location /robots.txt { + root %(proj_path)s/static; + access_log off; + log_not_found off; + } + + location /favicon.ico { + root %(proj_path)s/static/img; + access_log off; + log_not_found off; + } + +} diff --git a/app/deploy/start_app-dev.sh b/app/deploy/start_app-dev.sh new file mode 100644 index 00000000..afa1a684 --- /dev/null +++ b/app/deploy/start_app-dev.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +# paths +root='/opt/' +sandbox=$root'app/' +manage=$sandbox'manage.py' +wsgi=$sandbox'wsgi.py' +static=$root'static/' +media=$root'media/' + +# waiting for other services +sh $sandbox/deploy/wait.sh + +# django init +python $manage migrate --noinput +python $manage collectstatic --noinput + +# static files auto update +watchmedo shell-command --patterns="*.js;*.css" --recursive \ + --command='python '$manage' collectstatic --noinput' $sandbox & + +# app start +uwsgi --socket :8000 --wsgi-file $wsgi --chdir $sandbox --master --processes 4 --threads 2 --py-autoreload 3 + +#python $manage runserver 0.0.0.0:8000 diff --git a/app/deploy/start_app.sh b/app/deploy/start_app.sh new file mode 100644 index 00000000..809c27d7 --- /dev/null +++ b/app/deploy/start_app.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +# paths +app='/srv/app' +manage=$app'/manage.py' +wsgi=$app'/wsgi.py' +static='/srv/static/' + +# uwsgi params +port=8000 +processes=2 +threads=2 +autoreload=3 + +# waiting for other services +sh $app/deploy/wait.sh + +if [ ! -f $app/.init ]; then + python $manage telemeta-create-admin-user + python $manage telemeta-create-boilerplate + python $manage update_index --workers $processes + touch $app/.init +fi + +# django init +python $manage makemigrations --noinput +python $manage migrate --noinput +python $manage collectstatic --noinput + +# static files auto update +watchmedo shell-command --patterns="*.js;*.css" --recursive \ + --command='python '$manage' collectstatic --noinput' $static & + +# app start +uwsgi --socket :$port --wsgi-file $wsgi --chdir $app --master \ + --processes $processes --threads $threads --py-autoreload $autoreload diff --git a/app/deploy/supervisor.conf.template b/app/deploy/supervisor.conf.template new file mode 100644 index 00000000..5f48e9b3 --- /dev/null +++ b/app/deploy/supervisor.conf.template @@ -0,0 +1,9 @@ +[program:gunicorn_%(proj_name)s] +command=%(venv_path)s/bin/gunicorn -c gunicorn.conf.py -p gunicorn.pid %(proj_app)s.wsgi:application +directory=%(proj_path)s +user=%(user)s +autostart=true +stdout_logfile = /home/%(user)s/logs/%(proj_name)s_supervisor +autorestart=true +redirect_stderr=true +environment=LANG="%(locale)s",LC_ALL="%(locale)s",LC_LANG="%(locale)s" diff --git a/app/deploy/wait.sh b/app/deploy/wait.sh new file mode 100644 index 00000000..02289edf --- /dev/null +++ b/app/deploy/wait.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +# apt-get install -y --force-yes netcat + +set -e + +host=$(env | grep _TCP_ADDR | cut -d = -f 2) +port=$(env | grep _TCP_PORT | cut -d = -f 2) + +echo -n "waiting for TCP connection to $host:$port..." + +while ! nc -w 1 $host $port 2>/dev/null +do + echo -n . + sleep 1 +done + +echo 'ok' diff --git a/app/manage.py b/app/manage.py new file mode 100755 index 00000000..e9d335d4 --- /dev/null +++ b/app/manage.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + + from mezzanine.utils.conf import real_project_name + + settings_module = "%s.settings" % real_project_name("manifeste") + os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings_module) + + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv) diff --git a/app/manifeste/__init__.py b/app/manifeste/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/app/manifeste/local_settings.py b/app/manifeste/local_settings.py new file mode 100644 index 00000000..99f7507a --- /dev/null +++ b/app/manifeste/local_settings.py @@ -0,0 +1,49 @@ +import os + +DEBUG = True + +# Make these unique, and don't share it with anybody. +SECRET_KEY = "+3b01&_6_m@@yb4f06$s0zno8vkybh81nbuj_q(xzk+xeih1+s" +NEVERCACHE_KEY = "l11tr%#!uc@+%$51(&+%=&z6h9yrw42(jpcj$3_&6evtu6hl%z" + +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. + } +} + +# EXTENSIONS AND FORMATS +# Allowed Extensions for File Upload. Lower case is important. +FILEBROWSER_EXTENSIONS = { + 'Folder': [''], + 'Image': ['.jpg', '.jpeg', '.gif', '.png', '.tif', '.tiff'], + 'Document': ['.pdf', '.doc', '.rtf', '.txt', '.xls', '.csv', '.docx'], + 'Video': ['.mov', '.wmv', '.mpeg', '.mpg', '.avi', '.rm'], + 'Audio': ['.mp3', '.mp4', '.wav', '.aiff', '.midi', '.m4p'] + } + +# Define different formats for allowed selections. +# This has to be a subset of EXTENSIONS. +# e.g., add ?type=image to the browse-URL ... +FILEBROWSER_SELECT_FORMATS = { + 'File': ['Folder', 'Document'], + 'Image': ['Image'], + 'Media': ['Video', 'Audio'], + 'Audio': ['Audio'], + 'Document': ['Document'], + # for TinyMCE we can also define lower-case items + 'image': ['Image'], + 'file': ['Folder', 'Image', 'Document'], + 'media': ['Video', 'Audio'], + 'audio': ['Audio'], +} + +EMAIL_HOST = 'smtp.ircam.fr' +EMAIL_PORT = '25' +DEFAULT_FROM_EMAIL = 'manifeste2016@ircam.fr' +EMAIL_SUBJECT_PREFIX = "IRCAM Manifeste 2016" diff --git a/app/manifeste/migrations/__init__.py b/app/manifeste/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/app/manifeste/settings.py b/app/manifeste/settings.py new file mode 100644 index 00000000..48596778 --- /dev/null +++ b/app/manifeste/settings.py @@ -0,0 +1,309 @@ + +from __future__ import absolute_import, unicode_literals +import os +from django.utils.translation import ugettext_lazy as _ + +###################### +# MEZZANINE SETTINGS # +###################### + +# The following settings are already defined with default values in +# the ``defaults.py`` module within each of Mezzanine's apps, but are +# common enough to be put here, commented out, for conveniently +# overriding. Please consult the settings documentation for a full list +# of settings Mezzanine implements: +# http://mezzanine.jupo.org/docs/configuration.html#default-settings + +# Controls the ordering and grouping of the admin menu. +# +# ADMIN_MENU_ORDER = ( +# ("Content", ("pages.Page", "blog.BlogPost", +# "generic.ThreadedComment", (_("Media Library"), "fb_browse"),)), +# (_("Shop"), ("shop.Product", "shop.ProductOption", "shop.DiscountCode", +# "shop.Sale", "shop.Order")), +# ("Site", ("sites.Site", "redirects.Redirect", "conf.Setting")), +# ("Users", ("auth.User", "auth.Group",)), +# ) + +# A three item sequence, each containing a sequence of template tags +# used to render the admin dashboard. +# +# DASHBOARD_TAGS = ( +# ("blog_tags.quick_blog", "mezzanine_tags.app_list"), +# ("comment_tags.recent_comments",), +# ("mezzanine_tags.recent_actions",), +# ) + +# A sequence of templates used by the ``page_menu`` template tag. Each +# item in the sequence is a three item sequence, containing a unique ID +# for the template, a label for the template, and the template path. +# These templates are then available for selection when editing which +# menus a page should appear in. Note that if a menu template is used +# that doesn't appear in this setting, all pages will appear in it. + +PAGE_MENU_TEMPLATES = ( + (1, _("Top navigation bar"), "pages/menus/dropdown.html"), + # (2, _("Left-hand tree"), "pages/menus/tree.html"), + # (3, _("Footer"), "pages/menus/footer.html"), +) + +# A sequence of fields that will be injected into Mezzanine's (or any +# library's) models. Each item in the sequence is a four item sequence. +# The first two items are the dotted path to the model and its field +# name to be added, and the dotted path to the field class to use for +# the field. The third and fourth items are a sequence of positional +# args and a dictionary of keyword args, to use when creating the +# field instance. When specifying the field class, the path +# ``django.models.db.`` can be omitted for regular Django model fields. +# + +EXTRA_MODEL_FIELDS = ( + ) + +# Setting to turn on featured images for blog posts. Defaults to False. +# +BLOG_USE_FEATURED_IMAGE = True + +# If True, the django-modeltranslation will be added to the +# INSTALLED_APPS setting. +USE_MODELTRANSLATION = True + +# SEARCH_MODEL_CHOICES = ('shop.Product',) + +COMMENTS_ACCOUNT_REQUIRED = True + +######################## +# MAIN DJANGO SETTINGS # +######################## + +# Hosts/domain names that are valid for this site; required if DEBUG is False +# See https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts +ALLOWED_HOSTS = ['*'] + +# Local time zone for this installation. Choices can be found here: +# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name +# although not all choices may be available on all operating systems. +# On Unix systems, a value of None will cause Django to use the same +# timezone as the operating system. +# If running in a Windows environment this must be set to the same as your +# system time zone. +TIME_ZONE = 'Europe/Paris' + +# If you set this to True, Django will use timezone-aware datetimes. +USE_TZ = True + +# Language code for this installation. All choices can be found here: +# http://www.i18nguy.com/unicode/language-identifiers.html +LANGUAGE_CODE = "en" + +# Supported languages +LANGUAGES = ( + ('fr', _('French')), + ('en', _('English')), +) + +# A boolean that turns on/off debug mode. When set to ``True``, stack traces +# are displayed for error pages. Should always be set to ``False`` in +# production. Best set to ``True`` in local_settings.py +DEBUG = False + +# Whether a user's session cookie expires when the Web browser is closed. +SESSION_EXPIRE_AT_BROWSER_CLOSE = True + +SITE_ID = 1 + +# If you set this to False, Django will make some optimizations so as not +# to load the internationalization machinery. +USE_I18N = True + +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 # +############# + +DATABASES = { + "default": { + # Ends with "postgresql_psycopg2", "mysql", "sqlite3" or "oracle". + "ENGINE": "django.db.backends.sqlite3", + # DB name or path to database file if using sqlite3. + "NAME": "dev.db", + # Not used with sqlite3. + "USER": "", + # Not used with sqlite3. + "PASSWORD": "", + # Set to empty string for localhost. Not used with sqlite3. + "HOST": "", + # Set to empty string for default. Not used with sqlite3. + "PORT": "", + } +} + +######### +# PATHS # +######### + +# Full filesystem path to the project. +PROJECT_APP_PATH = os.path.dirname(os.path.abspath(__file__)) +PROJECT_APP = os.path.basename(PROJECT_APP_PATH) +PROJECT_ROOT = BASE_DIR = os.path.dirname(PROJECT_APP_PATH) + +# Every cache key will get prefixed with this value - here we set it to +# the name of the directory the project is in to try and use something +# project specific. +CACHE_MIDDLEWARE_KEY_PREFIX = PROJECT_APP + +# URL prefix for static files. +# Example: "http://media.lawrence.com/static/" +STATIC_URL = "/static/" + +# Absolute path to the directory static files should be collected to. +# Don't put anything in this directory yourself; store your static files +# in apps' "static/" subdirectories and in STATICFILES_DIRS. +# Example: "/home/media/media.lawrence.com/static/" +# STATIC_ROOT = os.path.join(PROJECT_ROOT, STATIC_URL.strip("/")) +STATIC_ROOT = '/srv/static/' + +# URL that handles the media served from MEDIA_ROOT. Make sure to use a +# trailing slash. +# Examples: "http://media.lawrence.com/media/", "http://example.com/media/" +MEDIA_URL = "/media/" + +# Absolute filesystem path to the directory that will hold user-uploaded files. +# Example: "/home/media/media.lawrence.com/media/" +# MEDIA_ROOT = os.path.join(PROJECT_ROOT, *MEDIA_URL.strip("/").split("/")) +MEDIA_ROOT = '/srv/media/' + +# Package/module name to import the root urlpatterns from for the project. +ROOT_URLCONF = "%s.urls" % PROJECT_APP + +# Put strings here, like "/home/html/django_templates" +# or "C:/www/django/templates". +# Always use forward slashes, even on Windows. +# Don't forget to use absolute paths, not relative paths. +TEMPLATE_DIRS = (os.path.join(PROJECT_ROOT, "templates"),) + + +################ +# APPLICATIONS # +################ + +INSTALLED_APPS = ( + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.redirects", + "django.contrib.sessions", + "django.contrib.sites", + "django.contrib.sitemaps", + "django.contrib.staticfiles", + "mezzanine.boot", + "mezzanine.conf", + "mezzanine.core", + "mezzanine.generic", + "mezzanine.pages", + "mezzanine.blog", + "mezzanine.forms", + "mezzanine.galleries", + "mezzanine.twitter", + "mezzanine.accounts", + # "mezzanine.mobile", +) + +# 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. +TEMPLATE_CONTEXT_PROCESSORS = ( + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + "django.core.context_processors.debug", + "django.core.context_processors.i18n", + "django.core.context_processors.static", + "django.core.context_processors.media", + "django.core.context_processors.request", + "django.core.context_processors.tz", + "mezzanine.conf.context_processors.settings", + "mezzanine.pages.context_processors.page", +) + +# List of middleware classes to use. Order is important; in the request phase, +# these middleware classes will be applied in the order given, and in the +# response phase the middleware will be applied in reverse order. +MIDDLEWARE_CLASSES = ( + "mezzanine.core.middleware.UpdateCacheMiddleware", + 'django.contrib.sessions.middleware.SessionMiddleware', + # Uncomment if using internationalisation or localisation + 'django.middleware.locale.LocaleMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + + "mezzanine.core.request.CurrentRequestMiddleware", + "mezzanine.core.middleware.RedirectFallbackMiddleware", + "mezzanine.core.middleware.TemplateForDeviceMiddleware", + "mezzanine.core.middleware.TemplateForHostMiddleware", + "mezzanine.core.middleware.AdminLoginInterfaceSelectorMiddleware", + "mezzanine.core.middleware.SitePermissionMiddleware", + # Uncomment the following if using any of the SSL settings: + # "mezzanine.core.middleware.SSLRedirectMiddleware", + "mezzanine.pages.middleware.PageMiddleware", + "mezzanine.core.middleware.FetchFromCacheMiddleware", +) + +# Store these package names here as they may change in the future since +# at the moment we are using custom forks of them. +PACKAGE_NAME_FILEBROWSER = "filebrowser_safe" +PACKAGE_NAME_GRAPPELLI = "grappelli_safe" + +######################### +# OPTIONAL APPLICATIONS # +######################### + +# These will be added to ``INSTALLED_APPS``, only if available. +OPTIONAL_APPS = ( + "debug_toolbar", + "django_extensions", + "compressor", + PACKAGE_NAME_FILEBROWSER, + PACKAGE_NAME_GRAPPELLI, +) + +################## +# LOCAL SETTINGS # +################## + +# Allow any settings to be defined in local_settings.py which should be +# ignored in your version control system allowing for settings to be +# defined per machine. +try: + from .local_settings import * +except ImportError as e: + if "local_settings" not in str(e): + raise e + + +#################### +# DYNAMIC SETTINGS # +#################### + +# set_dynamic_settings() will rewrite globals based on what has been +# defined so far, in order to provide some better defaults where +# applicable. We also allow this settings module to be imported +# without Mezzanine installed, as the case may be when using the +# fabfile, where setting the dynamic settings below isn't strictly +# required. +try: + from mezzanine.utils.conf import set_dynamic_settings +except ImportError: + pass +else: + set_dynamic_settings(globals()) diff --git a/app/manifeste/urls.py b/app/manifeste/urls.py new file mode 100644 index 00000000..c1ae1c04 --- /dev/null +++ b/app/manifeste/urls.py @@ -0,0 +1,104 @@ +from __future__ import unicode_literals + +from django.conf.urls import patterns, include, url +from django.conf.urls.i18n import i18n_patterns +from django.contrib import admin + +from mezzanine.core.views import direct_to_template +from mezzanine.conf import settings + + +admin.autodiscover() + +# Add the urlpatterns for any custom Django applications here. +# You can also change the ``home`` view to add your own functionality +# to the project's homepage. + +urlpatterns = i18n_patterns("", + # Change the admin prefix here to use an alternate URL for the + # admin interface, which would be marginally more secure. + ("^admin/", include(admin.site.urls)), +) + +if settings.USE_MODELTRANSLATION: + urlpatterns += patterns('', + url('^i18n/$', 'django.views.i18n.set_language', name='set_language'), + ) + +urlpatterns += patterns('', + # (r'^newsletter/', include('newsletter.urls')), + + # We don't want to presume how your homepage works, so here are a + # few patterns you can use to set it up. + + # HOMEPAGE AS STATIC TEMPLATE + # --------------------------- + # This pattern simply loads the index.html template. It isn't + # commented out like the others, so it's the default. You only need + # one homepage pattern, so if you use a different one, comment this + # one out. + + url("^$", direct_to_template, {"template": "index.html"}, name="home"), + + # HOMEPAGE AS AN EDITABLE PAGE IN THE PAGE TREE + # --------------------------------------------- + # This pattern gives us a normal ``Page`` object, so that your + # homepage can be managed via the page tree in the admin. If you + # use this pattern, you'll need to create a page in the page tree, + # and specify its URL (in the Meta Data section) as "/", which + # is the value used below in the ``{"slug": "/"}`` part. Make + # sure to uncheck all templates for the "show in menus" field + # when you create the page, since the link to the homepage is + # always hard-coded into all the page menus that display navigation + # on the site. Also note that the normal rule of adding a custom + # template per page with the template name using the page's slug + # doesn't apply here, since we can't have a template called + # "/.html" - so for this case, the template "pages/index.html" can + # be used. + + # url("^$", "mezzanine.pages.views.page", {"slug": "/"}, name="home"), + + # HOMEPAGE FOR A BLOG-ONLY SITE + # ----------------------------- + # This pattern points the homepage to the blog post listing page, + # and is useful for sites that are primarily blogs. If you use this + # pattern, you'll also need to set BLOG_SLUG = "" in your + # ``settings.py`` module, and delete the blog page object from the + # page tree in the admin if it was installed. + + # url("^$", "mezzanine.blog.views.blog_post_list", name="home"), + + # MEZZANINE'S URLS + # ---------------- + # ADD YOUR OWN URLPATTERNS *ABOVE* THE LINE BELOW. + # ``mezzanine.urls`` INCLUDES A *CATCH ALL* PATTERN + # FOR PAGES, SO URLPATTERNS ADDED BELOW ``mezzanine.urls`` + # WILL NEVER BE MATCHED! + + # If you'd like more granular control over the patterns in + # ``mezzanine.urls``, go right ahead and take the parts you want + # from it, and use them directly below instead of using + # ``mezzanine.urls``. + ("^", include("mezzanine.urls")), + + # MOUNTING MEZZANINE UNDER A PREFIX + # --------------------------------- + # You can also mount all of Mezzanine's urlpatterns under a + # URL prefix if desired. When doing this, you need to define the + # ``SITE_PREFIX`` setting, which will contain the prefix. Eg: + # SITE_PREFIX = "my/site/prefix" + # For convenience, and to avoid repeating the prefix, use the + # commented out pattern below (commenting out the one above of course) + # which will make use of the ``SITE_PREFIX`` setting. Make sure to + # add the import ``from django.conf import settings`` to the top + # of this file as well. + # Note that for any of the various homepage patterns above, you'll + # need to use the ``SITE_PREFIX`` setting as well. + + # ("^%s/" % settings.SITE_PREFIX, include("mezzanine.urls")) +) + +# Adds ``STATIC_URL`` to the context of error pages, so that error +# pages can use JS, CSS and images. +handler404 = "mezzanine.core.views.page_not_found" +handler500 = "mezzanine.core.views.server_error" diff --git a/app/wsgi.py b/app/wsgi.py new file mode 100644 index 00000000..faa39cf2 --- /dev/null +++ b/app/wsgi.py @@ -0,0 +1,18 @@ +""" +WSGI config for diggersdigest project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/ +""" + +import os +from django.core.wsgi import get_wsgi_application +from mezzanine.utils.conf import real_project_name + +settings_module = "%s.settings" % real_project_name("manifeste") + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings_module) + +application = get_wsgi_application() diff --git a/doc/cahier_des_charges_2016.pdf b/doc/cahier_des_charges_2016.pdf new file mode 100644 index 00000000..ecb5b1ae Binary files /dev/null and b/doc/cahier_des_charges_2016.pdf differ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..3ff47325 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# +# Copyright (c) 2015 IRCAM + +# Manifeste is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. + +# Manifeste is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with Manifeste. If not, see . + +# Authors: +# Guillaume Pellerin + + +media: + image: debian:jessie + volumes: + - ./data/media/:/srv/media + - ./data/static/:/srv/static + - ./data/backup/:/srv/backup + command: "true" + +db: + image: mysql + volumes: + # - ./app/deploy/my.cnf:/etc/mysql/my.cnf + - ./data/var/lib/mysql/:/var/lib/mysql + volumes_from: + - media + environment: + - MYSQL_ROOT_PASSWORD=hyRob0otlaz4 + - MYSQL_DATABASE=manifeste + - MYSQL_USER=manifeste + - MYSQL_PASSWORD=Onukifsid7 + +app: + build: . + command: /bin/sh deploy/start_app.sh + volumes: + - ./app/:/srv/app + volumes_from: + - media + expose: + - "8000" + links: + - db + +nginx: + image: nginx + ports: + - "8000:80" + volumes: + - ./app/deploy/nginx-app.conf:/etc/nginx/conf.d/default.conf + volumes_from: + - media + links: + - app diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 00000000..e69de29b diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..ee732c80 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,9 @@ +--index-url https://pypi.python.org/simple/ + +setuptools +uwsgi +watchdog +MySQL-python==1.2.5 +Django==1.8.7 +mezzanine==4.0.1 +django-modeltranslation