* Initial import of a django project.
authorMatthijs Kooijman <matthijs@stdin.nl>
Mon, 21 Jan 2008 21:08:17 +0000 (22:08 +0100)
committerMatthijs Kooijman <matthijs@stdin.nl>
Mon, 21 Jan 2008 21:08:17 +0000 (22:08 +0100)
   * Contains working phpbb authentication.
   * Contains some stuff for registration and influences (quite unfinished).

25 files changed:
__init__.py [new file with mode: 0644]
auth.py [new file with mode: 0644]
base/__init__.py [new file with mode: 0644]
base/models.py [new file with mode: 0644]
base/views.py [new file with mode: 0644]
dbsettings.py.tmpl [new file with mode: 0644]
events/__init__.py [new file with mode: 0644]
events/models.py [new file with mode: 0644]
events/views.py [new file with mode: 0644]
events/views/__init__.py [new file with mode: 0644]
events/views/event.py [new file with mode: 0644]
influences/__init__.py [new file with mode: 0644]
influences/models.py [new file with mode: 0644]
influences/views.py [new file with mode: 0644]
manage.py [new file with mode: 0755]
settings.py [new file with mode: 0644]
templates/base/base.html [new file with mode: 0644]
templates/base/login.html [new file with mode: 0644]
templates/events/event/detail.html [new file with mode: 0644]
templates/influences/character/detail.html [new file with mode: 0644]
templates/influences/character_addinfluence.html [new file with mode: 0644]
templates/influences/character_detail.html [new file with mode: 0644]
templates/influences/character_list.html [new file with mode: 0644]
templates/influences/index.html [new file with mode: 0644]
urls.py [new file with mode: 0644]

