Commit 738b5808 authored by Christophe Siraut's avatar Christophe Siraut

Initial commit.

parents
*.pyc
fix*
*.sqlite
*~
env
flyer/settings.py
page/static/media/images
page/static/media/files
static
Options +ExecCGI
AddHandler fcgid-script .fcgi
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteCond %{REQUEST_URI} !^/static/
RewriteRule ^(.*)$ site.fcgi/$1 [QSA,L]
clean:
find . -name "*.pyc" -exec rm -f {} \;
find . -name "*~" -exec rm -f {} \;
[ ! -d media -o ! -d static -o ! -d env ] || rm -r env static media
build: clean
[ -f flyers/settings.py ] || cp flyers/settings_example.py flyers/settings.py
[ -d media/uploads ] || mkdir -p media/uploads
chmod +x site.fcgi
virtualenv env
. env/bin/activate
env/bin/pip install -r requirements.txt
env/bin/python manage.py collectstatic --noinput
env/bin/python manage.py syncdb --noinput
#env/bin/python manage.py createsuperuser --noinput --username admin --email no@example.com
#env/bin/python manage.py changepassword admin
env/bin/python manage.py loaddata json/auth.json
env/bin/python manage.py loaddata json/general.json
permissions: clean
sudo chown -R ${USER}:www-data .
find . -type f -exec chmod 664 {} \;
chmod 775 manage.py site.fcgi env/bin/python
prepimages:
find . -iname "*.jpg" -exec cp {} 1024 \;
find . -iname "*.jpg" -exec cp {} 640 \;
for i in 1024/*; do convert "$i" -resize 1024x1024 "$i"; done
for i in 640/*; do convert "$i" -resize 1024x1024 "$i"; done
TESTPATH = /var/www/django-flyers
test: clean
sudo rm -fr $(TESTPATH)
sudo cp -r ../django-flyers $(TESTPATH)
. $(TESTPATH)/env/bin/activate
cd $(TESTPATH) && env/bin/python manage.py collectstatic --noinput
sudo chown -R www-data $(TESTPATH)
kill:
for p in $$(ps aux | grep site.fcgi | cut -f 2-3 -d' '); do sudo kill $$p; done
Required server-side:
- python-sorl
- mod-rewrite
- libjpeg62-dev
In the admin section you find the follwoing items:
- A page structures the websites. When "In menu" is enabled, the page gets a link in the main menu. The "Weight" value is helpful to order the menu. A page can have childeren pages; a snapshot of the childeren is be displayed on their parent.
from models import Page, Image, Agenda, Press, Reference, Video, ImagesUpload, File
from django.contrib import admin
#admin.site.register(Page)
class PageAdmin(admin.ModelAdmin):
list_display = ('title', 'parent', 'in_menu', 'weight')
admin.site.register(Page, PageAdmin)
class ImageAdmin(admin.ModelAdmin):
list_display = ('title', 'page')
class VideoAdmin(admin.ModelAdmin):
list_display = ('title', 'page')
class FileAdmin(admin.ModelAdmin):
list_display = ('title', 'page')
admin.site.register(Image, ImageAdmin)
admin.site.register(Agenda)
admin.site.register(Press)
admin.site.register(Reference)
admin.site.register(Video, VideoAdmin)
#admin.site.register(File, FileAdmin)
admin.site.register(ImagesUpload)
from .models import Page
def menu(request):
menupages = Page.objects.filter(in_menu=True)
return {'menu': menupages }
from django.db import models
from django.template.defaultfilters import slugify
from ckeditor.fields import RichTextField
from sorl.thumbnail.fields import ImageField
class Page(models.Model):
title = models.CharField(max_length=80)
text = RichTextField(max_length=4000,blank=True,null=True)
parent = models.ForeignKey('self',blank=True,null=True)
in_menu = models.BooleanField()
weight = models.IntegerField(default=0,blank=True,null=True)
date = models.DateField(auto_now=True)
bgimage = models.ImageField(upload_to="images",blank=True)
slug = models.CharField(max_length=80, editable=False)
lnk = models.CharField(max_length=100, editable=False)
def __unicode__(self):
return self.title
class Meta:
ordering = ['weight']
def save(self):
#if not self.id:
self.slug = slugify(self.title)
#self.lnk = "/" + self.folder.slug + "/" + self.slug
super(Page, self).save()
class Image(models.Model):
page = models.ForeignKey(Page)
#image = models.ImageField(upload_to="images")
image = ImageField(upload_to="images")
title = models.CharField(max_length=80,blank=True,null=True)
text = RichTextField(max_length=800,blank=True,null=True)
def url(self):
return '/media/%s' % self.image
def __unicode__(self):
return self.title
def save(self):
if not self.title:
self.title = slugify(str(self.image))
super(Image, self).save()
class Video(models.Model):
page = models.ForeignKey(Page)
title = models.CharField(max_length=80)
text = RichTextField(max_length=800,blank=True,null=True)
def __unicode__(self):
return self.title
class Agenda(models.Model):
page = models.ForeignKey(Page, unique=True)
text = RichTextField(max_length=2000,blank=True,null=True)
def __unicode__(self):
return "Agenda " + str(self.page)
class Press(models.Model):
page = models.ForeignKey(Page)
image = ImageField(upload_to="images",blank=True,null=True)
text = RichTextField(max_length=2000,blank=True,null=True)
def __unicode__(self):
return "Press review" + str(self.page)
class Meta:
verbose_name = 'Press review'
class Reference(models.Model):
page = models.ForeignKey(Page)
text = RichTextField(max_length=2000,blank=True,null=True)
def __unicode__(self):
return "Reference " + str(self.page)
class File(models.Model):
page = models.ForeignKey(Page)
file = models.FileField(upload_to="files",blank=True,null=True)
text = RichTextField(max_length=200,blank=True,null=True)
def __unicode__(self):
return self.title
def save(self):
if not self.title:
self.title = slugify(str(self.file))
super(File, self).save()
class ImagesUpload(models.Model):
page = models.ForeignKey(Page)
zip_file = models.FileField(upload_to="zip", help_text='Select a .zip file of images to upload')
class Meta:
verbose_name = 'imagepack'
#def __unicode__(self):
# return str(self.zip_file)
def save(self):
super(ImagesUpload, self).save()
page = self.process_zipfile()
super(ImagesUpload, self).delete()
return page
def process_zipfile(self):
import os
import zipfile
from cStringIO import StringIO
from PIL import Image as PILImage
from django.core.files.base import ContentFile
if os.path.isfile(self.zip_file.path):
# TODO: implement try-except here
zip = zipfile.ZipFile(self.zip_file.path)
bad_file = zip.testzip()
if bad_file:
raise Exception('"%s" in the .zip archive is corrupt.' % bad_file)
count = 1
page = self.page
#f = open('/tmp/workfile', 'wa')
#f.write(filename)
#f.write(slug)
for filename in sorted(zip.namelist()):
if filename.startswith('__'): # do not process meta files
continue
data = zip.read(filename)
if len(data):
try:
# the following is taken from django.newforms.fields.ImageField:
# load() is the only method that can spot a truncated JPEG,
# but it cannot be called sanely after verify()
trial_image = PILImage.open(StringIO(data))
trial_image.load()
# verify() is the only method that can spot a corrupt PNG,
# but it must be called immediately after the constructor
trial_image = PILImage.open(StringIO(data))
trial_image.verify()
except Exception:
# if a "bad" file is found we just skip it.
continue
#while 1:
#title = ' '.join([self.title, str(count)])
slug = slugify(filename)
try:
print slug
p = Image.objects.get(title=slug)
except:
image = Image(title=slug,page=self.page)
image.image.save(filename, ContentFile(data))
#image.save() # needed?
#page.photos.add(photo)
#count = count + 1
#break
count = count + 1
zip.close()
return page
{% extends "admin/base.html" %}
{% load i18n %}
{% block title %}{{ title }} | {% trans 'Django site admin' %}{% endblock %}
{% block branding %}
<h1 id="site-name">{% trans 'Jordi administration' %}</h1>
{% endblock %}
{% block nav-global %}{% endblock %}
{% load i18n %}{% load static %}<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset="utf-8" />
<title>{{ settings.site_name }} {% block title %}{% endblock %}</title>
<meta name="Author" content="Tobald" />
<link href="/static/css/weblog.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/static/lightbox/js/prototype.js"></script>
<script type="text/javascript" src="/static/lightbox/js/scriptaculous.js?load=effects,builder"></script>
<script type="text/javascript" src="/static/lightbox/js/lightbox.js"></script>
<link rel="stylesheet" href="/static/lightbox/css/lightbox.css" type="text/css" media="screen" />
{% block style %}{% endblock %}
<style>
#bgimage {
{% if object.bgimage %}
background: url("{% get_media_prefix %}{{ object.bgimage }}") no-repeat center center; /* center center fixed; */
background-size: cover;
{% else %}
background: url("{% get_static_prefix %}images/Texture0419.gif") repeat; /* center center fixed; */
{% endif %}
}
</style>
</head>
<body>
<div id="bgimage"></div>
<div id="diag"></div>
<div id="slider" class="slideRight">
<div id="content" >
{% block content %}{% endblock %}
&nbsp;
</div>
<div id="footer">
<div class="pagewrap" style="padding: 10px; text-align: center;">Website powered with <a href="http://www.tobald.eu.org/projects/flyers/">Flyers</a> - <a href="/admin/">Admin</a> </div></div>
</div>
</div>
<div class="menu">
<a href="/"><img src="{% get_media_prefix %}{{ settings.logo }}" alt="{{ settings.site_name }}"></a>
<br /><br />
<div class="menutext diagonal">
{% for page in menu %}
<a href="/{{ page.slug }}/">{{ page }}</a><br />
{% endfor %}
</div>
</div>
{% if SITE_MULTILINGUAL %}
<div id="languageselect">
<form action="/i18n/setlang/" method="post" name="langForm" class="langForm">
{% csrf_token %}
<input name="next" type="hidden" value="/{{ page.slug }}/" />
<select name="language" onChange="langForm.submit();" >
{% for lang in LANGUAGES %}
{% ifequal lang.0 LANGUAGE_CODE %}
<option value="#" />{{ lang.1 }}</option>
{% endifequal %}
{% endfor %}
{% for lang in LANGUAGES %}
{% ifnotequal lang.0 LANGUAGE_CODE %}
<option value="{{ lang.0 }}" />{{ lang.1 }}</option>
{% endifnotequal %}
{% endfor %}
</select>
</form>
</div>
{% endif %}
<div id="viewback">
<img src="/static/images/eye.png" onmouseover="javascript:updateTransition();" onmouseout="javascript:updateTransition();">
</div>
<script type="text/javascript">
function updateTransition() {
var el = document.querySelector("div.slideLeft");
if (el) {
el.className = "slideRight";
} else {
el = document.querySelector("div.slideRight");
el.className = "slideLeft";
}
return el;
}
</script>
</body>
</html>
{% extends "base.html" %}
{% load thumbnail %}{% load i18n %}{% load static %}
{% block title %} - {{ object.title }}{% endblock %}
{% block content %}
{% if object.text %}
<div class="pagewrap">
<div class="page">
<div class="pagelinks">
{% if object.agenda_set.all %} <a href="#agenda">Agenda</a>&nbsp;{% endif %}
{% if object.image_set.all %} <a href="#pictures">Pictures</a>&nbsp;{% endif %}
{% if object.video_set.all %} <a href="#videos">Videos</a>&nbsp;{% endif %}
{% if object.press_set.all %} <a href="#press">Press</a>{% endif %}
{% if object.reference_set.all %} <a href="#references">References</a>{% endif %}
{% if object.file_set.all %} <a href="#file">Files</a>{% endif %}
</div>
<div class="pagetitle">{{ object.title }}</div>
<div class="pagetext">{{ object.text|safe|urlize|linebreaks }}</div>
</div>
{% for page in object.page_set.all %}
<a href="/{{ page.slug }}/">
{% thumbnail page.bgimage "120x120" crop="center" as im %}
<img class="thumb" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }} title="{{ image.title }}" style="float:left; margin: 10px 20px;">
{% endthumbnail %}
</a>
<div class="pagetitle" style=";"><a href="/{{ page.slug }}/">{{ page|title }}</a></div>
{{ page.text|safe|truncatewords:32|linebreaks }}
<div style="clear:both;"></div>
{% endfor %}
</div>
{% if object.agenda_set.all %}
<div class="pagewrap">
<div class="page">
<div id="agenda" class="pagetitle">Agenda {{ object.title }}</div>
{% for a in object.agenda_set.all %}
{{ a.text|safe|urlize|linebreaks }}
{% endfor %}
</div>
</div>
{% endif %}
{% if object.image_set.all %}
<div class="pagewrap notrans">
<div class="page" style="text-align:center;">
<div id="pictures" class="pagetitle">{{ object.title }} Pictures</div>
{% for image in object.image_set.all %}
{% thumbnail image.image "120x120" crop="center" as im %}
<a href="{{ image.url }}" rel="lightbox[{{ image.page }}]">
<img class="thumb" src="{% get_media_prefix %}{{ im }}" width="{{ im.width }}" height="{{ im.height }} rel="lightbox" title="{{ image.title }}">
</a>
{% endthumbnail %}
{% endfor %}
</div>
</div>
{% endif %}
{% if object.video_set.all %}
<div class="pagewrap notrans" style="padding: 0;">
<div class="page" style="text-align:center;margin: 0;padding: 0;">
<div id="videos" class="pagetitle">{{ object.title }} Videos</div>
{% for video in object.video_set.all %}
{{ video.title }}
{{ video.text|safe }}
{% endfor %}
</div>
</div>
{% endif %}
{% if object.press_set.all %}
<div class="pagewrap notrans">
<div class="page">
<div id="press" class="pagetitle">{{ object.title }} Press Reviews</div>
{% for image in object.press_set.all %}
{{ image.text|safe|urlize|linebreaks }}
{% thumbnail image.image "120x120" crop="center" as im %}
<a href="/static/{{ image.image }}" rel="lightbox[{{ image.page }}]">
<img class="thumb" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }} rel="lightbox" title="{{ image.title }}">
</a>
{% endthumbnail %}
{% endfor %}
</div>
</div>
{% endif %}
{% if object.reference_set.all %}
<div class="pagewrap notrans">
<div class="page">
<div id="references" class="pagetitle">{{ object.title }} References</div>
{% for o in object.reference_set.all %}
{{ o.text|safe|urlize|linebreaks }}
{% endfor %}
</div>
</div>
{% endif %}
{% if object.file_set.all %}
<div class="pagewrap">
<div class="page">
<div id="file" class="pagetitle">{{ object.title }} files</div>
<ul>
{% for a in object.file_set.all %}
<li><a href="/static/{{ a.file }}">{{ a.title }}</a></li>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
{% endif %}
{% endblock %}
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
Replace this with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.assertEqual(1 + 1, 2)
# Create your views here.
# -*- coding: utf-8 -*-
"""
Django settings for flyers project.
For more information on this file, see
https://docs.djangoproject.com/en/1.6/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.6/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '$60dfh^63$8#qttdy)ze+w7fy9!m7*v+*_bix8clj(2f61sy&q'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
TEMPLATE_DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'sorl.thumbnail',
'ckeditor',
'content',
'general'
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
ROOT_URLCONF = 'flyers.urls'
WSGI_APPLICATION = 'flyers.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.6/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.6/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.6/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
CKEDITOR_UPLOAD_PATH = os.path.join(BASE_DIR, 'media', 'uploads')
from django.conf import global_settings
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
'content.context_processors.menu',
'general.context_processors.settings',
)
LANGUAGE_CODE = 'fr-be'
LANGUAGES = (
('en', 'English'),
('fr', 'Français'),
('es', 'Español'),
('ca', 'Català'),
)
MODELTRANSLATION_TRANSLATION_REGISTRY = ('flyer.translation',)
SITE_MULTILINGUAL = False
if SITE_MULTILINGUAL:
INSTALLED_APPS += ('modeltranslation',)
from django.conf.urls import patterns, include, url
from django.views.generic import TemplateView
from django.views.generic import DetailView
from django.shortcuts import get_object_or_404
from content.models import Page
from general.models import Settings
from django.contrib import admin
admin.autodiscover()
class HomepageDetail(DetailView):
model = Page
def get_object(self):
settings = Settings.objects.get(pk=1)
if settings.home_page:
return get_object_or_404(Page, pk=settings.home_page.pk)
return None
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'flyers.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
#url(r'^ckeditor/', include('ckeditor.urls')),
url(r'^ckeditor/', include('flyers.urls_ckeditor')),
#url(r'^$', TemplateView.as_view(template_name='homepage.html')),
url(r'^$', HomepageDetail.as_view()),
url(r'^(?P<slug>.+)/$', DetailView.as_view(model=Page)),
)
import settings
if settings.DEBUG:
urlpatterns += patterns('',
url(r'^media/(?P<path>.*)$',
'django.views.static.serve',
{'document_root': settings.MEDIA_ROOT, }),
)
from django.conf.urls import patterns, url
urlpatterns = patterns(
'',
url(r'^upload/', 'ckeditor.views.upload', name='ckeditor_upload'),
url(r'^browse/', 'ckeditor.views.browse', name='ckeditor_browse'),
)
"""
WSGI config for flyers 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.6/howto/deployment/wsgi/
"""
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "flyers.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
from django.contrib import admin
from .models import Settings
class SettingsAdmin(admin.ModelAdmin):
list_display = ('site_name', 'site_address')
admin.site.register(Settings, SettingsAdmin)
from .models import Settings
def settings(request):
try:
settings = Settings.objects.get(pk=1)
except:
settings = None
return {'settings': settings}
from django.db import models
from content.models import Page
class Settings(models.Model):
site_name = models.CharField(max_length=90, blank=True, null=True)
site_address = models.URLField(max_length=90, blank=True, null=True)
site_description = models.TextField(max_length=300, blank=True, null=True)
logo = models.ImageField(upload_to="images", blank=True, null=True)
home_page = models.ForeignKey(Page, blank=True, null=True)
class Meta:
verbose_name_plural = "Settings"
from django.test import TestCase
# Create your tests here.
from django.shortcuts import render
# Create your views here.
#!/usr/bin/env python
import os