From 7ac6b48b67d0fdb2aec271ad4069715daeb58b34 Mon Sep 17 00:00:00 2001 From: Brett Parker Date: Wed, 2 Sep 2009 13:39:26 +0100 Subject: [PATCH] Initial import of eatslugs code... --- .gitignore | 3 + eatslugs/__init__.py | 0 eatslugs/generic/__init__.py | 0 eatslugs/generic/context_processors.py | 6 ++ eatslugs/generic/docutils_xhtml11.py | 32 +++++++ eatslugs/generic/helpers.py | 100 ++++++++++++++++++++ eatslugs/generic/templatetags/__init__.py | 0 eatslugs/generic/templatetags/thumbnail.py | 37 ++++++++ eatslugs/generic/templatetags/xhtml11rst.py | 22 +++++ eatslugs/generic/views.py | 14 +++ eatslugs/manage.py | 11 +++ eatslugs/recipes/__init__.py | 0 eatslugs/recipes/admin.py | 7 ++ eatslugs/recipes/models.py | 16 ++++ eatslugs/recipes/views.py | 1 + eatslugs/settings.py | 83 ++++++++++++++++ eatslugs/urls.py | 16 ++++ media/img/sandwich.png | Bin 0 -> 11268 bytes media/img/slug.png | Bin 0 -> 5935 bytes media/style/main.css | 31 ++++++ templates/404.html | 6 ++ templates/base.html | 20 ++++ templates/main_index.html | 8 ++ 23 files changed, 413 insertions(+) create mode 100644 .gitignore create mode 100644 eatslugs/__init__.py create mode 100644 eatslugs/generic/__init__.py create mode 100644 eatslugs/generic/context_processors.py create mode 100644 eatslugs/generic/docutils_xhtml11.py create mode 100644 eatslugs/generic/helpers.py create mode 100644 eatslugs/generic/templatetags/__init__.py create mode 100644 eatslugs/generic/templatetags/thumbnail.py create mode 100644 eatslugs/generic/templatetags/xhtml11rst.py create mode 100644 eatslugs/generic/views.py create mode 100755 eatslugs/manage.py create mode 100644 eatslugs/recipes/__init__.py create mode 100644 eatslugs/recipes/admin.py create mode 100644 eatslugs/recipes/models.py create mode 100644 eatslugs/recipes/views.py create mode 100644 eatslugs/settings.py create mode 100644 eatslugs/urls.py create mode 100644 media/img/sandwich.png create mode 100644 media/img/slug.png create mode 100644 media/style/main.css create mode 100644 templates/404.html create mode 100644 templates/base.html create mode 100644 templates/main_index.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8c4ffb7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +eatslugs.db +*.pyc +*.pyo diff --git a/eatslugs/__init__.py b/eatslugs/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/eatslugs/generic/__init__.py b/eatslugs/generic/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/eatslugs/generic/context_processors.py b/eatslugs/generic/context_processors.py new file mode 100644 index 0000000..d7ab9e0 --- /dev/null +++ b/eatslugs/generic/context_processors.py @@ -0,0 +1,6 @@ +from django.conf import settings + +def media(request): + return { + 'MEDIA_URL': settings.MEDIA_URL, + } diff --git a/eatslugs/generic/docutils_xhtml11.py b/eatslugs/generic/docutils_xhtml11.py new file mode 100644 index 0000000..4b7d9b9 --- /dev/null +++ b/eatslugs/generic/docutils_xhtml11.py @@ -0,0 +1,32 @@ +# Author: Brett Parker + +""" +HTML1.1 Writer. +""" + +__docformat__ = 'reStructuredText' + +import sys +import os +import os.path +import codecs +import docutils +from docutils import frontend, nodes, utils, writers +from docutils.writers import html4css1 + +class Writer(html4css1.Writer): + + config_section = 'xhtml11 writer' + config_section_dependencies = ('writers', 'html4css1 writer') + + def __init__(self): + html4css1.Writer.__init__(self) + self.translator_class = HTMLTranslator + +class HTMLTranslator(html4css1.HTMLTranslator): + + def is_compactable(self, node): + return False + + def should_be_compact_paragraph(self, node): + return False diff --git a/eatslugs/generic/helpers.py b/eatslugs/generic/helpers.py new file mode 100644 index 0000000..6c85aa1 --- /dev/null +++ b/eatslugs/generic/helpers.py @@ -0,0 +1,100 @@ +from django.conf import settings +from PIL import Image +import os, sys + +def make_thumbnail(imagefile,width=None,height=None): + # first check that the thumbnail image doesn't already exist + # and if it does that it's newer than the origional image + + base_dir = settings.MEDIA_ROOT + thumbs_dir = base_dir + if not thumbs_dir.endswith("/"): + thumbs_dir = "%s/" %(thumbs_dir,) + base_dir = "%s/" %(base_dir,) + + try: + thumbs_dir = "%s%s/" %(thumbs_dir, settings.THUMBS_DIRECTORY) + thumbsdirectory = settings.THUMBS_DIRECTORY + except: + thumbs_dir = "%sthumbs/" %(thumbs_dir,) + thumbsdirectory = "thumbs" + + if width != None: + try: + thumb = os.stat("%sw%d/%s" % (thumbs_dir, width, imagefile)) + pic = os.stat("%s%s" % (base_dir, imagefile)) + if thumb.st_ctime < pic.st_ctime: + # regenerate the icon + img = Image.open("%s%s" %(base_dir, imagefile)) + (curwidth,curheight) = img.size + + newwidth = width + newheight = int((newwidth * curheight) / curwidth) + + newimg = img.resize((newwidth, newheight)) + newimg.save("%sw%d/%s" %(thumbs_dir, width, imagefile)) + + return "%s%s/w%d/%s" %(settings.MEDIA_URL, thumbsdirectory, width, imagefile) + else: + # we have a winner! + return "%s%s/w%d/%s" %(settings.MEDIA_URL, thumbsdirectory, width, imagefile) + except: + # well, there's not one there. feh. sucks. + try: + directory_to_create = imagefile[:imagefile.rindex(os.sep)] + img = Image.open("%s%s" %(base_dir, imagefile)) + if not os.path.isdir("%sw%d/%s" %(thumbs_dir, width, directory_to_create)): + os.makedirs("%sw%d/%s" %(thumbs_dir, width, directory_to_create)) + (curwidth,curheight) = img.size + + newwidth = width + newheight = int((newwidth * curheight) / curwidth) + + newimg = img.resize((newwidth, newheight)) + newimg.save("%sw%d/%s" %(thumbs_dir, width, imagefile)) + + return "%s%s/w%d/%s" %(settings.MEDIA_URL, thumbsdirectory, width, imagefile) + except Exception, e: + sys.stderr.write("Got exception: %s" %(e,)) + + elif height != None: + try: + thumb = os.stat("%sh%d/%s" % (thumbs_dir, height, imagefile)) + pic = os.stat("%s%s" % (base_dir, imagefile)) + if thumb.st_ctime < pic.st_ctime: + # regenerate the icon + img = Image.open("%s%s" %(base_dir, imagefile)) + (curwidth,curheight) = img.size + + newheight = height + newheight = int((newheight * curwidth) / curheight) + + newimg = img.resize((newwidth, newheight)) + newimg.save("%sh%d/%s" %(thumbs_dir, height, imagefile)) + + return "%s%s/h%d/%s" %(settings.MEDIA_URL, thumbsdirectory, height, imagefile) + else: + # we have a winner! + return "%s%s/h%d/%s" %(settings.MEDIA_URL, thumbsdirectory, height, imagefile) + except: + # well, there's not one there. feh. sucks. + try: + directory_to_create = imagefile[:imagefile.rindex(os.sep)] + img = Image.open("%s%s" %(base_dir, imagefile)) + os.makedirs("%sh%h/%s" %(thumbs_dir, height, directory_to_create)) + (curwidth,curheight) = img.size + + newheight = height + newwidth = int((newheight * curwidth) / curheight) + + newimg = img.resize((newwidth, newheight)) + newimg.save("%sh%d/%s" %(thumbs_dir, height, imagefile)) + + return "%s%s/h%d/%s" %(settings.MEDIA_URL, thumbsdirectory, height, imagefile) + except: + pass + + # if everything fails, we'll return the origional image URL + # this is for simpilicity + return "%s%s" %(settings.MEDIA_URL, imagefile) + diff --git a/eatslugs/generic/templatetags/__init__.py b/eatslugs/generic/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/eatslugs/generic/templatetags/thumbnail.py b/eatslugs/generic/templatetags/thumbnail.py new file mode 100644 index 0000000..4e20cef --- /dev/null +++ b/eatslugs/generic/templatetags/thumbnail.py @@ -0,0 +1,37 @@ +from django import template +from django.conf import settings +from generic import helpers +import sys + +register = template.Library() + +def thumbnail(image_url, args=''): + options = {} + + if ',' not in args: + args = "%s," %(args,) + + for arg in args.split(','): + arg = arg.strip() + try: + (kw,val) = arg.split('=', 1) + try: + options[kw] = int(val) + except: + pass + except: + pass + + if options.has_key("height") or options.has_key("width"): + if options.has_key("width") and options.has_key("height"): + return helpers.make_thumbnail(image_url[len(settings.MEDIA_URL):], width=options["width"], height=options["height"]) + elif options.has_key("width"): + return helpers.make_thumbnail(image_url[len(settings.MEDIA_URL):], width=options["width"]) + else: + return helpers.make_thumbnail(image_url[len(settings.MEDIA_URL):], height=options["height"]) + else: + pass + + return "%s" %(image_url) + +register.filter(thumbnail) diff --git a/eatslugs/generic/templatetags/xhtml11rst.py b/eatslugs/generic/templatetags/xhtml11rst.py new file mode 100644 index 0000000..3bc212a --- /dev/null +++ b/eatslugs/generic/templatetags/xhtml11rst.py @@ -0,0 +1,22 @@ +from django import template +from django.conf import settings +from django.utils.encoding import smart_str, force_unicode +from django.utils.safestring import mark_safe +from generic import docutils_xhtml11 + +register = template.Library() + +def restructuredtext(value): + try: + from docutils.core import publish_parts + except ImportError: + if settings.DEBUG: + raise template.TemplateSyntaxError, "Error in {% restructuredtext %} filter: The Python docutils library isn't installed." + return force_unicode(value) + else: + docutils_settings = getattr(settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {}) + parts = publish_parts(source=smart_str(value), writer=docutils_xhtml11.Writer(), settings_overrides=docutils_settings) + return mark_safe(force_unicode(parts["fragment"])) +restructuredtext.is_safe = True + +register.filter(restructuredtext) diff --git a/eatslugs/generic/views.py b/eatslugs/generic/views.py new file mode 100644 index 0000000..63d9ea1 --- /dev/null +++ b/eatslugs/generic/views.py @@ -0,0 +1,14 @@ +from settings import MEDIA_URL +from django.http import HttpResponseNotFound +from django.template import RequestContext, loader + + +def render_404(request, template_name='404.html'): + t = loader.get_template(template_name) + return HttpResponseNotFound( \ + t.render(RequestContext(request, + { + 'request_path': request.path, + 'media_url' : MEDIA_URL, + } + ))) diff --git a/eatslugs/manage.py b/eatslugs/manage.py new file mode 100755 index 0000000..bcdd55e --- /dev/null +++ b/eatslugs/manage.py @@ -0,0 +1,11 @@ +#!/usr/bin/python +from django.core.management import execute_manager +try: + import settings # Assumed to be in the same directory. +except ImportError: + import sys + sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) + sys.exit(1) + +if __name__ == "__main__": + execute_manager(settings) diff --git a/eatslugs/recipes/__init__.py b/eatslugs/recipes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/eatslugs/recipes/admin.py b/eatslugs/recipes/admin.py new file mode 100644 index 0000000..7cecf88 --- /dev/null +++ b/eatslugs/recipes/admin.py @@ -0,0 +1,7 @@ +from django.contrib import admin +from models import Drink, Recipe, Combination + +admin.site.register(Drink) +admin.site.register(Recipe) +admin.site.register(Combination) + diff --git a/eatslugs/recipes/models.py b/eatslugs/recipes/models.py new file mode 100644 index 0000000..dda8c98 --- /dev/null +++ b/eatslugs/recipes/models.py @@ -0,0 +1,16 @@ +from django.db import models + +# Create your models here. + +class Recipe(models.Model): + name = models.CharField(max_length=250) + ingrediants = models.TextField() + description = models.TextField() + +class Drink(models.Model): + name = models.CharField(max_length=250) + description = models.TextField() + +class Combination(models.Model): + recipe = models.ForeignKey('Recipe') + drink = models.ForeignKey('Drink') diff --git a/eatslugs/recipes/views.py b/eatslugs/recipes/views.py new file mode 100644 index 0000000..60f00ef --- /dev/null +++ b/eatslugs/recipes/views.py @@ -0,0 +1 @@ +# Create your views here. diff --git a/eatslugs/settings.py b/eatslugs/settings.py new file mode 100644 index 0000000..27227aa --- /dev/null +++ b/eatslugs/settings.py @@ -0,0 +1,83 @@ +# Django settings for eatslugs project. + +# Rather than editing settings here, add them to the localsettings.py file +# which will be included at the end of the run and replace anything in here. + +import os +topdir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) + +DEBUG = True +TEMPLATE_DEBUG = DEBUG + +ADMINS = ( + ('Brett Parker', 'iDunno@sommitrealweird.co.uk'), +) + +MANAGERS = ADMINS + +DATABASE_ENGINE = 'sqlite3' +DATABASE_NAME = os.path.join(topdir, 'eatslugs.db') +DATABASE_USER = '' +DATABASE_PASSWORD = '' +DATABASE_HOST = '' +DATABASE_PORT = '' + +TIME_ZONE = 'Europe/London' + +LANGUAGE_CODE = 'en-gb' + +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 + +MEDIA_ROOT = os.path.join(topdir, 'media') + os.sep +MEDIA_URL = '/media/' + +ADMIN_MEDIA_PREFIX = '/admin-media/' + +import random +import string +key_chars = "%s%s%s" %(string.letters, string.digits, '+-()_#~') +SECRET_KEY = "".join([random.choice(key_chars) for a in range(0,50)]) + +# List of callables that know how to import templates from various sources. +TEMPLATE_LOADERS = ( + 'django.template.loaders.filesystem.load_template_source', + 'django.template.loaders.app_directories.load_template_source', +) + +MIDDLEWARE_CLASSES = ( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', +) + +ROOT_URLCONF = 'urls' + +TEMPLATE_DIRS = ( + os.path.join(topdir, 'templates') +) + +INSTALLED_APPS = ( + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.sites', + 'recipes', +) + +TEMPLATE_CONTEXT_PROCESSORS = ( + 'django.core.context_processors.auth', + 'django.core.context_processors.debug', + 'django.core.context_processors.i18n', + 'generic.context_processors.media', +) + +try: + from localsettings import * +except: + pass + diff --git a/eatslugs/urls.py b/eatslugs/urls.py new file mode 100644 index 0000000..8597968 --- /dev/null +++ b/eatslugs/urls.py @@ -0,0 +1,16 @@ +from django.conf.urls.defaults import * +from django.views.generic.simple import direct_to_template +from django.views.static import serve +from django.conf import settings + +# Uncomment the next two lines to enable the admin: +from django.contrib import admin +admin.autodiscover() + +urlpatterns = patterns('', + # Example: + # (r'^recipes/', include('recipes.urls')), + (r'^$', direct_to_template, {"template": 'main_index.html'},), + (r'^media/(?P.*)$', serve, {'document_root': settings.MEDIA_ROOT, 'show_indexes': False}), + (r'^admin/(.*)', admin.site.root), +) diff --git a/media/img/sandwich.png b/media/img/sandwich.png new file mode 100644 index 0000000000000000000000000000000000000000..104498c673020c817341d06ffe844131e1c0ea6c GIT binary patch literal 11268 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, couldn't find what you were looking for. Oops.

+{% endblock %} diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..7afbb33 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,20 @@ + + + + + {% block title %}{% if title %}{{ title }}{% else %}EATSLUGS{% endif %}{% endblock %} + + {% block extrahead %}{% endblock %} + + +
+
+ A Yummy SandwichA Slug... no, really.

East Anglian Sandwich, Toasty and Luncheon Users Group Symposium

+
+
+ {% block content %} + {% endblock %} +
+
+ + diff --git a/templates/main_index.html b/templates/main_index.html new file mode 100644 index 0000000..6d92f33 --- /dev/null +++ b/templates/main_index.html @@ -0,0 +1,8 @@ +{% extends "base.html" %} + +{% block content %} +

Welcome to the EATSLUGS website

+

+ This will be a collection of random sandwich and drink combinations come up with by our resident experts (or just generally by us lot being insane...) - we hope you will like them. +

+{% endblock %} -- 2.39.5