diff --git a/__init__.py b/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/auth.py b/auth.py
new file mode 100644 (file)
index 0000000..88f9f63
--- /dev/null
+++ b/auth.py
@@ -0,0 +1,109 @@
+from django.conf import settings
+from django.contrib.auth.models import User, check_password
+import md5
+import MySQLdb
+
+
+"""
+This auth backend allows django to authenticate against an external phpbb
+database. If authentication is successful, the corresponding User from the
+normal django database is returned (linked on the username field). If no such
+User exists, it is created automatically.
+
+This class uses the following variables from you django settings:
+    PHPBB_DATABASE_HOST
+    PHPBB_DATABASE_PORT
+    PHPBB_DATABASE_USER
+    PHPBB_DATABASE_PASSWORD
+    PHPBB_DATABASE_NAME
+
+If any of these settings are missing, the corresponding setting from Django's
+own database settings are used. This means, that, usually, you only have to
+specify the database name where phpbb lives.
+"""
+class PhpBBBackend:
+    def connect(self):
+        host     = getattr(settings, 'PHPBB_DATABASE_HOST',     settings.DATABASE_HOST)
+        port     = getattr(settings, 'PHPBB_DATABASE_PORT',     settings.DATABASE_PORT)
+        user     = getattr(settings, 'PHPBB_DATABASE_USER',     settings.DATABASE_USER)
+        password = getattr(settings, 'PHPBB_DATABASE_PASSWORD', settings.DATABASE_PASSWORD)
+        name     = getattr(settings, 'PHPBB_DATABASE_NAME',     settings.DATABASE_NAME)
+
+        # This code was shamelessly stolen from
+        # django.db.backends.mysql.base.cursor
+        kwargs = {
+            #'conv': django_conversions,
+            'charset': 'utf8',
+            'use_unicode': False,
+        }
+        if user:
+            kwargs['user'] = user
+        if name:
+            kwargs['db'] = name
+        if password:
+            kwargs['passwd'] = password
+        if host.startswith('/'):
+            kwargs['unix_socket'] = host
+        elif host:
+            kwargs['host'] = host
+        if port:
+            kwargs['port'] = int(port)
+
+        conn = MySQLdb.connect (**kwargs)
+        # End stolen code
+
+        return conn
+
+    def check_login(self, username, password):
+        conn = self.connect()
+
+        # Get some data
+        cursor = conn.cursor ()
+        cursor.execute ("SELECT user_password,user_email FROM users WHERE username=%s", username)
+
+        # No data? No login.
+        if (cursor.rowcount == 0):
+            print("User %s not found", username)
+            return False
+       
+        # Check password
+        row = cursor.fetchone()
+        conn.close()
+
+        if (md5.new(password).hexdigest() == row[0]):
+            return row[1]
+        else:
+            return False
+            
+
+    """
+    Authenticate against a PhpBB database.
+
+    Most of this code has been taken from Django's user auth tutorial.
+    """
+    def authenticate(self, username=None, password=None):
+        print password
+        email = self.check_login(username, password)
+        if email:
+            print "Login checked out"
+            try:
+                user = User.objects.get(username=username)
+            except User.DoesNotExist:
+                print "User did nog exist"
+                # Create a new user. Note that we can set password
+                # to anything, because it won't be checked; the password
+                # from settings.py will.
+                user = User(username=username, password='get from settings.py')
+                user.email = email
+                user.save()
+            print user
+            return user
+        else:
+            return None
+
+    def get_user(self, user_id):
+        try:
+            return User.objects.get(pk=user_id)
+        except User.DoesNotExist:
+            return None
+    
diff --git a/base/__init__.py b/base/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/base/models.py b/base/models.py
new file mode 100644 (file)
index 0000000..1ba0cff
--- /dev/null
@@ -0,0 +1,6 @@
+from django.db import models
+
+# Create your models here.
+class EEObject(models.Model):
+       created     = models.DateField(auto_now_add=1)
+       modified    = models.DateField(auto_now=1)
diff --git a/base/views.py b/base/views.py
new file mode 100644 (file)
index 0000000..60f00ef
--- /dev/null
@@ -0,0 +1 @@
+# Create your views here.
diff --git a/dbsettings.py.tmpl b/dbsettings.py.tmpl
new file mode 100644 (file)
index 0000000..04242fe
--- /dev/null
@@ -0,0 +1,13 @@
+# Database settings. Put here to keep them out of version control. We
+# don't want sensitive data in there, and database settings might vary
+# per deployment
+DATABASE_ENGINE = 'mysql'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
+DATABASE_NAME = 'ee_django'         # Or path to database file if using sqlite3.
+DATABASE_USER = 'ee_django'         # Not used with sqlite3.
+DATABASE_PASSWORD = ''              # Not used with sqlite3.
+DATABASE_HOST = ''                  # Set to empty string for localhost. Not used with sqlite3.
+DATABASE_PORT = ''                  # Set to empty string for default. Not used with sqlite3.
+
+# Database to use for phpbb authentication. Other variables from above
+# (except for ENGINE) can similarly be overridden.
+PHPBB_DATABASE_NAME = 'ee_forum'
diff --git a/events/__init__.py b/events/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/events/models.py b/events/models.py
new file mode 100644 (file)
index 0000000..273ed7c
--- /dev/null
@@ -0,0 +1,35 @@
+from django.db import models
+
+# Create your models here.
+class Event(models.Model):
+       name = models.CharField(maxlength=50)
+       title = models.CharField(maxlength=100)
+       slots = models.IntegerField()
+
+       def __str__(self):
+               if (self.title):
+                       return self.name + ' - ' + self.title
+               else:
+                       return self.name
+
+       class Admin:
+               fields = (
+                       (None,            {'fields' : ('name', 'title')} ),
+                       ('Registrations', {'fields' : ('slots',)} ),
+               )
+
+class Person(models.Model):
+       first_name = models.CharField(maxlength=255)
+       last_name  = models.CharField(maxlength=255)
+
+       def __str__(self):
+               return self.first_name + ' ' + self.last_name
+
+       class Admin:
+               list_display    = ('first_name', 'last_name')
+               list_filter     = ['last_name']
+               search_fields   = ['first_name', 'last_name']
+
+class Registration(models.Model):
+       person = models.ForeignKey(Person, edit_inline=models.STACKED, num_in_admin=3)
+       event  = models.ForeignKey(Event, core=True)
diff --git a/events/views.py b/events/views.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/events/views/__init__.py b/events/views/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/events/views/event.py b/events/views/event.py
new file mode 100644 (file)
index 0000000..fc06909
--- /dev/null
@@ -0,0 +1,23 @@
+#from django.template import Context, loader
+#from django.http import HttpResponse
+from ee.events.models import Event
+from django.shortcuts import render_to_response
+from django.http import Http404
+
+
+
+def detail(request, event_id):
+       try:
+               event = Event.objects.get(id=event_id)
+               #t = loader.get_template('events/event/detail.html')
+               #c = Context({
+               #       'event' : event,
+               #})
+               #return HttpResponse(t.render(c))
+               return render_to_response('events/event/detail.html', {'event' : event})
+       except Event.DoesNotExist:
+               raise Http404
+
+def regs(request, event_id):
+       pass
+       #return HttpResponse('')
diff --git a/influences/__init__.py b/influences/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/influences/models.py b/influences/models.py
new file mode 100644 (file)
index 0000000..bda1dc5
--- /dev/null
@@ -0,0 +1,22 @@
+from django.db import models
+from ee.base.models import EEObject
+
+# Create your models here.
+class Character(EEObject):
+       name = models.CharField(maxlength=255)
+       def __str__(self):
+               return self.name
+
+       class Admin:
+               pass
+
+class Influence(EEObject):
+       contact     = models.CharField(maxlength=255)
+       character   = models.ForeignKey(Character, edit_inline=models.TABULAR, num_in_admin=3, core=True)
+       description = models.TextField()
+
+       def __str__(self):
+               return self.description[0:10]
+
+       class Admin:
+               pass
diff --git a/influences/views.py b/influences/views.py
new file mode 100644 (file)
index 0000000..4450efa
--- /dev/null
@@ -0,0 +1,23 @@
+from django.shortcuts import render_to_response
+from django.shortcuts import get_object_or_404
+from ee.influences.models import Character
+from ee.influences.models import Influence
+from django import newforms as forms
+
+class AddInfluenceForm(forms.Form):
+       contact     = forms.CharField(max_length=255, help_text='Which contact will you ask?')
+       description = forms.CharField(help_text='What do you want to achieve')
+
+def addinfluence(request, character_id):
+       character = get_object_or_404(Character, id=character_id)
+       message = None
+       if (request.method == "POST"):
+               f = AddInfluenceForm(request.POST)
+               if (f.is_valid()):
+                       inf = character.influence_set.create(contact = f.clean_data['contact'], description = f.clean_data['description'])
+                       message = "Influence added"
+                       f = None
+       else:
+               f = AddInfluenceForm()
+
+       return render_to_response('influences/character_addinfluence.html', {'character' : character, 'message' : message, 'form' : f})
diff --git a/manage.py b/manage.py
new file mode 100755 (executable)
index 0000000..bcdd55e
--- /dev/null
+++ b/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/settings.py b/settings.py
new file mode 100644 (file)
index 0000000..574b395
--- /dev/null
@@ -0,0 +1,90 @@
+# Django settings for ee project.
+
+from dbsettings import *
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+    # ('Your Name', 'your_email@domain.com'),
+)
+
+MANAGERS = ADMINS
+
+PHPBB_DATABASE_NAME = 'ee_forum'
+
+# Local time zone for this installation. Choices can be found here:
+# http://www.postgresql.org/docs/8.1/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
+# although not all variations may be possible on all operating systems.
+# If running in a Windows environment this must be set to the same as your
+# system time zone.
+TIME_ZONE = 'Europe/Amsterdam'
+
+# Language code for this installation. All choices can be found here:
+# http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
+# http://blogs.law.harvard.edu/tech/stories/storyReader$15
+LANGUAGE_CODE = 'en-us'
+
+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
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+MEDIA_ROOT = ''
+
+# URL that handles the media served from MEDIA_ROOT.
+# Example: "http://media.lawrence.com"
+MEDIA_URL = ''
+
+# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
+# trailing slash.
+# Examples: "http://foo.com/media/", "/media/".
+ADMIN_MEDIA_PREFIX = '/media/'
+
+# Make this unique, and don't share it with anybody.
+SECRET_KEY = '6-zo+-1@-342%k4%82aw#kxr4f%5w00xhwby5$&fa@+!dh@(2='
+
+# 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',
+#     'django.template.loaders.eggs.load_template_source',
+)
+
+MIDDLEWARE_CLASSES = (
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.middleware.doc.XViewMiddleware',
+)
+
+ROOT_URLCONF = 'ee.urls'
+
+TEMPLATE_DIRS = (
+    # 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.
+       '/home/matthijs/docs/src/django/ee/templates',
+)
+
+INSTALLED_APPS = (
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.sites',
+    'django.contrib.admin',
+       'ee.events',
+       'ee.influences',
+       'ee.base',
+)
+
+TEMPLATE_CONTEXT_PROCESSORS = (
+       "django.core.context_processors.auth",
+       "django.core.context_processors.debug",
+       "django.core.context_processors.i18n",
+)
+
+LOGIN_URL = "/accounts/login/"
diff --git a/templates/base/base.html b/templates/base/base.html
new file mode 100644 (file)
index 0000000..ab807ba
--- /dev/null
@@ -0,0 +1,8 @@
+<html>
+<head>
+</head>
+<body>
+{% block content %}
+{% endblock %}
+</body>
+</html>
diff --git a/templates/base/login.html b/templates/base/login.html
new file mode 100644 (file)
index 0000000..834dac4
--- /dev/null
@@ -0,0 +1,19 @@
+{% extends "base/base.html" %}
+
+{% block content %}
+
+{% if form.has_errors %}
+<p>Your username and password didn't match. Please try again.</p>
+{% endif %}
+
+<form method="post" action=".">
+<table>
+<tr><td><label for="id_username">Username:</label></td><td>{{ form.username }}</td></tr>
+<tr><td><label for="id_password">Password:</label></td><td>{{ form.password }}</td></tr>
+</table>
+
+<input type="submit" value="login" />
+<input type="hidden" name="next" value="{{ next }}" />
+</form>
+
+{% endblock %}
diff --git a/templates/events/event/detail.html b/templates/events/event/detail.html
new file mode 100644 (file)
index 0000000..af5d0bf
--- /dev/null
@@ -0,0 +1,2 @@
+<h1>{{ event.name }}</h1>
+<i>{{ event.title}}</i>
diff --git a/templates/influences/character/detail.html b/templates/influences/character/detail.html
new file mode 100644 (file)
index 0000000..509e431
--- /dev/null
@@ -0,0 +1,22 @@
+{% character = object %}
+<h1>{{ character.name }}</h1>
+Influences voor {{ character.name }}
+<ul>
+{% for influence in influences %}
+       <li>{{ influence }}</li>
+{% endfor %}
+</ul>
+
+<form action="addinfluence/" method="post">
+       <table>
+               <tr>
+                       <td>Contact:</td>
+                       <td><input type="text" name="contact" /></td>
+               </tr>
+               <tr>
+                       <td>Influence:</td>
+                       <td><textarea name="description"></textarea></td>
+               </tr>
+       </table>
+       <input type="submit" value="Indienen"/>
+</form>
diff --git a/templates/influences/character_addinfluence.html b/templates/influences/character_addinfluence.html
new file mode 100644 (file)
index 0000000..964a841
--- /dev/null
@@ -0,0 +1,13 @@
+<h1><a href="/influences/character/{{ character.id }}/">{{ character.name }}</a></h1>
+<p>Influence toevoegen</p>
+{% if message %}
+{{ message }}
+{% endif %}
+{% if form %}
+<form method="POST">
+<table>
+{{ form.as_table }}
+</table>
+<input type="submit"/>
+</form>
+{% endif %}
diff --git a/templates/influences/character_detail.html b/templates/influences/character_detail.html
new file mode 100644 (file)
index 0000000..56c60cd
--- /dev/null
@@ -0,0 +1,9 @@
+<h1>{{ object.name }}</h1>
+Influences voor {{ object.name }}
+<ul>
+{% for influence in object.influence_set.objects.all %}
+       <li>{{ influence }}</li>
+{% endfor %}
+</ul>
+
+<a href="/influences/character/{{ object.id }}/addinfluence">Influence toevoegen</a>
diff --git a/templates/influences/character_list.html b/templates/influences/character_list.html
new file mode 100644 (file)
index 0000000..8d417b5
--- /dev/null
@@ -0,0 +1,9 @@
+{% if object_list %}
+       <ul>
+       {% for character in object_list %}
+               <li><a href="character/{{ character.id }}/">{{ character.name }}</a></li>
+       {% endfor %}
+       </ul>
+{% else %}
+       <p>Geen karakters.</p>
+{% endif %}
diff --git a/templates/influences/index.html b/templates/influences/index.html
new file mode 100644 (file)
index 0000000..0e5ab70
--- /dev/null
@@ -0,0 +1,9 @@
+{% if characters %}
+       <ul>
+       {% for character in characters %}
+               <li><a href="character/{{ character.id }}/">{{ character.name }}</a></li>
+       {% endfor %}
+       </ul>
+{% else %}
+       <p>Geen karakters.</p>
+{% endif %}
diff --git a/urls.py b/urls.py
new file mode 100644 (file)
index 0000000..24a9ec1
--- /dev/null
+++ b/urls.py
@@ -0,0 +1,17 @@
+from django.conf.urls.defaults import *
+from ee.influences.models import Character
+
+chars_dict = {
+       'queryset': Character.objects.all(),
+}
+urlpatterns = patterns('',
+    (r'^admin/', include('django.contrib.admin.urls')),
+       (r'^events/event/(?P<event_id>\d+)/$', 'ee.events.views.event.detail'),
+       (r'^events/event/(?P<event_id>\d+)/regs$', 'ee.events.views.event.regs'),
+       (r'^influences/$', 'django.views.generic.list_detail.object_list', chars_dict),
+       (r'^influences/character/(?P<object_id>\d+)/$', 'django.views.generic.list_detail.object_detail', chars_dict),
+       (r'^influences/character/(?P<character_id>\d+)/addinfluence/$', 'ee.influences.views.addinfluence'),
+       (r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'base/login.html'}),
+       (r'^accounts/logout/$', 'django.contrib.auth.views.logout_then_login', {'template_name': 'base/login.html'}),
+)