changeset 127:382af80db050

Rename of temp dir to personasbackend
author Atul Varma <varmaa@toolness.com>
date Wed, 02 Apr 2008 11:59:58 -0700
parents cb128e025ae9
children 9bcc77e37c19
files PersonasBackendTemp/__init__.py PersonasBackendTemp/manage.py PersonasBackendTemp/personas/__init__.py PersonasBackendTemp/personas/ajax.py PersonasBackendTemp/personas/fixtures/initial_data.xml PersonasBackendTemp/personas/forms.py PersonasBackendTemp/personas/json_feeds.py PersonasBackendTemp/personas/models.py PersonasBackendTemp/personas/sections.py PersonasBackendTemp/personas/templates/personas/base.html PersonasBackendTemp/personas/templates/personas/edit.html PersonasBackendTemp/personas/templates/personas/home.html PersonasBackendTemp/personas/templates/personas/legacy_persona.xul PersonasBackendTemp/personas/templates/personas/list.html PersonasBackendTemp/personas/templates/personas/logged_out.html PersonasBackendTemp/personas/templates/personas/login.html PersonasBackendTemp/personas/templates/personas/todo.html PersonasBackendTemp/personas/tests.py PersonasBackendTemp/personas/urls.py PersonasBackendTemp/personas/views.py PersonasBackendTemp/settings.py PersonasBackendTemp/urls.py PersonasBackendTemp/utils.py PersonasBackendTemp/weaveproxyauth.py personasbackend/__init__.py personasbackend/manage.py personasbackend/personas/__init__.py personasbackend/personas/ajax.py personasbackend/personas/fixtures/initial_data.xml personasbackend/personas/forms.py personasbackend/personas/json_feeds.py personasbackend/personas/models.py personasbackend/personas/sections.py personasbackend/personas/templates/personas/base.html personasbackend/personas/templates/personas/edit.html personasbackend/personas/templates/personas/home.html personasbackend/personas/templates/personas/legacy_persona.xul personasbackend/personas/templates/personas/list.html personasbackend/personas/templates/personas/logged_out.html personasbackend/personas/templates/personas/login.html personasbackend/personas/templates/personas/todo.html personasbackend/personas/tests.py personasbackend/personas/urls.py personasbackend/personas/views.py personasbackend/settings.py personasbackend/urls.py personasbackend/utils.py personasbackend/weaveproxyauth.py
diffstat 44 files changed, 1444 insertions(+), 1444 deletions(-) [+]
line wrap: on
line diff
--- a/PersonasBackendTemp/manage.py	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-#!/usr/bin/env 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)
--- a/PersonasBackendTemp/personas/ajax.py	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-from django.http import HttpResponse
-from django.shortcuts import get_object_or_404
-
-from PersonasBackend.personas import models
-
-def report_selection( request, persona_id ):
-    persona = get_object_or_404( models.Persona, id=persona_id )
-    persona.popularity += 1
-    persona.save()
-    return HttpResponse()
--- a/PersonasBackendTemp/personas/fixtures/initial_data.xml	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<django-objects version="1.0"><object pk="1" model="personas.category"><field type="CharField" name="name">Other</field></object><object pk="2" model="personas.category"><field type="CharField" name="name">Geometric</field></object><object pk="3" model="personas.category"><field type="CharField" name="name">Sports</field></object><object pk="4" model="personas.category"><field type="CharField" name="name">Scenery</field></object><object pk="5" model="personas.category"><field type="CharField" name="name">Nature</field></object><object pk="6" model="personas.category"><field type="CharField" name="name">Holidays</field></object><object pk="7" model="personas.category"><field type="CharField" name="name">Foxkeh</field></object><object pk="8" model="personas.category"><field type="CharField" name="name">Firefox</field></object><object pk="1" model="personas.persona"><field type="CharField" name="name">Firefox Logo</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">8</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=firefox_b</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="2" model="personas.persona"><field type="CharField" name="name">Firefox Flicks</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">8</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=firefox_flicks</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="3" model="personas.persona"><field type="CharField" name="name">Mozilla Classic</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">8</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=mozilla_classic</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="4" model="personas.persona"><field type="CharField" name="name">Foxkeh Straw</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_straw</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="5" model="personas.persona"><field type="CharField" name="name">Foxkeh Hanami</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_hanami</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="6" model="personas.persona"><field type="CharField" name="name">Foxkeh Hinimatsuri</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_hinimatsuri</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="7" model="personas.persona"><field type="CharField" name="name">Foxkeh Kodomo No Hi</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_kodomo_no_hi</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="8" model="personas.persona"><field type="CharField" name="name">Foxkeh Setsubun</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_setsubun</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="9" model="personas.persona"><field type="CharField" name="name">Foxkeh Giant Butterbur</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_butterbur</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="10" model="personas.persona"><field type="CharField" name="name">Foxkeh Tanabata</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_tanabata</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="11" model="personas.persona"><field type="CharField" name="name">Viva Firefox</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">8</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=viva</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="12" model="personas.persona"><field type="CharField" name="name">Developer Kit</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">8</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=kit</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="13" model="personas.persona"><field type="CharField" name="name">Tranquility</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">5</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=tranquility</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="14" model="personas.persona"><field type="CharField" name="name">California Sunset</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">4</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=california_sunset</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="15" model="personas.persona"><field type="CharField" name="name">Wood Paneling</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=wood_paneling</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="16" model="personas.persona"><field type="CharField" name="name">Hearts</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=hearts</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="17" model="personas.persona"><field type="CharField" name="name">Blue Spheres</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=blue_spheres</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="18" model="personas.persona"><field type="CharField" name="name">Les Diablerets</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">4</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=les_diablerets</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="19" model="personas.persona"><field type="CharField" name="name">Seagull</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">4</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=seagull</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="20" model="personas.persona"><field type="CharField" name="name">Verdelet</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">4</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=verdelet</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="21" model="personas.persona"><field type="CharField" name="name">Green Wave</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=green_wave</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="22" model="personas.persona"><field type="CharField" name="name">Golf</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">3</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=golf</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="23" model="personas.persona"><field type="CharField" name="name">Basketball</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">3</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=bball</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="24" model="personas.persona"><field type="CharField" name="name">Antique Wallpaper</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=antique_wallpaper</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="25" model="personas.persona"><field type="CharField" name="name">Bamboo</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">5</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=bamboo</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="26" model="personas.persona"><field type="CharField" name="name">Plaid</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">2</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=plaid</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="27" model="personas.persona"><field type="CharField" name="name">Soccer</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">3</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=soccer</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="28" model="personas.persona"><field type="CharField" name="name">Suede</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=suede</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="29" model="personas.persona"><field type="CharField" name="name">Aquarium</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">5</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=aquarium</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="30" model="personas.persona"><field type="CharField" name="name">Dialogonal Lines</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">2</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=diagonal_lines</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="31" model="personas.persona"><field type="CharField" name="name">Dots</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">2</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=dots</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="32" model="personas.persona"><field type="CharField" name="name">Golden Gate Bridge</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">4</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=golden_gate_bridge</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="33" model="personas.persona"><field type="CharField" name="name">Grass</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">5</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=grass</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="34" model="personas.persona"><field type="CharField" name="name">Foxkeh Green Winter</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_green_winter</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="35" model="personas.persona"><field type="CharField" name="name">Jellyfish</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">5</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=jellyfish</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="36" model="personas.persona"><field type="CharField" name="name">Yosemite</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">4</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=yosemite</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="37" model="personas.persona"><field type="CharField" name="name">Snowman</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">6</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=snowman</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="38" model="personas.persona"><field type="CharField" name="name">Snowflakes</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">6</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=snowflakes</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="39" model="personas.persona"><field type="CharField" name="name">Reindeer</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">6</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=reindeer</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="40" model="personas.persona"><field type="CharField" name="name">Foxkeh Canoe</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_canoe</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="41" model="personas.persona"><field type="CharField" name="name">Foxkeh Helloween</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_helloween</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="42" model="personas.persona"><field type="CharField" name="name">Foxkeh Susuki</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_susuki</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="43" model="personas.persona"><field type="CharField" name="name">Foxkeh Hanabi</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_hanabi</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="44" model="personas.persona"><field type="CharField" name="name">Paper</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=paper</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="45" model="personas.persona"><field type="CharField" name="name">Winter</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">6</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=winter</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="46" model="personas.persona"><field type="CharField" name="name">Leather</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=leather</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="47" model="personas.persona"><field type="CharField" name="name">Niagra Falls</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">4</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=niagra_falls</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="48" model="personas.persona"><field type="CharField" name="name">Groovy Blue</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=groovy_blue</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="49" model="personas.persona"><field type="CharField" name="name">Groovy Hearts</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=groovy_hearts</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="50" model="personas.persona"><field type="CharField" name="name">Groovy Orange</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=groovy_orange</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="51" model="personas.persona"><field type="CharField" name="name">Groovy Pink</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=groovy_pink</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object></django-objects>
--- a/PersonasBackendTemp/personas/forms.py	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-import django.newforms as forms
-from PersonasBackend.personas import models
-
-class PersonaForm( forms.ModelForm ):
-    """
-    Form given to normal users who don't have the permission to
-    publish Personas.
-    """
-
-    class Meta:
-        model = models.Persona
-        exclude = ["owner", "date_published", "popularity", "status"]
-
-    agree_to_terms = forms.BooleanField(
-        label = "I agree to the terms of use.",
-        # TODO: setting required to True doesn't seem to have any effect,
-        # but the Django docs say it should ensure that the checkbox
-        # is filled out.
-        required = True,
-        help_text = ("Terms of use: I agree that Mozilla is providing "
-                     "a service by hosting the "
-                     "content I am submitting, and that they are in no "
-                     "way responsible for any damages that occur as "
-                     "a result of hosting said content.")
-        )
-
-    def _color_cleaner( self, field ):
-        models.ensure_color_is_valid(
-            self.cleaned_data[field],
-            error_class = forms.ValidationError
-            )
-        return self.cleaned_data[field]
-
-    def clean_text_color( self ):
-        return self._color_cleaner( "text_color" )
-
-    def clean_accent_color( self ):
-        return self._color_cleaner( "accent_color" )
-
-    def clean( self ):
-        if not self.cleaned_data["agree_to_terms"]:
-            raise forms.ValidationError(
-                "You must agree to the terms of service to "
-                "submit your Persona."
-                )
-
-        return self.cleaned_data
--- a/PersonasBackendTemp/personas/json_feeds.py	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-from django.http import HttpResponse
-from django.utils import simplejson
-
-from PersonasBackend.personas import models
-
-NEW_MENU_ID = "personas-new-menu"
-POPULAR_MENU_ID = "personas-popular-menu"
-
-def _makeJsonResponse( obj ):
-    json = simplejson.dumps( obj, indent=4 )
-    response = HttpResponse( json )
-    response["Content-Type"] = "text/plain"
-    return response
-
-def categories( request ):
-    categoryDicts = [
-        {"label": "Most Popular", "id" : POPULAR_MENU_ID,
-         "type" : "list", "parent" : "top" },
-	{"label": "Recent", "id" : "personas-recent-menu",
-         "type" : "recent", "parent" : "top" },
-	{"label": "New", "id" : NEW_MENU_ID,
-         "type" : "list", "parent" : "top" },
-	{"label": "All", "id" : "personas-category-menu",
-         "type" : "category", "parent" : "top" },
-        ]
-
-    for category in models.Category.objects.all():
-        categoryDicts.append(
-            {"label" : category.name,
-             "id" : category.json_id,
-             "type" : "list",
-             "parent" : "personas-category-menu"}
-            )
-
-    return _makeJsonResponse( {"categories" : categoryDicts} )
-
-def personas( request ):
-    personaDicts = []
-
-    isPopular = {}
-    isNew = {}
-
-    published = models.Persona.objects.filter( status="published" )
-
-    for persona in published.order_by( "-popularity" )[:10]:
-        isPopular[persona.id] = True
-
-    for persona in published.order_by( "-date_published" )[:10]:
-        isNew[persona.id] = True
-
-    for persona in published:
-        categories = [persona.category.json_id]
-        if persona.id in isPopular:
-            categories.append( POPULAR_MENU_ID )
-        if persona.id in isNew:
-            categories.append( NEW_MENU_ID )
-
-        personaDicts.append(
-            {"label" : persona.name,
-             "id" : persona.json_id,
-             "textColor" : persona.text_color,
-             "accentColor" : persona.accent_color,
-             "baseURL" : persona.resolved_url,
-             "menu" : ",".join( categories ),
-             "preview" : "yes"}
-            )
-
-    return _makeJsonResponse( {"personas" : personaDicts} )
--- a/PersonasBackendTemp/personas/models.py	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,604 +0,0 @@
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-# 
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-# 
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-# 
-# The Original Code is PersonasBackend.
-# 
-# The Initial Developer of the Original Code is Mozilla.
-# Portions created by the Initial Developer are Copyright (C) 2008
-# the Initial Developer. All Rights Reserved.
-# 
-# Contributor(s):
-#   Atul Varma <atul@mozilla.org>
-# 
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-# 
-# ***** END LICENSE BLOCK *****
-
-"""
-models.py
-
-This module contains the models for the Personas application.
-
-Note that changes to Personas are automatically revision-controlled.
-Among other things, this allows for:
-
-  (A) A humane user interface that supports undo operations.
-
-  (B) A workflow that allows for Personas to be changed by a submitter
-      and reviewed while the original, unchanged Persona remains
-      published and accessible by clients.
-"""
-
-import datetime
-
-from django.db import models
-from django.core.urlresolvers import reverse
-from django.contrib.auth.models import User
-from django.core.validators import ValidationError
-
-from PersonasBackend.utils import make_absolute_url
-
-MAX_COLOR_LENGTH = 7
-
-def parse_personas_view_url( url ):
-    """
-    TODO: Document this.
-
-    Examples:
-
-      >>> parse_personas_view_url( "http://personas-view/blargy?thing=blarg" )
-      {'kwargs': {'thing': 'blarg'}, 'view': 'blargy'}
-
-      >>> parse_personas_view_url( "http://porsonas-view/blargy?thing=blarg" )
-    """
-
-    if not url.startswith( "http://personas-view/" ):
-        return None
-
-    import urlparse
-    import cgi
-
-    _, _, path, _, query, _ = urlparse.urlparse( url )
-    view = path[1:]
-    kwargs = cgi.parse_qs( query )
-
-    # It is completely ridiculous that we have to do this, but
-    # apparently we do, because django's reverse() doesn't like being
-    # passed dictionaries with unicode keys.
-    string_kwargs = {}
-    for key in kwargs:
-        string_kwargs[str(key)] = str(kwargs[key][0])
-
-    return {'view':view, 'kwargs':string_kwargs}
-
-def ensure_color_is_valid( color,
-                           error_class = ValidationError ):
-    """
-    Given a color string, raises a ValidationError if the color isn't
-    formatted properly.
-
-    Examples:
-
-      >>> ensure_color_is_valid('')
-
-      >>> ensure_color_is_valid('blah')
-      Traceback (most recent call last):
-      ...
-      ValidationError: [u"The color must start with a '#'."]
-
-      >>> ensure_color_is_valid('#aaaaaaa')
-      Traceback (most recent call last):
-      ...
-      ValidationError: [u'The color is too long.']
-
-      >>> ensure_color_is_valid('#aaaaa')
-      Traceback (most recent call last):
-      ...
-      ValidationError: [u'The color is too short.']
-
-      >>> ensure_color_is_valid('#aaazaa')
-      Traceback (most recent call last):
-      ...
-      ValidationError: [u"The character 'z' isn't valid."]
-
-      >>> ensure_color_is_valid('#aaaaaa')
-      >>> ensure_color_is_valid('#FFFF11')
-    """
-
-    HEX_CHARS = "0123456789abcdef"
-
-    if not color:
-        return
-
-    if not color.startswith("#"):
-        raise error_class( "The color must start with a '#'." )
-    if len(color) > MAX_COLOR_LENGTH:
-        raise error_class( "The color is too long." )
-    if len(color) < MAX_COLOR_LENGTH:
-        raise error_class( "The color is too short." )
-    for char in color.lower()[1:MAX_COLOR_LENGTH]:
-        if char not in HEX_CHARS:
-            raise error_class( "The character '%s' isn't valid." % char )
-
-class Category(models.Model):
-    """
-    Represents a Personas category; every Persona can be assigned one,
-    and only one, category.
-    """
-
-    class Admin:
-        pass
-
-    class Meta:
-        verbose_name_plural = "categories"
-
-    name = models.CharField(
-        "Category name",
-        max_length=50,
-        unique=True,
-        )
-
-    def __str__(self):
-        return self.name
-
-    def _get_json_id( self ):
-        return "personas-category-%d" % self.id
-
-    json_id = property( _get_json_id )
-
-class Persona(models.Model):
-    """
-    Encapsulates the most recent revision of a Persona.
-    """
-
-    class Admin:
-        list_display = ["name", "date_updated", "status"]
-
-    class Meta:
-        permissions = (
-            ("can_publish", "Can publish"),
-            )
-
-    MAX_NAME_LENGTH = 50
-
-    name = models.CharField(
-        max_length=MAX_NAME_LENGTH,
-        blank=False,
-        )
-
-    owner = models.ForeignKey(
-        User,
-        help_text=("The user who owns this persona can make "
-                   "changes to it."),
-        related_name="owned_personas",
-        # TODO: Consider making this null=False.  Keeping it true
-        # makes it easier to write tests, though.
-        null=True,
-        blank=True,
-        )
-
-    category = models.ForeignKey(
-        Category,
-        related_name="personas",
-        null=False,
-        )
-
-    description = models.TextField(
-        help_text = "HTML is allowed.",
-        blank=False,
-        )
-
-    url = models.URLField(
-        "Persona URL",
-        help_text=("URL for the content that will be placed behind "
-                   "the browser's chrome."),
-        verify_exists=False,
-        blank=False,
-        )
-
-    def __get_resolved_url(self):
-        viewinfo = parse_personas_view_url( self.url )
-        if not viewinfo:
-            return self.url
-        else:
-            return make_absolute_url( reverse(
-                    viewinfo['view'],
-                    kwargs = viewinfo['kwargs']
-                    ) )
-
-    resolved_url = property(__get_resolved_url)
-
-    text_color = models.CharField(
-        help_text=("The RGB color, as a #RRGGBB color hash, "
-                   "of the color of text that will be displayed "
-                   "on the persona."),
-        max_length=MAX_COLOR_LENGTH,
-        validator_list=[ensure_color_is_valid],
-        blank=True
-        )
-
-    accent_color = models.CharField(
-        help_text=("The RGB color, as a #RRGGBB color hash, "
-                   "of the accent colors that will be displayed "
-                   "on the persona."),
-        max_length=MAX_COLOR_LENGTH,
-        validator_list=[ensure_color_is_valid],
-        blank=True,
-        )
-
-    date_published = models.DateTimeField(
-        help_text=("The date that the Persona was last published."),
-        null=True,
-        editable=True,
-        )
-
-    date_updated = models.DateTimeField(
-        # This ensures that this field is updated with the current
-        # timestamp whenever the record is changed.
-        auto_now=True,
-        null=False,
-        editable=False,
-        )
-
-    updater = models.ForeignKey(
-        User,
-        help_text="The user who made this revision.",
-        related_name="changed_personas",
-        null=True,
-        editable=False
-        )
-
-    revision = models.PositiveIntegerField(
-        "Revision number",
-        help_text=("This number is incremented whenever the Persona "
-                   "is changed."),
-        null=False,
-        editable=False,
-        )
-
-    popularity = models.PositiveIntegerField(
-        "Popularity",
-        help_text=("A number indicating how popular the Persona is; the "
-                   "higher this value, the better."),
-        default=0,
-        null=False,
-        )
-
-    MAX_STATUS_LENGTH = 10
-
-    status = models.CharField(
-        max_length=MAX_STATUS_LENGTH,
-        choices=(("published", "Published"),
-                 ("unpublished", "Unpublished"),
-                 ("deleted", "Deleted")),
-        blank=False,
-        help_text=("Status of the Persona; can be deleted, published, "
-                   "or unpublished (i.e., pending for review).")
-        )
-
-    def __str__(self):
-        return self.name
-
-    # These are the properties of this record that are "versioned",
-    # i.e. tracked by built-in revision control when changed.
-    VERSIONED_PROPERTIES = (
-        "name",
-        "owner",
-        "category",
-        "description",
-        "url",
-        "text_color",
-        "accent_color",
-        "status",
-        )
-
-    def __make_new_revision(self):
-        """
-        Detect if any of our versioned properties have changed, and if
-        so, make a new revision.
-        """
-
-        original = Persona.objects.get(id=self.id)
-
-        assert original.revision == self.revision
-
-        delta = {}
-        for attr in self.VERSIONED_PROPERTIES:
-            origValue = getattr(original, attr)
-            newValue = getattr(self, attr)
-            if origValue != newValue:
-                delta[attr] = origValue
-        if delta:
-            rev = Revision(
-                revision_of = original,
-                date_updated = original.date_updated,
-                updater = original.updater,
-                revision = original.revision
-                )
-
-            for attr in delta:
-                setattr(rev, attr, delta[attr])
-                setattr(rev, "has_%s" % attr, True)
-            rev.save()
-
-            self.revision += 1
-
-    def save( self, updater=None ):
-        """
-        Saves the object.  If a versioned property is changed, a new
-        revision is generated automatically.
-
-        Example:
-
-          >>> p = Persona(name='Test Persona',
-          ...             description='Thos is a test.',
-          ...             url='http://blarg.com',
-          ...             category=Category.objects.get(name='Other'))
-          >>> p.save()
-          >>> p.revision
-          0
-          >>> p.revisions.all()
-          []
-
-          >>> p.description = 'This is a test.'
-          >>> p.url = 'http://blarg2.com'
-          >>> p.save()
-          >>> p.revision
-          1
-          >>> p.revisions.all()
-          [<Revision: Test Persona - r0>]
-          >>> p.revisions.get(revision=0).description
-          u'Thos is a test.'
-          >>> p.revisions.get(revision=0).url
-          u'http://blarg.com'
-        """
-
-        if updater:
-            self.updater = updater
-        else:
-            # We were probably saved through the admin interface,
-            # which saves its own separate history of changes.
-            self.updater = None
-
-        if self.id == None:
-            # We're a brand-new Persona.
-            self.revision = 0
-            if not self.owner:
-                self.owner = self.updater
-            assert self.owner == self.updater
-            if not self.status:
-                if ( self.updater and
-                     self.updater.has_perm( "personas.can_publish" ) ):
-                    # If the person creating the Persona can publish
-                    # Personas, mark this new Persona as published, by
-                    # default.
-                    self.status = "published"
-                else:
-                    # Otherwise, mark this new Persona as unpublished by
-                    # default.
-                    self.status = "unpublished"
-            if self.status == "published":
-                self.date_published = datetime.datetime.now()
-        else:
-            # We're an existing Persona that's being modified.
-
-            if self.updater:
-                if not self.can_user_edit( self.updater ):
-                    # The user can't actually edit this Persona, reject
-                    # the change.  View logic should've prevented this
-                    # from ever being the case, so we're going to be
-                    # ungraceful here.
-                    raise AssertionError( "User can't edit this persona." )
-
-                if ( self.status == "published" and
-                     not self.updater.has_perm( "personas.can_publish" ) ):
-                    # The Persona is currently published, but a user
-                    # without publishing permissions has just changed it,
-                    # so mark it as unpublished so an editor can review it
-                    # before re-publishing it.
-
-                    self.status = "unpublished"
-
-            original = Persona.objects.get(id=self.id)
-
-            if ( (original.status != self.status) and 
-                 (self.status == "published") ):
-                self.date_published = datetime.datetime.now()
-
-            self.__make_new_revision()
-
-        super(Persona, self).save()
-
-    def can_user_edit( self, user ):
-        """
-        Returns whether the given User can edit this Persona.
-        """
-
-        return ( user.has_perm( "personas.can_publish" ) or
-                 self.owner == user )
-
-    def _get_json_id( self ):
-        return "persona-%d" % self.id
-
-    json_id = property( _get_json_id )
-
-class Revision(models.Model):
-    """
-    Represents an old revision of a Persona.
-
-    This record only stores a "reverse delta" relative to the revision
-    that follows it; for instance, if a user changes a Persona at
-    revision 0 by modifying its description, then the Revision record
-    for revision 0 will contain only the description for the Persona
-    at that revision, since all other properties can be obtained by
-    looking at revision 1.  In this way, the complete "picture" of
-    revision 0 can be reconstructed by starting at the record for
-    revision 0 and traveling to newer revisions until every field of
-    the Persona has been populated.
-    """
-
-    class Meta:
-        unique_together = (("revision_of", "revision"),)
-        ordering = ["revision"]
-
-    # Auto-generated fields
-
-    revision_of = models.ForeignKey(
-        Persona,
-        verbose_name="The Persona that this record is an old revision of",
-        related_name="revisions",
-        null=False,
-        )
-
-    date_updated = models.DateTimeField(
-        null=False,
-        )
-
-    updater = models.ForeignKey(
-        User,
-        related_name="previously_changed_revisions",
-        null=True,
-        )
-
-    revision = models.PositiveIntegerField(
-        null=False,
-        )
-
-    # Versioned fields
-
-    for attr in Persona.VERSIONED_PROPERTIES:
-        locals()["has_%s" % attr] = models.BooleanField(default=False)
-    del attr
-
-    name = models.CharField(
-        max_length=Persona.MAX_NAME_LENGTH,
-        null=True,
-        )
-
-    owner = models.ForeignKey(
-        User,
-        related_name="previously_owned_personas",
-        null=True,
-        )
-
-    category = models.ForeignKey(
-        Category,
-        related_name="revisions",
-        null=True,
-        )
-
-    description = models.TextField(
-        null=True,
-        )
-
-    url = models.URLField(
-        null=True,
-        )
-
-    text_color = models.CharField(
-        max_length=MAX_COLOR_LENGTH,
-        null=True,
-        )
-
-    accent_color = models.CharField(
-        max_length=MAX_COLOR_LENGTH,
-        null=True,
-        )
-
-    status = models.CharField(
-        max_length=Persona.MAX_STATUS_LENGTH,
-        null=True,
-        )
-
-    def __str__(self):
-        return "%s - r%s" % (self.revision_of.name, self.revision)
-
-    def resolve(self):
-        """
-        Fills-in (resolves) all the fields of the revision by
-        computing reverse deltas to future/present revisions.
-
-          >>> p = Persona(name='Test Persona',
-          ...             description='Thos is a test.',
-          ...             url='http://www.blarg.com',
-          ...             category=Category.objects.get(name='Other'))
-          >>> p.save()
-          >>> p.description = 'This is a test.'
-          >>> p.save()
-          >>> p.name = 'Blarg'
-          >>> p.save()
-          >>> p.description = "This is a great test."
-          >>> p.save()
-          >>> p.url = "http://www.test.com"
-          >>> p.save()
-          >>> r = p.revisions.get(revision=0)
-          >>> r.resolve()
-          >>> r.name
-          u'Test Persona'
-          >>> r.description
-          u'Thos is a test.'
-          >>> r.url
-          u'http://www.blarg.com'
-        """
-
-        persona = self.revision_of
-        futureRevs = persona.revisions.filter(revision__gt=self.revision)
-        attrsLeft = [ attr for attr in Persona.VERSIONED_PROPERTIES
-                      if getattr(self, attr) == None ]
-        for rev in futureRevs:
-            attrsFound = []
-            for attr in attrsLeft:
-                if getattr(rev, "has_%s" % attr):
-                    setattr(self, attr, getattr(rev, attr))
-                    attrsFound.append(attr)
-            if attrsFound:
-                attrsLeft = [ attr for attr in attrsLeft
-                              if attr not in attrsFound ]
-                if not attrsLeft:
-                    break
-        for attr in attrsLeft:
-            setattr(self, attr, getattr(persona, attr))
-
-    def save(self):
-        """
-        The save method for a Revision can only be called once,
-        because Revision objects are meant to be immutable:
-
-          >>> p = Persona(name='Test Persona',
-          ...             url='http://www.blah.com',
-          ...             category=Category.objects.get(name='Other'))
-          >>> p.save()
-          >>> p.description = 'This is a test.'
-          >>> p.save()
-          >>> r = p.revisions.get(revision=0)
-          >>> r.status = "deleted"
-          >>> r.save()
-          Traceback (most recent call last):
-          ...
-          AssertionError: Revisions are immutable
-        """
-
-        if self.id == None:
-            super(Revision, self).save()
-        else:
-            raise AssertionError("Revisions are immutable")
--- a/PersonasBackendTemp/personas/sections.py	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-from django.core import urlresolvers
-from django.contrib.sites.models import Site
-
-class Sections( object ):
-    def __init__( self, *sections ):
-        self.sections = sections
-        self.sidebar_entries = []
-        self.views = {}
-        self.names = {}
-        for section in self.sections:
-            if section.in_sidebar:
-                self.sidebar_entries.append( section )
-            assert section.name not in self.names
-            self.names[section.name] = section
-            assert section.view not in self.views
-            self.views[section.view] = section
-
-            curr_section = section
-            while curr_section.parent_name:
-                curr_parent = self.names[curr_section.parent_name]
-                section.parents.append( curr_parent )
-                curr_section = curr_parent
-
-class Section( object ):
-    def __init__( self, name, view, in_sidebar = False,
-                  parent_name = None ):
-        self.name = name
-        self.view = view
-        self.in_sidebar = in_sidebar
-        self.parent_name = parent_name
-
-        # This will be filled out by the parent Sections object.
-        self.parents = []
-
-    def url( self ):
-        return urlresolvers.reverse( self.view )
-
-sections = Sections(
-    Section( "Home",
-             "PersonasBackend.personas.views.home_view",
-             in_sidebar = True ),
-    Section( "Browse",
-             "PersonasBackend.personas.views.list_view",
-             parent_name = "Home",
-             in_sidebar = True ),
-    Section( "Create",
-             "PersonasBackend.personas.views.new_view",
-             parent_name = "Home",
-             in_sidebar = True ),
-    Section( "Edit",
-             "PersonasBackend.personas.views.edit_view",
-             parent_name = "Home" ),
-    Section( "Log in",
-             "django.contrib.auth.views.login",
-             parent_name = "Home" ),
-    Section( "Log out",
-             "django.contrib.auth.views.logout",
-             parent_name = "Home" )
-    )
-
-def context( request ):
-    viewfunc, args, kwargs = urlresolvers.resolve( request.path )
-    viewname = ".".join( [viewfunc.__module__,
-                          viewfunc.__name__] )
-    return {
-        "site_name" : Site.objects.get_current().name,
-        "sidebar_entries" : sections.sidebar_entries,
-        "section" : sections.views.get( viewname, None )
-        }
--- a/PersonasBackendTemp/personas/templates/personas/base.html	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <meta http-equiv="Content-Type"
-          content="text/html; charset=iso-8859-1" />
-    <title>{{ section.name }} :: {{ site_name }}</title>
-    <link rel="stylesheet"
-          type="text/css"
-          href="{{ MEDIA_URL }}css/otherpages.css" />
-    <link rel="shortcut icon" href="{{ MEDIA_URL }}img/favicon.ico"
-          type="image/x-icon" />
-  </head>
-<body>
-  <div id="content">
-    <div id="top">
-
-      <img src="http://labs.mozilla.com/projects/personas/images/personas-logo-beta.png"
-           alt="Personas for Firefox" />
-    </div>
-        
-    <div id="bottom">
-      <div><img src="http://labs.mozilla.com/projects/personas/images/otherpages-table-top.png" alt="" /></div>
-
-      <div class="table_middle">
-        <div id="sidebar">
-          <div class="menu-box">
-            <ul>
-              {% for entry in sidebar_entries %}
-              {% ifequal entry.name section.name %}
-              <li class="selected">
-                <a href="{{ entry.url }}">{{entry.name}}</a>
-              </li>
-              {% else %}
-              <li><a href="{{ entry.url }}">{{ entry.name }}</a></li>
-              {% endifequal %}
-              {% endfor %}
-              {% if perms.personas.can_publish %}
-              <li><a href="{% url django.contrib.admin.views.main.index %}"
-                     >Administer</a></li>
-              {% endif %}
-            </ul>
-          </div>
-          {% if user.is_authenticated %}
-          <p>Logged in as {{ user.email }}.</p>
-          <p><a href="{% url logout %}">Log out</a></p>
-          {% else %}
-          <a href="https://services.mozilla.com/" >Register</a> | 
-          <a href="{% url login %}">Log in</a>
-          {% endif %}
-        </div>
-        
-        <div id="section-content">
-          <div class="title">{% block title %}{{ section.name }}{% endblock %}</div>
-          <div class="divider"></div>
-      
-          <div class="details">
-            {% if messages %}
-            {% for message in messages %}
-            <div class="message">{{ message }}</div>
-            {% endfor %}
-            {% endif %}
-            {% block content %}{% endblock %}
-          </div>
-        </div>
-
-        <div><img src="http://labs.mozilla.com/projects/personas/images/otherpages-table-foot.png" alt="" /></div>
-
-      </div>
-    
-      <div id="footer">
-        <div class="labs">
-          <a href="http://labs.mozilla.com"><img src="http://labs.mozilla.com/projects/personas/images/mozilla-labs-large.png" alt="Mozilla Labs" border="0" /></a>
-
-          Personas for Firefox is a <a href="http://labs.mozilla.com">Mozilla Labs Project</a>.
-        </div>
-        <div class="legal">
-          &copy; 2007 Mozilla
-          <span>
-            <a href="http://www.mozilla.com/en-US/about/legal.html">Legal Notices</a> |
-            <a href="http://www.mozilla.com/en-US/privacy-policy.html">Privacy Policy</a>
-          </span>
-        </div>
-      </div>
-    </div>
-  </div>
-</body>
-</html>
--- a/PersonasBackendTemp/personas/templates/personas/edit.html	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-{% extends "personas/base.html" %}
-
-{% block content %}
-<form enctype="multipart/form-data" method="post" action=".">
-  <table class="persona-form corner-box">
-    {{ form }}
-  </table>
-  <input type="submit" class="amo-submit" value="Submit"/>
-</form>
-{% endblock %}
--- a/PersonasBackendTemp/personas/templates/personas/home.html	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-{% extends "personas/base.html" %}
-
-{% block title %}What are Personas?{% endblock %}
-
-{% block content %}
-<p>Personas for Firefox is an extension that adds lightweight theming to your browser.</p>
-<p>Personas is a prototype that builds upon the ideas that:</p>
-<ul>
-<li>themes today are too hard to find, install and use</li>
-<li>graphic designers should be able to style the browser without having to code</li>
-<li>browsers can be more than just desktop software, they can include online components</li>
-<li>people just want their computer to be a little more fun and personal</li>
-</ul>
-{% endblock %}
--- a/PersonasBackendTemp/personas/templates/personas/legacy_persona.xul	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        flex="1"
-        style="background-repeat: no-repeat;"
-        onload="document.documentElement.style.backgroundImage = 'url({{image}})'">
-
-  <!-- Because CSS image loads don't block the load/pageshow events in Firefox 2,
-     - we load the image in an image tag, which does block those events, and then
-     - set the background-image property once the image has finished loading. -->
-  <image id="image" collapsed="true"/>
-
-  <script type="application/javascript;version=1.7">
-    <![CDATA[
-     document.getElementById("image").setAttribute("src", "{{image}}");
-     document.documentElement.style.backgroundPosition = "{{position}}";
-    ]]>
-  </script>
-</window>
--- a/PersonasBackendTemp/personas/templates/personas/list.html	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-{% extends "personas/base.html" %}
-
-{% block content %}
-{% if personas %}
-<p>Here's a list of all available Personas.</p>
-<p>If you have the Personas extension installed, just mouseover the
-preview image for a Persona to preview it&mdash;when your mouse moves
-away from the image, your original Persona will replace the preview.</p>
-<p>If you like the Persona, you can click on the preview image to set it
-as your current Persona.</p>
-<p>Enjoy!</p>
-<script>
-function dispatchPersonaEvent(aType, aNode, aUrl) {
-    if (aUrl) {
-        /* TODO: We should only do this if the Persona is successfully
-           set, i.e. if the user actually has Personas installed, etc. */
-        /* TODO: We should probably just use a library like jQuery to
-           do this for us. */
-        var request = new XMLHttpRequest();
-        /* TODO: Be reasonable and make this a POST, as this 'ping' will
-           change the server's state. */
-        request.open( "GET", aUrl, true );
-        request.onreadystatechange = function() {}
-        request.send(null);
-    }
-
-    var event = document.createEvent("Events");
-    event.initEvent(aType, true, false);
-    aNode.dispatchEvent(event);
-}
-</script>
-{% for persona in personas %}
-<div class="corner-box">
-  <div onclick="dispatchPersonaEvent('SelectPersona',
-                event.originalTarget,
-                '{% url report-selection persona.id %}')"
-       onmouseover="dispatchPersonaEvent('PreviewPersona',
-                    event.originalTarget)"
-       onmouseout="dispatchPersonaEvent('ResetPersona',
-                   event.originalTarget)">
-    <img persona="{{ persona.json_id }}"
-         category="{{ persona.category.json_id }}"
-         src="{{ persona.get_header_url }}" class="preview-image"
-         width="300" height="20" alt="" />
-  </div>
-  <div class="persona-title">
-    <h2 class="persona-name">{{ persona.name }}</h2>
-    {% if persona.owner %}
-    <span class="developer"> by {{ persona.owner.first_name }}
-    {{ persona.owner.last_name }}</span>
-    {% endif %}
-  </div>
-  <div class="persona-desc">{{ persona.description|safe }}</div>
-  {% if perms.personas.can_publish %}
-  <a href="{% url django.contrib.admin.views.main.change_stage "personas","persona",persona.id %}">Edit</a>
-  {% else %}
-  {% ifequal persona.owner user %}
-  <a href="{% url edit-persona persona.id %}">Edit</a>
-  {% endifequal %}
-  {% endif %}
-</div>
-{% endfor %}
-{% else %}
-<p>There are currently no personas available.</p>
-{% endif %}
-{% endblock %}
--- a/PersonasBackendTemp/personas/templates/personas/logged_out.html	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-{% extends "personas/base.html" %}
-
-{% block content %}
-<p>{{ title }}</p>
-{% endblock %}
--- a/PersonasBackendTemp/personas/templates/personas/login.html	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-{% extends "personas/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="." class="persona-form corner-box">
-  <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" class="amo-submit" value="Log in" />
-  <input type="hidden" name="next" value="{{ next }}" />
-</form>
-{% endblock %}
--- a/PersonasBackendTemp/personas/templates/personas/todo.html	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-{% extends "personas/base.html" %}
-
-{% block content %}
-This page is under construction.
-{% endblock %}
--- a/PersonasBackendTemp/personas/tests.py	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-import unittest
-import datetime
-
-from django.test.client import Client
-from django.core.urlresolvers import reverse
-from PersonasBackend.personas import models
-
-class JsonTests( unittest.TestCase ):
-    def setUp( self ):
-        for persona in models.Persona.objects.all():
-            persona.delete()
-        self.cat = models.Category( name = "Random Things" )
-        self.cat.save()
-        self.persona = models.Persona(
-            name = "Test Persona",
-            category = self.cat,
-            url = "http://www.blarg.com/mypersona",
-            status = "published"
-            )
-        self.persona.save()
-
-    def tearDown( self ):
-        self.persona.delete()
-        self.cat.delete()
-
-    def testCategoriesWorks( self ):
-        # Just a smoke test to make sure nothing crashes...
-        client = Client()
-        response = client.get( reverse("personas-categories-json") )
-        assert response.status_code == 200
-
-    def testAllPersonasWorks( self ):
-        # Just a smoke test to make sure nothing crashes...
-        client = Client()
-        response = client.get( reverse("personas-all-json") )
-        assert response.status_code == 200
-
-    def testPublishDateIsUpdatedProperly( self ):
-      p = models.Persona(
-          name='Yet Another Test Persona',
-          url='http://www.test.com/testpersona',
-          category=models.Category.objects.get(name='Other'))
-
-      p.save()
-      self.assertEquals( p.status, "unpublished" )
-      self.assertEquals( p.date_published, None )
-
-      p.status = "published"
-      now = datetime.datetime.now()
-      p.save()
-      assert p.date_published >= now
-
-if __name__ == "__main__":
-    unittest.main()
--- a/PersonasBackendTemp/personas/urls.py	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-from django.conf.urls.defaults import *
-
-urlpatterns = patterns('',
-    # JSON feeds
-
-    # TODO: Replace the '.+' at the beginning of these with
-    # a real regexp that conveys the locale to the view.
-    url(r'^.+/personas_categories.dat$',
-     'PersonasBackend.personas.json_feeds.categories',
-     name='personas-categories-json'),
-    url(r'^.+/personas_all.dat$',
-     'PersonasBackend.personas.json_feeds.personas',
-     name='personas-all-json'),
-
-    # Dynamic wrappers for views
-    url(r'^legacy/(?P<name>.+)$',
-        'PersonasBackend.personas.views.legacy_cbeard_persona',
-        name='legacy-cbeard-persona'),
-
-    # Auth
-    url(r'^login/$', 'django.contrib.auth.views.login',
-        {'template_name':'personas/login.html'},
-        name='login'),
-    url(r'^logout/$', 'django.contrib.auth.views.logout',
-        {'template_name':'personas/logged_out.html'},
-        name='logout'),
-
-    # AJAX calls
-    url(r'^ajax/report_selection/(?P<persona_id>\d+)/$',
-        'PersonasBackend.personas.ajax.report_selection',
-        name='report-selection'),
-
-    # Personas UI
-    url(r'^new/$',
-        'PersonasBackend.personas.views.new_view',
-        name='new-persona'),
-    url(r'^(?P<persona_id>\d+)/edit/$',
-        'PersonasBackend.personas.views.edit_view',
-        name='edit-persona'),
-    url(r'^list/$', 'PersonasBackend.personas.views.list_view',
-        name='list-personas'),
-    url(r'^$', 'PersonasBackend.personas.views.home_view',
-        name='personas-home'),
-
-    # 'Fake' scaffolding view for pages that still need to be
-    # constructed.
-    url(r'^TODO/$', 'PersonasBackend.personas.views.todo_view',
-        name='TODO'),
-)
--- a/PersonasBackendTemp/personas/views.py	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-from django.http import HttpResponseRedirect, HttpResponseForbidden
-from django.http import HttpResponse, HttpResponseBadRequest
-from django.template import RequestContext
-from django.contrib.auth.decorators import login_required
-from django.core.urlresolvers import reverse
-from django.shortcuts import render_to_response, get_object_or_404
-
-from PersonasBackend.personas import models
-from PersonasBackend.personas import forms
-
-def legacy_cbeard_persona( request, name ):
-    PREFIX = "http://sm-labs01.mozilla.org/legacy-personas/"
-    FOOTER_URL = "%(prefix)s%(name)s/stbar-%(name)s.jpg"
-    HEADER_URL = "%(prefix)s%(name)s/tbox-%(name)s.jpg"
-
-    urldict = {"prefix" : PREFIX, "name" : name}
-
-    action = request.GET.get( "action", "" )
-
-    if action == "footer":
-        position = "bottom left"
-        img_src = FOOTER_URL % urldict
-    elif action == "header":
-        position = "top right"
-        img_src = HEADER_URL % urldict
-    else:
-        return HttpResponseBadRequest( "Invalid or unsupported action: %s" %
-                                       action )
-
-    return render_to_response(
-        "personas/legacy_persona.xul",
-        { "image" : img_src, "position" : position },
-        mimetype = "application/vnd.mozilla.xul+xml"
-        )
-
-def list_view( request ):
-    personas = models.Persona.objects.filter( status="published" )
-    return render_to_response(
-        "personas/list.html",
-        { "personas" : personas,
-          "title" : "Browse Personas" },
-        context_instance = RequestContext(request)
-        )
-
-def home_view( request ):
-    return render_to_response(
-        "personas/home.html",
-        { "title" : "Home" },
-        context_instance = RequestContext(request)
-        )
-
-def todo_view( request ):
-    return render_to_response(
-        "personas/todo.html",
-        { "title" : "Under Construction" },
-        context_instance = RequestContext(request)
-        )
-
-def new_view( request ):
-    return edit_view( request )
-
-@login_required
-def edit_view( request, persona_id=None ):
-    if persona_id is None:
-        persona = None
-        pageTitle = "Create a new Persona"
-    else:
-        persona = get_object_or_404( models.Persona, id=persona_id )
-        if not persona.can_user_edit( request.user ):
-            return HttpResponseForbidden(
-                "<h1>You do not have permission to edit "
-                "this Persona.</h1>"
-                )
-        pageTitle = "Edit Persona"
-
-    if request.method == "POST":
-        form = forms.PersonaForm( request.POST,
-                                  instance=persona )
-        if form.is_valid():
-            newPersona = form.save( commit=False )
-            newPersona.save( updater = request.user )
-            if persona is None:
-                msgText = ("Persona created successfully.  It will need "
-                           "to be reviewed by a staff member "
-                           "before it is published.")
-            else:
-                msgText = ("Persona edited successfully.  Your changes "
-                           "will need to be approved by a staff member "
-                           "before they can take effect.")
-            request.user.message_set.create( message = msgText )
-            url = reverse("edit-persona", args=[newPersona.id])
-            return HttpResponseRedirect( url )
-    else:
-        form = forms.PersonaForm( instance=persona )
-
-    return render_to_response(
-        "personas/edit.html",
-        { "form" : form,
-          "title" : pageTitle },
-        context_instance = RequestContext(request)
-        )
--- a/PersonasBackendTemp/settings.py	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-# Django settings for PersonasBackend project.
-
-import os
-
-myPath = os.path.abspath( os.path.dirname( __file__ ) )
-
-DEBUG = True
-TEMPLATE_DEBUG = DEBUG
-
-ADMINS = (
-    # ('Your Name', 'your_email@domain.com'),
-)
-
-MANAGERS = ADMINS
-
-DATABASE_ENGINE = 'sqlite3'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
-DATABASE_NAME = os.path.join( myPath, "temp_db" )             # Or path to database file if using sqlite3.
-DATABASE_USER = ''             # 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.
-
-# 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 = 'America/Chicago'
-
-# 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 = os.path.normpath( os.path.join( myPath, "..", "media" ) )
-
-BASE_DIR = "personas/"
-
-# URL that handles the media served from MEDIA_ROOT.
-# Example: "http://media.lawrence.com"
-MEDIA_URL = '/%smedia/' % BASE_DIR
-
-# 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 = '/%sadmin/media/' % BASE_DIR
-
-# Make this unique, and don't share it with anybody.
-SECRET_KEY = 'x=0z4lnv#vws4p4a%r(fb=(wh&o4k)k!5!a9b*3-j7s87^v43d'
-
-# 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.cache.CacheMiddleware',
-    'django.middleware.common.CommonMiddleware',
-    'django.contrib.sessions.middleware.SessionMiddleware',
-    'django.contrib.auth.middleware.AuthenticationMiddleware',
-    'django.middleware.doc.XViewMiddleware',
-)
-
-LOGIN_URL = '/%slogin/' % BASE_DIR
-LOGIN_REDIRECT_URL = '/%s' % BASE_DIR
-
-ROOT_URLCONF = 'PersonasBackend.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.
-    os.path.normpath( os.path.join( myPath, "..", "templates" ) ),
-)
-
-INSTALLED_APPS = (
-    'django.contrib.auth',
-    'django.contrib.contenttypes',
-    'django.contrib.sessions',
-    'django.contrib.sites',
-    'django.contrib.admin',
-    'PersonasBackend.personas',
-)
-
-TEMPLATE_CONTEXT_PROCESSORS = (
-    "django.core.context_processors.auth",
-    "django.core.context_processors.debug",
-    "django.core.context_processors.i18n",
-    "django.core.context_processors.media",
-    "PersonasBackend.personas.sections.context",
-)
-
-CACHE_BACKEND = 'locmem:///'
-CACHE_MIDDLEWARE_SECONDS = 5
-CACHE_MIDDLEWARE_KEY_PREFIX = "personas"
-
-AUTHENTICATION_BACKENDS = (
-    "PersonasBackend.weaveproxyauth.Backend",
-)
--- a/PersonasBackendTemp/urls.py	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-import os
-
-from django.conf.urls.defaults import *
-from PersonasBackend import settings
-import django.contrib.admin
-
-urlpatterns = patterns('',
-    # Admin media
-    # TODO: Remove the static.serve, b/c it's supposedly insecure.
-    (r'^%sadmin/media/(?P<path>.*)$' % settings.BASE_DIR,
-     'django.views.static.serve',
-     {'document_root': os.path.join( django.contrib.admin.__path__[0],
-                                     "media" )}),
-
-    # Admin
-    (r'^%sadmin/' % settings.BASE_DIR,
-     include('django.contrib.admin.urls')),
-
-    # Personas media
-    # TODO: Remove the static.serve, b/c it's supposedly insecure.
-    (r'^%smedia/(?P<path>.*)$' % settings.BASE_DIR,
-     'django.views.static.serve',
-     {'document_root': settings.MEDIA_ROOT}),
-
-    # Personas
-    (r'^%s' % settings.BASE_DIR,
-     include('PersonasBackend.personas.urls')),
-)
--- a/PersonasBackendTemp/utils.py	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-from django.contrib.sites.models import Site
-
-def make_absolute_url( path ):
-    domain = Site.objects.get_current().domain
-    if domain == "localhost":
-        domain = "localhost:8000"
-    url = "http://%s%s" % (domain, path)
-    return url
--- a/PersonasBackendTemp/weaveproxyauth.py	Wed Apr 02 11:59:36 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-import sha
-import urllib2
-import httplib
-
-from django.contrib.auth.models import User
-
-class Backend(object):
-    def authenticate(self, username=None, password=None):
-        hexuser = sha.sha(username).hexdigest()
-        url = "https://services.mozilla.com/user/%s/" % hexuser
-        authHandler = urllib2.HTTPBasicAuthHandler()
-        authHandler.add_password("services.mozilla.com - proxy",
-                                 "services.mozilla.com",
-                                 username,
-                                 password)
-
-        opener = urllib2.build_opener(authHandler)
-
-        try:
-            obj = opener.open(url)
-            obj.read()
-            auth_successful = True
-        except urllib2.HTTPError, e:
-            if e.code == httplib.UNAUTHORIZED:
-                auth_successful = False
-            else:
-                raise
-
-        if auth_successful:
-            try:
-                user = User.objects.get(email=username)
-            except User.DoesNotExist:
-                # We have to go through this annoyance because Django
-                # auth requires us to enter a username, and the username
-                # can be no more than 30 characters and can't include
-                # anything other than alphanumeric characters.
-                munged_username = "".join(
-                    [char for char in username if char.isalnum()]
-                    )[:25]
-
-                offset = 0
-                while User.objects.filter(
-                    username = munged_username + str(offset)
-                    ):
-                    offset += 1
-
-                user = User(username=munged_username + str(offset),
-                            password="Retrieved from Weave",
-                            email=username)
-                user.save()
-            return user
-
-        return None
-
-    def get_user(self, user_id):
-        try:
-            return User.objects.get(pk=user_id)
-        except User.DoesNotExist:
-            return None
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/manage.py	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,11 @@
+#!/usr/bin/env 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)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/personas/ajax.py	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,10 @@
+from django.http import HttpResponse
+from django.shortcuts import get_object_or_404
+
+from PersonasBackend.personas import models
+
+def report_selection( request, persona_id ):
+    persona = get_object_or_404( models.Persona, id=persona_id )
+    persona.popularity += 1
+    persona.save()
+    return HttpResponse()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/personas/fixtures/initial_data.xml	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<django-objects version="1.0"><object pk="1" model="personas.category"><field type="CharField" name="name">Other</field></object><object pk="2" model="personas.category"><field type="CharField" name="name">Geometric</field></object><object pk="3" model="personas.category"><field type="CharField" name="name">Sports</field></object><object pk="4" model="personas.category"><field type="CharField" name="name">Scenery</field></object><object pk="5" model="personas.category"><field type="CharField" name="name">Nature</field></object><object pk="6" model="personas.category"><field type="CharField" name="name">Holidays</field></object><object pk="7" model="personas.category"><field type="CharField" name="name">Foxkeh</field></object><object pk="8" model="personas.category"><field type="CharField" name="name">Firefox</field></object><object pk="1" model="personas.persona"><field type="CharField" name="name">Firefox Logo</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">8</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=firefox_b</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="2" model="personas.persona"><field type="CharField" name="name">Firefox Flicks</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">8</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=firefox_flicks</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="3" model="personas.persona"><field type="CharField" name="name">Mozilla Classic</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">8</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=mozilla_classic</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="4" model="personas.persona"><field type="CharField" name="name">Foxkeh Straw</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_straw</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="5" model="personas.persona"><field type="CharField" name="name">Foxkeh Hanami</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_hanami</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="6" model="personas.persona"><field type="CharField" name="name">Foxkeh Hinimatsuri</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_hinimatsuri</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="7" model="personas.persona"><field type="CharField" name="name">Foxkeh Kodomo No Hi</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_kodomo_no_hi</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="8" model="personas.persona"><field type="CharField" name="name">Foxkeh Setsubun</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_setsubun</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="9" model="personas.persona"><field type="CharField" name="name">Foxkeh Giant Butterbur</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_butterbur</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="10" model="personas.persona"><field type="CharField" name="name">Foxkeh Tanabata</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_tanabata</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="11" model="personas.persona"><field type="CharField" name="name">Viva Firefox</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">8</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=viva</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="12" model="personas.persona"><field type="CharField" name="name">Developer Kit</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">8</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=kit</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="13" model="personas.persona"><field type="CharField" name="name">Tranquility</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">5</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=tranquility</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="14" model="personas.persona"><field type="CharField" name="name">California Sunset</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">4</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=california_sunset</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="15" model="personas.persona"><field type="CharField" name="name">Wood Paneling</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=wood_paneling</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="16" model="personas.persona"><field type="CharField" name="name">Hearts</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=hearts</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="17" model="personas.persona"><field type="CharField" name="name">Blue Spheres</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=blue_spheres</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="18" model="personas.persona"><field type="CharField" name="name">Les Diablerets</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">4</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=les_diablerets</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="19" model="personas.persona"><field type="CharField" name="name">Seagull</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">4</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=seagull</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="20" model="personas.persona"><field type="CharField" name="name">Verdelet</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">4</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=verdelet</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="21" model="personas.persona"><field type="CharField" name="name">Green Wave</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=green_wave</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="22" model="personas.persona"><field type="CharField" name="name">Golf</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">3</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=golf</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="23" model="personas.persona"><field type="CharField" name="name">Basketball</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">3</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=bball</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="24" model="personas.persona"><field type="CharField" name="name">Antique Wallpaper</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=antique_wallpaper</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="25" model="personas.persona"><field type="CharField" name="name">Bamboo</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">5</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=bamboo</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="26" model="personas.persona"><field type="CharField" name="name">Plaid</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">2</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=plaid</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="27" model="personas.persona"><field type="CharField" name="name">Soccer</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">3</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=soccer</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="28" model="personas.persona"><field type="CharField" name="name">Suede</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=suede</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="29" model="personas.persona"><field type="CharField" name="name">Aquarium</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">5</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=aquarium</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="30" model="personas.persona"><field type="CharField" name="name">Dialogonal Lines</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">2</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=diagonal_lines</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="31" model="personas.persona"><field type="CharField" name="name">Dots</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">2</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=dots</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="32" model="personas.persona"><field type="CharField" name="name">Golden Gate Bridge</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">4</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=golden_gate_bridge</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="33" model="personas.persona"><field type="CharField" name="name">Grass</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">5</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=grass</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="34" model="personas.persona"><field type="CharField" name="name">Foxkeh Green Winter</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_green_winter</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="35" model="personas.persona"><field type="CharField" name="name">Jellyfish</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">5</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=jellyfish</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="36" model="personas.persona"><field type="CharField" name="name">Yosemite</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">4</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=yosemite</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="37" model="personas.persona"><field type="CharField" name="name">Snowman</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">6</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=snowman</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="38" model="personas.persona"><field type="CharField" name="name">Snowflakes</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">6</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=snowflakes</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="39" model="personas.persona"><field type="CharField" name="name">Reindeer</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">6</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=reindeer</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="40" model="personas.persona"><field type="CharField" name="name">Foxkeh Canoe</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_canoe</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="41" model="personas.persona"><field type="CharField" name="name">Foxkeh Helloween</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_helloween</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="42" model="personas.persona"><field type="CharField" name="name">Foxkeh Susuki</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_susuki</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="43" model="personas.persona"><field type="CharField" name="name">Foxkeh Hanabi</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">7</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=foxkeh_hanabi</field><field type="CharField" name="text_color">#FFFFFF</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="44" model="personas.persona"><field type="CharField" name="name">Paper</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=paper</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="45" model="personas.persona"><field type="CharField" name="name">Winter</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">6</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=winter</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="46" model="personas.persona"><field type="CharField" name="name">Leather</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=leather</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="47" model="personas.persona"><field type="CharField" name="name">Niagra Falls</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">4</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=niagra_falls</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="48" model="personas.persona"><field type="CharField" name="name">Groovy Blue</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=groovy_blue</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="49" model="personas.persona"><field type="CharField" name="name">Groovy Hearts</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=groovy_hearts</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="50" model="personas.persona"><field type="CharField" name="name">Groovy Orange</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=groovy_orange</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object><object pk="51" model="personas.persona"><field type="CharField" name="name">Groovy Pink</field><field to="auth.user" name="owner" rel="ManyToOneRel"><None></None></field><field to="personas.category" name="category" rel="ManyToOneRel">1</field><field type="TextField" name="description">&amp;nbsp;</field><field type="CharField" name="url">http://personas-view/legacy-cbeard-persona?name=groovy_pink</field><field type="CharField" name="text_color">#000000</field><field type="CharField" name="accent_color"></field><field type="DateTimeField" name="date_published">2008-03-28 16:49:23</field><field type="DateTimeField" name="date_updated">2008-03-28 16:49:23</field><field to="auth.user" name="updater" rel="ManyToOneRel"><None></None></field><field type="PositiveIntegerField" name="revision">0</field><field type="PositiveIntegerField" name="popularity">0</field><field type="CharField" name="status">published</field></object></django-objects>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/personas/forms.py	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,47 @@
+import django.newforms as forms
+from PersonasBackend.personas import models
+
+class PersonaForm( forms.ModelForm ):
+    """
+    Form given to normal users who don't have the permission to
+    publish Personas.
+    """
+
+    class Meta:
+        model = models.Persona
+        exclude = ["owner", "date_published", "popularity", "status"]
+
+    agree_to_terms = forms.BooleanField(
+        label = "I agree to the terms of use.",
+        # TODO: setting required to True doesn't seem to have any effect,
+        # but the Django docs say it should ensure that the checkbox
+        # is filled out.
+        required = True,
+        help_text = ("Terms of use: I agree that Mozilla is providing "
+                     "a service by hosting the "
+                     "content I am submitting, and that they are in no "
+                     "way responsible for any damages that occur as "
+                     "a result of hosting said content.")
+        )
+
+    def _color_cleaner( self, field ):
+        models.ensure_color_is_valid(
+            self.cleaned_data[field],
+            error_class = forms.ValidationError
+            )
+        return self.cleaned_data[field]
+
+    def clean_text_color( self ):
+        return self._color_cleaner( "text_color" )
+
+    def clean_accent_color( self ):
+        return self._color_cleaner( "accent_color" )
+
+    def clean( self ):
+        if not self.cleaned_data["agree_to_terms"]:
+            raise forms.ValidationError(
+                "You must agree to the terms of service to "
+                "submit your Persona."
+                )
+
+        return self.cleaned_data
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/personas/json_feeds.py	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,68 @@
+from django.http import HttpResponse
+from django.utils import simplejson
+
+from PersonasBackend.personas import models
+
+NEW_MENU_ID = "personas-new-menu"
+POPULAR_MENU_ID = "personas-popular-menu"
+
+def _makeJsonResponse( obj ):
+    json = simplejson.dumps( obj, indent=4 )
+    response = HttpResponse( json )
+    response["Content-Type"] = "text/plain"
+    return response
+
+def categories( request ):
+    categoryDicts = [
+        {"label": "Most Popular", "id" : POPULAR_MENU_ID,
+         "type" : "list", "parent" : "top" },
+	{"label": "Recent", "id" : "personas-recent-menu",
+         "type" : "recent", "parent" : "top" },
+	{"label": "New", "id" : NEW_MENU_ID,
+         "type" : "list", "parent" : "top" },
+	{"label": "All", "id" : "personas-category-menu",
+         "type" : "category", "parent" : "top" },
+        ]
+
+    for category in models.Category.objects.all():
+        categoryDicts.append(
+            {"label" : category.name,
+             "id" : category.json_id,
+             "type" : "list",
+             "parent" : "personas-category-menu"}
+            )
+
+    return _makeJsonResponse( {"categories" : categoryDicts} )
+
+def personas( request ):
+    personaDicts = []
+
+    isPopular = {}
+    isNew = {}
+
+    published = models.Persona.objects.filter( status="published" )
+
+    for persona in published.order_by( "-popularity" )[:10]:
+        isPopular[persona.id] = True
+
+    for persona in published.order_by( "-date_published" )[:10]:
+        isNew[persona.id] = True
+
+    for persona in published:
+        categories = [persona.category.json_id]
+        if persona.id in isPopular:
+            categories.append( POPULAR_MENU_ID )
+        if persona.id in isNew:
+            categories.append( NEW_MENU_ID )
+
+        personaDicts.append(
+            {"label" : persona.name,
+             "id" : persona.json_id,
+             "textColor" : persona.text_color,
+             "accentColor" : persona.accent_color,
+             "baseURL" : persona.resolved_url,
+             "menu" : ",".join( categories ),
+             "preview" : "yes"}
+            )
+
+    return _makeJsonResponse( {"personas" : personaDicts} )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/personas/models.py	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,604 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+# 
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+# 
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+# 
+# The Original Code is PersonasBackend.
+# 
+# The Initial Developer of the Original Code is Mozilla.
+# Portions created by the Initial Developer are Copyright (C) 2008
+# the Initial Developer. All Rights Reserved.
+# 
+# Contributor(s):
+#   Atul Varma <atul@mozilla.org>
+# 
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+# 
+# ***** END LICENSE BLOCK *****
+
+"""
+models.py
+
+This module contains the models for the Personas application.
+
+Note that changes to Personas are automatically revision-controlled.
+Among other things, this allows for:
+
+  (A) A humane user interface that supports undo operations.
+
+  (B) A workflow that allows for Personas to be changed by a submitter
+      and reviewed while the original, unchanged Persona remains
+      published and accessible by clients.
+"""
+
+import datetime
+
+from django.db import models
+from django.core.urlresolvers import reverse
+from django.contrib.auth.models import User
+from django.core.validators import ValidationError
+
+from PersonasBackend.utils import make_absolute_url
+
+MAX_COLOR_LENGTH = 7
+
+def parse_personas_view_url( url ):
+    """
+    TODO: Document this.
+
+    Examples:
+
+      >>> parse_personas_view_url( "http://personas-view/blargy?thing=blarg" )
+      {'kwargs': {'thing': 'blarg'}, 'view': 'blargy'}
+
+      >>> parse_personas_view_url( "http://porsonas-view/blargy?thing=blarg" )
+    """
+
+    if not url.startswith( "http://personas-view/" ):
+        return None
+
+    import urlparse
+    import cgi
+
+    _, _, path, _, query, _ = urlparse.urlparse( url )
+    view = path[1:]
+    kwargs = cgi.parse_qs( query )
+
+    # It is completely ridiculous that we have to do this, but
+    # apparently we do, because django's reverse() doesn't like being
+    # passed dictionaries with unicode keys.
+    string_kwargs = {}
+    for key in kwargs:
+        string_kwargs[str(key)] = str(kwargs[key][0])
+
+    return {'view':view, 'kwargs':string_kwargs}
+
+def ensure_color_is_valid( color,
+                           error_class = ValidationError ):
+    """
+    Given a color string, raises a ValidationError if the color isn't
+    formatted properly.
+
+    Examples:
+
+      >>> ensure_color_is_valid('')
+
+      >>> ensure_color_is_valid('blah')
+      Traceback (most recent call last):
+      ...
+      ValidationError: [u"The color must start with a '#'."]
+
+      >>> ensure_color_is_valid('#aaaaaaa')
+      Traceback (most recent call last):
+      ...
+      ValidationError: [u'The color is too long.']
+
+      >>> ensure_color_is_valid('#aaaaa')
+      Traceback (most recent call last):
+      ...
+      ValidationError: [u'The color is too short.']
+
+      >>> ensure_color_is_valid('#aaazaa')
+      Traceback (most recent call last):
+      ...
+      ValidationError: [u"The character 'z' isn't valid."]
+
+      >>> ensure_color_is_valid('#aaaaaa')
+      >>> ensure_color_is_valid('#FFFF11')
+    """
+
+    HEX_CHARS = "0123456789abcdef"
+
+    if not color:
+        return
+
+    if not color.startswith("#"):
+        raise error_class( "The color must start with a '#'." )
+    if len(color) > MAX_COLOR_LENGTH:
+        raise error_class( "The color is too long." )
+    if len(color) < MAX_COLOR_LENGTH:
+        raise error_class( "The color is too short." )
+    for char in color.lower()[1:MAX_COLOR_LENGTH]:
+        if char not in HEX_CHARS:
+            raise error_class( "The character '%s' isn't valid." % char )
+
+class Category(models.Model):
+    """
+    Represents a Personas category; every Persona can be assigned one,
+    and only one, category.
+    """
+
+    class Admin:
+        pass
+
+    class Meta:
+        verbose_name_plural = "categories"
+
+    name = models.CharField(
+        "Category name",
+        max_length=50,
+        unique=True,
+        )
+
+    def __str__(self):
+        return self.name
+
+    def _get_json_id( self ):
+        return "personas-category-%d" % self.id
+
+    json_id = property( _get_json_id )
+
+class Persona(models.Model):
+    """
+    Encapsulates the most recent revision of a Persona.
+    """
+
+    class Admin:
+        list_display = ["name", "date_updated", "status"]
+
+    class Meta:
+        permissions = (
+            ("can_publish", "Can publish"),
+            )
+
+    MAX_NAME_LENGTH = 50
+
+    name = models.CharField(
+        max_length=MAX_NAME_LENGTH,
+        blank=False,
+        )
+
+    owner = models.ForeignKey(
+        User,
+        help_text=("The user who owns this persona can make "
+                   "changes to it."),
+        related_name="owned_personas",
+        # TODO: Consider making this null=False.  Keeping it true
+        # makes it easier to write tests, though.
+        null=True,
+        blank=True,
+        )
+
+    category = models.ForeignKey(
+        Category,
+        related_name="personas",
+        null=False,
+        )
+
+    description = models.TextField(
+        help_text = "HTML is allowed.",
+        blank=False,
+        )
+
+    url = models.URLField(
+        "Persona URL",
+        help_text=("URL for the content that will be placed behind "
+                   "the browser's chrome."),
+        verify_exists=False,
+        blank=False,
+        )
+
+    def __get_resolved_url(self):
+        viewinfo = parse_personas_view_url( self.url )
+        if not viewinfo:
+            return self.url
+        else:
+            return make_absolute_url( reverse(
+                    viewinfo['view'],
+                    kwargs = viewinfo['kwargs']
+                    ) )
+
+    resolved_url = property(__get_resolved_url)
+
+    text_color = models.CharField(
+        help_text=("The RGB color, as a #RRGGBB color hash, "
+                   "of the color of text that will be displayed "
+                   "on the persona."),
+        max_length=MAX_COLOR_LENGTH,
+        validator_list=[ensure_color_is_valid],
+        blank=True
+        )
+
+    accent_color = models.CharField(
+        help_text=("The RGB color, as a #RRGGBB color hash, "
+                   "of the accent colors that will be displayed "
+                   "on the persona."),
+        max_length=MAX_COLOR_LENGTH,
+        validator_list=[ensure_color_is_valid],
+        blank=True,
+        )
+
+    date_published = models.DateTimeField(
+        help_text=("The date that the Persona was last published."),
+        null=True,
+        editable=True,
+        )
+
+    date_updated = models.DateTimeField(
+        # This ensures that this field is updated with the current
+        # timestamp whenever the record is changed.
+        auto_now=True,
+        null=False,
+        editable=False,
+        )
+
+    updater = models.ForeignKey(
+        User,
+        help_text="The user who made this revision.",
+        related_name="changed_personas",
+        null=True,
+        editable=False
+        )
+
+    revision = models.PositiveIntegerField(
+        "Revision number",
+        help_text=("This number is incremented whenever the Persona "
+                   "is changed."),
+        null=False,
+        editable=False,
+        )
+
+    popularity = models.PositiveIntegerField(
+        "Popularity",
+        help_text=("A number indicating how popular the Persona is; the "
+                   "higher this value, the better."),
+        default=0,
+        null=False,
+        )
+
+    MAX_STATUS_LENGTH = 10
+
+    status = models.CharField(
+        max_length=MAX_STATUS_LENGTH,
+        choices=(("published", "Published"),
+                 ("unpublished", "Unpublished"),
+                 ("deleted", "Deleted")),
+        blank=False,
+        help_text=("Status of the Persona; can be deleted, published, "
+                   "or unpublished (i.e., pending for review).")
+        )
+
+    def __str__(self):
+        return self.name
+
+    # These are the properties of this record that are "versioned",
+    # i.e. tracked by built-in revision control when changed.
+    VERSIONED_PROPERTIES = (
+        "name",
+        "owner",
+        "category",
+        "description",
+        "url",
+        "text_color",
+        "accent_color",
+        "status",
+        )
+
+    def __make_new_revision(self):
+        """
+        Detect if any of our versioned properties have changed, and if
+        so, make a new revision.
+        """
+
+        original = Persona.objects.get(id=self.id)
+
+        assert original.revision == self.revision
+
+        delta = {}
+        for attr in self.VERSIONED_PROPERTIES:
+            origValue = getattr(original, attr)
+            newValue = getattr(self, attr)
+            if origValue != newValue:
+                delta[attr] = origValue
+        if delta:
+            rev = Revision(
+                revision_of = original,
+                date_updated = original.date_updated,
+                updater = original.updater,
+                revision = original.revision
+                )
+
+            for attr in delta:
+                setattr(rev, attr, delta[attr])
+                setattr(rev, "has_%s" % attr, True)
+            rev.save()
+
+            self.revision += 1
+
+    def save( self, updater=None ):
+        """
+        Saves the object.  If a versioned property is changed, a new
+        revision is generated automatically.
+
+        Example:
+
+          >>> p = Persona(name='Test Persona',
+          ...             description='Thos is a test.',
+          ...             url='http://blarg.com',
+          ...             category=Category.objects.get(name='Other'))
+          >>> p.save()
+          >>> p.revision
+          0
+          >>> p.revisions.all()
+          []
+
+          >>> p.description = 'This is a test.'
+          >>> p.url = 'http://blarg2.com'
+          >>> p.save()
+          >>> p.revision
+          1
+          >>> p.revisions.all()
+          [<Revision: Test Persona - r0>]
+          >>> p.revisions.get(revision=0).description
+          u'Thos is a test.'
+          >>> p.revisions.get(revision=0).url
+          u'http://blarg.com'
+        """
+
+        if updater:
+            self.updater = updater
+        else:
+            # We were probably saved through the admin interface,
+            # which saves its own separate history of changes.
+            self.updater = None
+
+        if self.id == None:
+            # We're a brand-new Persona.
+            self.revision = 0
+            if not self.owner:
+                self.owner = self.updater
+            assert self.owner == self.updater
+            if not self.status:
+                if ( self.updater and
+                     self.updater.has_perm( "personas.can_publish" ) ):
+                    # If the person creating the Persona can publish
+                    # Personas, mark this new Persona as published, by
+                    # default.
+                    self.status = "published"
+                else:
+                    # Otherwise, mark this new Persona as unpublished by
+                    # default.
+                    self.status = "unpublished"
+            if self.status == "published":
+                self.date_published = datetime.datetime.now()
+        else:
+            # We're an existing Persona that's being modified.
+
+            if self.updater:
+                if not self.can_user_edit( self.updater ):
+                    # The user can't actually edit this Persona, reject
+                    # the change.  View logic should've prevented this
+                    # from ever being the case, so we're going to be
+                    # ungraceful here.
+                    raise AssertionError( "User can't edit this persona." )
+
+                if ( self.status == "published" and
+                     not self.updater.has_perm( "personas.can_publish" ) ):
+                    # The Persona is currently published, but a user
+                    # without publishing permissions has just changed it,
+                    # so mark it as unpublished so an editor can review it
+                    # before re-publishing it.
+
+                    self.status = "unpublished"
+
+            original = Persona.objects.get(id=self.id)
+
+            if ( (original.status != self.status) and 
+                 (self.status == "published") ):
+                self.date_published = datetime.datetime.now()
+
+            self.__make_new_revision()
+
+        super(Persona, self).save()
+
+    def can_user_edit( self, user ):
+        """
+        Returns whether the given User can edit this Persona.
+        """
+
+        return ( user.has_perm( "personas.can_publish" ) or
+                 self.owner == user )
+
+    def _get_json_id( self ):
+        return "persona-%d" % self.id
+
+    json_id = property( _get_json_id )
+
+class Revision(models.Model):
+    """
+    Represents an old revision of a Persona.
+
+    This record only stores a "reverse delta" relative to the revision
+    that follows it; for instance, if a user changes a Persona at
+    revision 0 by modifying its description, then the Revision record
+    for revision 0 will contain only the description for the Persona
+    at that revision, since all other properties can be obtained by
+    looking at revision 1.  In this way, the complete "picture" of
+    revision 0 can be reconstructed by starting at the record for
+    revision 0 and traveling to newer revisions until every field of
+    the Persona has been populated.
+    """
+
+    class Meta:
+        unique_together = (("revision_of", "revision"),)
+        ordering = ["revision"]
+
+    # Auto-generated fields
+
+    revision_of = models.ForeignKey(
+        Persona,
+        verbose_name="The Persona that this record is an old revision of",
+        related_name="revisions",
+        null=False,
+        )
+
+    date_updated = models.DateTimeField(
+        null=False,
+        )
+
+    updater = models.ForeignKey(
+        User,
+        related_name="previously_changed_revisions",
+        null=True,
+        )
+
+    revision = models.PositiveIntegerField(
+        null=False,
+        )
+
+    # Versioned fields
+
+    for attr in Persona.VERSIONED_PROPERTIES:
+        locals()["has_%s" % attr] = models.BooleanField(default=False)
+    del attr
+
+    name = models.CharField(
+        max_length=Persona.MAX_NAME_LENGTH,
+        null=True,
+        )
+
+    owner = models.ForeignKey(
+        User,
+        related_name="previously_owned_personas",
+        null=True,
+        )
+
+    category = models.ForeignKey(
+        Category,
+        related_name="revisions",
+        null=True,
+        )
+
+    description = models.TextField(
+        null=True,
+        )
+
+    url = models.URLField(
+        null=True,
+        )
+
+    text_color = models.CharField(
+        max_length=MAX_COLOR_LENGTH,
+        null=True,
+        )
+
+    accent_color = models.CharField(
+        max_length=MAX_COLOR_LENGTH,
+        null=True,
+        )
+
+    status = models.CharField(
+        max_length=Persona.MAX_STATUS_LENGTH,
+        null=True,
+        )
+
+    def __str__(self):
+        return "%s - r%s" % (self.revision_of.name, self.revision)
+
+    def resolve(self):
+        """
+        Fills-in (resolves) all the fields of the revision by
+        computing reverse deltas to future/present revisions.
+
+          >>> p = Persona(name='Test Persona',
+          ...             description='Thos is a test.',
+          ...             url='http://www.blarg.com',
+          ...             category=Category.objects.get(name='Other'))
+          >>> p.save()
+          >>> p.description = 'This is a test.'
+          >>> p.save()
+          >>> p.name = 'Blarg'
+          >>> p.save()
+          >>> p.description = "This is a great test."
+          >>> p.save()
+          >>> p.url = "http://www.test.com"
+          >>> p.save()
+          >>> r = p.revisions.get(revision=0)
+          >>> r.resolve()
+          >>> r.name
+          u'Test Persona'
+          >>> r.description
+          u'Thos is a test.'
+          >>> r.url
+          u'http://www.blarg.com'
+        """
+
+        persona = self.revision_of
+        futureRevs = persona.revisions.filter(revision__gt=self.revision)
+        attrsLeft = [ attr for attr in Persona.VERSIONED_PROPERTIES
+                      if getattr(self, attr) == None ]
+        for rev in futureRevs:
+            attrsFound = []
+            for attr in attrsLeft:
+                if getattr(rev, "has_%s" % attr):
+                    setattr(self, attr, getattr(rev, attr))
+                    attrsFound.append(attr)
+            if attrsFound:
+                attrsLeft = [ attr for attr in attrsLeft
+                              if attr not in attrsFound ]
+                if not attrsLeft:
+                    break
+        for attr in attrsLeft:
+            setattr(self, attr, getattr(persona, attr))
+
+    def save(self):
+        """
+        The save method for a Revision can only be called once,
+        because Revision objects are meant to be immutable:
+
+          >>> p = Persona(name='Test Persona',
+          ...             url='http://www.blah.com',
+          ...             category=Category.objects.get(name='Other'))
+          >>> p.save()
+          >>> p.description = 'This is a test.'
+          >>> p.save()
+          >>> r = p.revisions.get(revision=0)
+          >>> r.status = "deleted"
+          >>> r.save()
+          Traceback (most recent call last):
+          ...
+          AssertionError: Revisions are immutable
+        """
+
+        if self.id == None:
+            super(Revision, self).save()
+        else:
+            raise AssertionError("Revisions are immutable")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/personas/sections.py	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,69 @@
+from django.core import urlresolvers
+from django.contrib.sites.models import Site
+
+class Sections( object ):
+    def __init__( self, *sections ):
+        self.sections = sections
+        self.sidebar_entries = []
+        self.views = {}
+        self.names = {}
+        for section in self.sections:
+            if section.in_sidebar:
+                self.sidebar_entries.append( section )
+            assert section.name not in self.names
+            self.names[section.name] = section
+            assert section.view not in self.views
+            self.views[section.view] = section
+
+            curr_section = section
+            while curr_section.parent_name:
+                curr_parent = self.names[curr_section.parent_name]
+                section.parents.append( curr_parent )
+                curr_section = curr_parent
+
+class Section( object ):
+    def __init__( self, name, view, in_sidebar = False,
+                  parent_name = None ):
+        self.name = name
+        self.view = view
+        self.in_sidebar = in_sidebar
+        self.parent_name = parent_name
+
+        # This will be filled out by the parent Sections object.
+        self.parents = []
+
+    def url( self ):
+        return urlresolvers.reverse( self.view )
+
+sections = Sections(
+    Section( "Home",
+             "PersonasBackend.personas.views.home_view",
+             in_sidebar = True ),
+    Section( "Browse",
+             "PersonasBackend.personas.views.list_view",
+             parent_name = "Home",
+             in_sidebar = True ),
+    Section( "Create",
+             "PersonasBackend.personas.views.new_view",
+             parent_name = "Home",
+             in_sidebar = True ),
+    Section( "Edit",
+             "PersonasBackend.personas.views.edit_view",
+             parent_name = "Home" ),
+    Section( "Log in",
+             "django.contrib.auth.views.login",
+             parent_name = "Home" ),
+    Section( "Log out",
+             "django.contrib.auth.views.logout",
+             parent_name = "Home" )
+    )
+
+def context( request ):
+    viewfunc, args, kwargs = urlresolvers.resolve( request.path )
+    viewname = ".".join( [viewfunc.__module__,
+                          viewfunc.__name__] )
+    return {
+        "site_name" : Site.objects.get_current().name,
+        "sidebar_entries" : sections.sidebar_entries,
+        "section" : sections.views.get( viewname, None )
+        }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/personas/templates/personas/base.html	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,87 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type"
+          content="text/html; charset=iso-8859-1" />
+    <title>{{ section.name }} :: {{ site_name }}</title>
+    <link rel="stylesheet"
+          type="text/css"
+          href="{{ MEDIA_URL }}css/otherpages.css" />
+    <link rel="shortcut icon" href="{{ MEDIA_URL }}img/favicon.ico"
+          type="image/x-icon" />
+  </head>
+<body>
+  <div id="content">
+    <div id="top">
+
+      <img src="http://labs.mozilla.com/projects/personas/images/personas-logo-beta.png"
+           alt="Personas for Firefox" />
+    </div>
+        
+    <div id="bottom">
+      <div><img src="http://labs.mozilla.com/projects/personas/images/otherpages-table-top.png" alt="" /></div>
+
+      <div class="table_middle">
+        <div id="sidebar">
+          <div class="menu-box">
+            <ul>
+              {% for entry in sidebar_entries %}
+              {% ifequal entry.name section.name %}
+              <li class="selected">
+                <a href="{{ entry.url }}">{{entry.name}}</a>
+              </li>
+              {% else %}
+              <li><a href="{{ entry.url }}">{{ entry.name }}</a></li>
+              {% endifequal %}
+              {% endfor %}
+              {% if perms.personas.can_publish %}
+              <li><a href="{% url django.contrib.admin.views.main.index %}"
+                     >Administer</a></li>
+              {% endif %}
+            </ul>
+          </div>
+          {% if user.is_authenticated %}
+          <p>Logged in as {{ user.email }}.</p>
+          <p><a href="{% url logout %}">Log out</a></p>
+          {% else %}
+          <a href="https://services.mozilla.com/" >Register</a> | 
+          <a href="{% url login %}">Log in</a>
+          {% endif %}
+        </div>
+        
+        <div id="section-content">
+          <div class="title">{% block title %}{{ section.name }}{% endblock %}</div>
+          <div class="divider"></div>
+      
+          <div class="details">
+            {% if messages %}
+            {% for message in messages %}
+            <div class="message">{{ message }}</div>
+            {% endfor %}
+            {% endif %}
+            {% block content %}{% endblock %}
+          </div>
+        </div>
+
+        <div><img src="http://labs.mozilla.com/projects/personas/images/otherpages-table-foot.png" alt="" /></div>
+
+      </div>
+    
+      <div id="footer">
+        <div class="labs">
+          <a href="http://labs.mozilla.com"><img src="http://labs.mozilla.com/projects/personas/images/mozilla-labs-large.png" alt="Mozilla Labs" border="0" /></a>
+
+          Personas for Firefox is a <a href="http://labs.mozilla.com">Mozilla Labs Project</a>.
+        </div>
+        <div class="legal">
+          &copy; 2007 Mozilla
+          <span>
+            <a href="http://www.mozilla.com/en-US/about/legal.html">Legal Notices</a> |
+            <a href="http://www.mozilla.com/en-US/privacy-policy.html">Privacy Policy</a>
+          </span>
+        </div>
+      </div>
+    </div>
+  </div>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/personas/templates/personas/edit.html	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,10 @@
+{% extends "personas/base.html" %}
+
+{% block content %}
+<form enctype="multipart/form-data" method="post" action=".">
+  <table class="persona-form corner-box">
+    {{ form }}
+  </table>
+  <input type="submit" class="amo-submit" value="Submit"/>
+</form>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/personas/templates/personas/home.html	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,14 @@
+{% extends "personas/base.html" %}
+
+{% block title %}What are Personas?{% endblock %}
+
+{% block content %}
+<p>Personas for Firefox is an extension that adds lightweight theming to your browser.</p>
+<p>Personas is a prototype that builds upon the ideas that:</p>
+<ul>
+<li>themes today are too hard to find, install and use</li>
+<li>graphic designers should be able to style the browser without having to code</li>
+<li>browsers can be more than just desktop software, they can include online components</li>
+<li>people just want their computer to be a little more fun and personal</li>
+</ul>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/personas/templates/personas/legacy_persona.xul	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,17 @@
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        flex="1"
+        style="background-repeat: no-repeat;"
+        onload="document.documentElement.style.backgroundImage = 'url({{image}})'">
+
+  <!-- Because CSS image loads don't block the load/pageshow events in Firefox 2,
+     - we load the image in an image tag, which does block those events, and then
+     - set the background-image property once the image has finished loading. -->
+  <image id="image" collapsed="true"/>
+
+  <script type="application/javascript;version=1.7">
+    <![CDATA[
+     document.getElementById("image").setAttribute("src", "{{image}}");
+     document.documentElement.style.backgroundPosition = "{{position}}";
+    ]]>
+  </script>
+</window>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/personas/templates/personas/list.html	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,66 @@
+{% extends "personas/base.html" %}
+
+{% block content %}
+{% if personas %}
+<p>Here's a list of all available Personas.</p>
+<p>If you have the Personas extension installed, just mouseover the
+preview image for a Persona to preview it&mdash;when your mouse moves
+away from the image, your original Persona will replace the preview.</p>
+<p>If you like the Persona, you can click on the preview image to set it
+as your current Persona.</p>
+<p>Enjoy!</p>
+<script>
+function dispatchPersonaEvent(aType, aNode, aUrl) {
+    if (aUrl) {
+        /* TODO: We should only do this if the Persona is successfully
+           set, i.e. if the user actually has Personas installed, etc. */
+        /* TODO: We should probably just use a library like jQuery to
+           do this for us. */
+        var request = new XMLHttpRequest();
+        /* TODO: Be reasonable and make this a POST, as this 'ping' will
+           change the server's state. */
+        request.open( "GET", aUrl, true );
+        request.onreadystatechange = function() {}
+        request.send(null);
+    }
+
+    var event = document.createEvent("Events");
+    event.initEvent(aType, true, false);
+    aNode.dispatchEvent(event);
+}
+</script>
+{% for persona in personas %}
+<div class="corner-box">
+  <div onclick="dispatchPersonaEvent('SelectPersona',
+                event.originalTarget,
+                '{% url report-selection persona.id %}')"
+       onmouseover="dispatchPersonaEvent('PreviewPersona',
+                    event.originalTarget)"
+       onmouseout="dispatchPersonaEvent('ResetPersona',
+                   event.originalTarget)">
+    <img persona="{{ persona.json_id }}"
+         category="{{ persona.category.json_id }}"
+         src="{{ persona.get_header_url }}" class="preview-image"
+         width="300" height="20" alt="" />
+  </div>
+  <div class="persona-title">
+    <h2 class="persona-name">{{ persona.name }}</h2>
+    {% if persona.owner %}
+    <span class="developer"> by {{ persona.owner.first_name }}
+    {{ persona.owner.last_name }}</span>
+    {% endif %}
+  </div>
+  <div class="persona-desc">{{ persona.description|safe }}</div>
+  {% if perms.personas.can_publish %}
+  <a href="{% url django.contrib.admin.views.main.change_stage "personas","persona",persona.id %}">Edit</a>
+  {% else %}
+  {% ifequal persona.owner user %}
+  <a href="{% url edit-persona persona.id %}">Edit</a>
+  {% endifequal %}
+  {% endif %}
+</div>
+{% endfor %}
+{% else %}
+<p>There are currently no personas available.</p>
+{% endif %}
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/personas/templates/personas/logged_out.html	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,5 @@
+{% extends "personas/base.html" %}
+
+{% block content %}
+<p>{{ title }}</p>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/personas/templates/personas/login.html	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,21 @@
+{% extends "personas/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="." class="persona-form corner-box">
+  <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" class="amo-submit" value="Log in" />
+  <input type="hidden" name="next" value="{{ next }}" />
+</form>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/personas/templates/personas/todo.html	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,5 @@
+{% extends "personas/base.html" %}
+
+{% block content %}
+This page is under construction.
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/personas/tests.py	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,54 @@
+import unittest
+import datetime
+
+from django.test.client import Client
+from django.core.urlresolvers import reverse
+from PersonasBackend.personas import models
+
+class JsonTests( unittest.TestCase ):
+    def setUp( self ):
+        for persona in models.Persona.objects.all():
+            persona.delete()
+        self.cat = models.Category( name = "Random Things" )
+        self.cat.save()
+        self.persona = models.Persona(
+            name = "Test Persona",
+            category = self.cat,
+            url = "http://www.blarg.com/mypersona",
+            status = "published"
+            )
+        self.persona.save()
+
+    def tearDown( self ):
+        self.persona.delete()
+        self.cat.delete()
+
+    def testCategoriesWorks( self ):
+        # Just a smoke test to make sure nothing crashes...
+        client = Client()
+        response = client.get( reverse("personas-categories-json") )
+        assert response.status_code == 200
+
+    def testAllPersonasWorks( self ):
+        # Just a smoke test to make sure nothing crashes...
+        client = Client()
+        response = client.get( reverse("personas-all-json") )
+        assert response.status_code == 200
+
+    def testPublishDateIsUpdatedProperly( self ):
+      p = models.Persona(
+          name='Yet Another Test Persona',
+          url='http://www.test.com/testpersona',
+          category=models.Category.objects.get(name='Other'))
+
+      p.save()
+      self.assertEquals( p.status, "unpublished" )
+      self.assertEquals( p.date_published, None )
+
+      p.status = "published"
+      now = datetime.datetime.now()
+      p.save()
+      assert p.date_published >= now
+
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/personas/urls.py	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,49 @@
+from django.conf.urls.defaults import *
+
+urlpatterns = patterns('',
+    # JSON feeds
+
+    # TODO: Replace the '.+' at the beginning of these with
+    # a real regexp that conveys the locale to the view.
+    url(r'^.+/personas_categories.dat$',
+     'PersonasBackend.personas.json_feeds.categories',
+     name='personas-categories-json'),
+    url(r'^.+/personas_all.dat$',
+     'PersonasBackend.personas.json_feeds.personas',
+     name='personas-all-json'),
+
+    # Dynamic wrappers for views
+    url(r'^legacy/(?P<name>.+)$',
+        'PersonasBackend.personas.views.legacy_cbeard_persona',
+        name='legacy-cbeard-persona'),
+
+    # Auth
+    url(r'^login/$', 'django.contrib.auth.views.login',
+        {'template_name':'personas/login.html'},
+        name='login'),
+    url(r'^logout/$', 'django.contrib.auth.views.logout',
+        {'template_name':'personas/logged_out.html'},
+        name='logout'),
+
+    # AJAX calls
+    url(r'^ajax/report_selection/(?P<persona_id>\d+)/$',
+        'PersonasBackend.personas.ajax.report_selection',
+        name='report-selection'),
+
+    # Personas UI
+    url(r'^new/$',
+        'PersonasBackend.personas.views.new_view',
+        name='new-persona'),
+    url(r'^(?P<persona_id>\d+)/edit/$',
+        'PersonasBackend.personas.views.edit_view',
+        name='edit-persona'),
+    url(r'^list/$', 'PersonasBackend.personas.views.list_view',
+        name='list-personas'),
+    url(r'^$', 'PersonasBackend.personas.views.home_view',
+        name='personas-home'),
+
+    # 'Fake' scaffolding view for pages that still need to be
+    # constructed.
+    url(r'^TODO/$', 'PersonasBackend.personas.views.todo_view',
+        name='TODO'),
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/personas/views.py	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,101 @@
+from django.http import HttpResponseRedirect, HttpResponseForbidden
+from django.http import HttpResponse, HttpResponseBadRequest
+from django.template import RequestContext
+from django.contrib.auth.decorators import login_required
+from django.core.urlresolvers import reverse
+from django.shortcuts import render_to_response, get_object_or_404
+
+from PersonasBackend.personas import models
+from PersonasBackend.personas import forms
+
+def legacy_cbeard_persona( request, name ):
+    PREFIX = "http://sm-labs01.mozilla.org/legacy-personas/"
+    FOOTER_URL = "%(prefix)s%(name)s/stbar-%(name)s.jpg"
+    HEADER_URL = "%(prefix)s%(name)s/tbox-%(name)s.jpg"
+
+    urldict = {"prefix" : PREFIX, "name" : name}
+
+    action = request.GET.get( "action", "" )
+
+    if action == "footer":
+        position = "bottom left"
+        img_src = FOOTER_URL % urldict
+    elif action == "header":
+        position = "top right"
+        img_src = HEADER_URL % urldict
+    else:
+        return HttpResponseBadRequest( "Invalid or unsupported action: %s" %
+                                       action )
+
+    return render_to_response(
+        "personas/legacy_persona.xul",
+        { "image" : img_src, "position" : position },
+        mimetype = "application/vnd.mozilla.xul+xml"
+        )
+
+def list_view( request ):
+    personas = models.Persona.objects.filter( status="published" )
+    return render_to_response(
+        "personas/list.html",
+        { "personas" : personas,
+          "title" : "Browse Personas" },
+        context_instance = RequestContext(request)
+        )
+
+def home_view( request ):
+    return render_to_response(
+        "personas/home.html",
+        { "title" : "Home" },
+        context_instance = RequestContext(request)
+        )
+
+def todo_view( request ):
+    return render_to_response(
+        "personas/todo.html",
+        { "title" : "Under Construction" },
+        context_instance = RequestContext(request)
+        )
+
+def new_view( request ):
+    return edit_view( request )
+
+@login_required
+def edit_view( request, persona_id=None ):
+    if persona_id is None:
+        persona = None
+        pageTitle = "Create a new Persona"
+    else:
+        persona = get_object_or_404( models.Persona, id=persona_id )
+        if not persona.can_user_edit( request.user ):
+            return HttpResponseForbidden(
+                "<h1>You do not have permission to edit "
+                "this Persona.</h1>"
+                )
+        pageTitle = "Edit Persona"
+
+    if request.method == "POST":
+        form = forms.PersonaForm( request.POST,
+                                  instance=persona )
+        if form.is_valid():
+            newPersona = form.save( commit=False )
+            newPersona.save( updater = request.user )
+            if persona is None:
+                msgText = ("Persona created successfully.  It will need "
+                           "to be reviewed by a staff member "
+                           "before it is published.")
+            else:
+                msgText = ("Persona edited successfully.  Your changes "
+                           "will need to be approved by a staff member "
+                           "before they can take effect.")
+            request.user.message_set.create( message = msgText )
+            url = reverse("edit-persona", args=[newPersona.id])
+            return HttpResponseRedirect( url )
+    else:
+        form = forms.PersonaForm( instance=persona )
+
+    return render_to_response(
+        "personas/edit.html",
+        { "form" : form,
+          "title" : pageTitle },
+        context_instance = RequestContext(request)
+        )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/settings.py	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,109 @@
+# Django settings for PersonasBackend project.
+
+import os
+
+myPath = os.path.abspath( os.path.dirname( __file__ ) )
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+    # ('Your Name', 'your_email@domain.com'),
+)
+
+MANAGERS = ADMINS
+
+DATABASE_ENGINE = 'sqlite3'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
+DATABASE_NAME = os.path.join( myPath, "temp_db" )             # Or path to database file if using sqlite3.
+DATABASE_USER = ''             # 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.
+
+# 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 = 'America/Chicago'
+
+# 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 = os.path.normpath( os.path.join( myPath, "..", "media" ) )
+
+BASE_DIR = "personas/"
+
+# URL that handles the media served from MEDIA_ROOT.
+# Example: "http://media.lawrence.com"
+MEDIA_URL = '/%smedia/' % BASE_DIR
+
+# 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 = '/%sadmin/media/' % BASE_DIR
+
+# Make this unique, and don't share it with anybody.
+SECRET_KEY = 'x=0z4lnv#vws4p4a%r(fb=(wh&o4k)k!5!a9b*3-j7s87^v43d'
+
+# 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.cache.CacheMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.middleware.doc.XViewMiddleware',
+)
+
+LOGIN_URL = '/%slogin/' % BASE_DIR
+LOGIN_REDIRECT_URL = '/%s' % BASE_DIR
+
+ROOT_URLCONF = 'PersonasBackend.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.
+    os.path.normpath( os.path.join( myPath, "..", "templates" ) ),
+)
+
+INSTALLED_APPS = (
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.sites',
+    'django.contrib.admin',
+    'PersonasBackend.personas',
+)
+
+TEMPLATE_CONTEXT_PROCESSORS = (
+    "django.core.context_processors.auth",
+    "django.core.context_processors.debug",
+    "django.core.context_processors.i18n",
+    "django.core.context_processors.media",
+    "PersonasBackend.personas.sections.context",
+)
+
+CACHE_BACKEND = 'locmem:///'
+CACHE_MIDDLEWARE_SECONDS = 5
+CACHE_MIDDLEWARE_KEY_PREFIX = "personas"
+
+AUTHENTICATION_BACKENDS = (
+    "PersonasBackend.weaveproxyauth.Backend",
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/urls.py	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,28 @@
+import os
+
+from django.conf.urls.defaults import *
+from PersonasBackend import settings
+import django.contrib.admin
+
+urlpatterns = patterns('',
+    # Admin media
+    # TODO: Remove the static.serve, b/c it's supposedly insecure.
+    (r'^%sadmin/media/(?P<path>.*)$' % settings.BASE_DIR,
+     'django.views.static.serve',
+     {'document_root': os.path.join( django.contrib.admin.__path__[0],
+                                     "media" )}),
+
+    # Admin
+    (r'^%sadmin/' % settings.BASE_DIR,
+     include('django.contrib.admin.urls')),
+
+    # Personas media
+    # TODO: Remove the static.serve, b/c it's supposedly insecure.
+    (r'^%smedia/(?P<path>.*)$' % settings.BASE_DIR,
+     'django.views.static.serve',
+     {'document_root': settings.MEDIA_ROOT}),
+
+    # Personas
+    (r'^%s' % settings.BASE_DIR,
+     include('PersonasBackend.personas.urls')),
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/utils.py	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,8 @@
+from django.contrib.sites.models import Site
+
+def make_absolute_url( path ):
+    domain = Site.objects.get_current().domain
+    if domain == "localhost":
+        domain = "localhost:8000"
+    url = "http://%s%s" % (domain, path)
+    return url
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/personasbackend/weaveproxyauth.py	Wed Apr 02 11:59:58 2008 -0700
@@ -0,0 +1,59 @@
+import sha
+import urllib2
+import httplib
+
+from django.contrib.auth.models import User
+
+class Backend(object):
+    def authenticate(self, username=None, password=None):
+        hexuser = sha.sha(username).hexdigest()
+        url = "https://services.mozilla.com/user/%s/" % hexuser
+        authHandler = urllib2.HTTPBasicAuthHandler()
+        authHandler.add_password("services.mozilla.com - proxy",
+                                 "services.mozilla.com",
+                                 username,
+                                 password)
+
+        opener = urllib2.build_opener(authHandler)
+
+        try:
+            obj = opener.open(url)
+            obj.read()
+            auth_successful = True
+        except urllib2.HTTPError, e:
+            if e.code == httplib.UNAUTHORIZED:
+                auth_successful = False
+            else:
+                raise
+
+        if auth_successful:
+            try:
+                user = User.objects.get(email=username)
+            except User.DoesNotExist:
+                # We have to go through this annoyance because Django
+                # auth requires us to enter a username, and the username
+                # can be no more than 30 characters and can't include
+                # anything other than alphanumeric characters.
+                munged_username = "".join(
+                    [char for char in username if char.isalnum()]
+                    )[:25]
+
+                offset = 0
+                while User.objects.filter(
+                    username = munged_username + str(offset)
+                    ):
+                    offset += 1
+
+                user = User(username=munged_username + str(offset),
+                            password="Retrieved from Weave",
+                            email=username)
+                user.save()
+            return user
+
+        return None
+
+    def get_user(self, user_id):
+        try:
+            return User.objects.get(pk=user_id)
+        except User.DoesNotExist:
+            return None