[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r19405: {} This is the first step in a direction of a djanjo Tor Weathe (in weather/branches: . django django/torweather django/torweather/relationships django/torweather/templates django/torweather/templates/admin django/torweather/templates/polls django/torweather/templates/relationships)



Author: ioerror
Date: 2009-05-01 01:56:47 -0400 (Fri, 01 May 2009)
New Revision: 19405

Added:
   weather/branches/django/
   weather/branches/django/torweather/
   weather/branches/django/torweather/__init__.py
   weather/branches/django/torweather/manage.py
   weather/branches/django/torweather/relationships/
   weather/branches/django/torweather/relationships/__init__.py
   weather/branches/django/torweather/relationships/admin.py
   weather/branches/django/torweather/relationships/forms.py
   weather/branches/django/torweather/relationships/models.py
   weather/branches/django/torweather/relationships/urls.py
   weather/branches/django/torweather/relationships/views.py
   weather/branches/django/torweather/settings.py
   weather/branches/django/torweather/templates/
   weather/branches/django/torweather/templates/404.html
   weather/branches/django/torweather/templates/500.html
   weather/branches/django/torweather/templates/admin/
   weather/branches/django/torweather/templates/admin/base_site.html
   weather/branches/django/torweather/templates/admin/index.html
   weather/branches/django/torweather/templates/manage_subscription.html
   weather/branches/django/torweather/templates/manage_subscription.html-old
   weather/branches/django/torweather/templates/polls/
   weather/branches/django/torweather/templates/polls/poll_detail.html
   weather/branches/django/torweather/templates/polls/poll_list.html
   weather/branches/django/torweather/templates/polls/results.html
   weather/branches/django/torweather/templates/polls/vote.html
   weather/branches/django/torweather/templates/relationships/
   weather/branches/django/torweather/templates/relationships/confirmation.html
   weather/branches/django/torweather/templates/relationships/index.html
   weather/branches/django/torweather/templates/relationships/index.html-old
   weather/branches/django/torweather/templates/relationships/modification.html
   weather/branches/django/torweather/templates/relationships/pending.html
   weather/branches/django/torweather/templates/relationships/subscribe.html
   weather/branches/django/torweather/templates/relationships/subscription-thanks.html
   weather/branches/django/torweather/templates/relationships/unsubscribe.html
   weather/branches/django/torweather/urls.py
Log:
This is the first step in a direction of a djanjo Tor Weather. This is very much a work in progress, for the love of _$_ do not judge my first web application framework webapp.


Added: weather/branches/django/torweather/manage.py
===================================================================
--- weather/branches/django/torweather/manage.py	                        (rev 0)
+++ weather/branches/django/torweather/manage.py	2009-05-01 05:56:47 UTC (rev 19405)
@@ -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)

Added: weather/branches/django/torweather/relationships/admin.py
===================================================================
--- weather/branches/django/torweather/relationships/admin.py	                        (rev 0)
+++ weather/branches/django/torweather/relationships/admin.py	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,10 @@
+from torweather.relationships.models import Node
+from torweather.relationships.models import NodeStatus
+from torweather.relationships.models import Subscriber
+from torweather.relationships.models import Subscription
+from django.contrib import admin
+
+admin.site.register(Subscription)
+admin.site.register(Node)
+admin.site.register(NodeStatus)
+admin.site.register(Subscriber)

Added: weather/branches/django/torweather/relationships/forms.py
===================================================================
--- weather/branches/django/torweather/relationships/forms.py	                        (rev 0)
+++ weather/branches/django/torweather/relationships/forms.py	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,16 @@
+from django.forms import ModelForm
+from torweather.relationships.models import Subscriber
+from torweather.relationships.models import Subscription
+from torweather.relationships.models import Node
+from torweather.relationships.models import NodeStatus
+
+class SubscriberForm(ModelForm):
+    class Meta:
+        model = Subscriber
+
+# Create a form for subscribers
+#form = SubscriberForm()
+
+# modification of forms for subscribers:
+#subscriber = Subscriber.objects.get(pk=1)
+#form = SubscriberForm(instance=subscriber)

Added: weather/branches/django/torweather/relationships/models.py
===================================================================
--- weather/branches/django/torweather/relationships/models.py	                        (rev 0)
+++ weather/branches/django/torweather/relationships/models.py	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,137 @@
+from django.db import models
+from django.forms import ModelForm
+import datetime
+import re
+
+class Subscriber(models.Model):
+    """ A unique subscriber for a given node """
+    def __unicode__(self):
+        return self.subscriber_email
+    # We want a point of contact
+    subscriber_email = models.EmailField('email address', max_length=75)
+    # We want to be able to suppress alerts per user
+    subscriber_suppress_alerts = models.BooleanField('Node alert suppression', 0)
+    # Was the node signed up today?
+    def subscribed_today(self):
+         return self.pub_date.date() == datetime.date.today()
+    subscribed_today.short_description = 'Subscribed Today?'
+
+class Node(models.Model):
+    """ A unique node in the Tor network """
+    def __unicode__(self):
+        return unicode(self.node_name)
+    # We want to store the Node nickname
+    node_name = models.CharField('Node name', max_length=200)
+    # We want to store a unique fingerprint
+    node_fingerprint = models.CharField('Node fingerprint', max_length=40)
+    # We'll start the strike count at 0
+    node_strike_count = models.IntegerField('Node strikes', default=0)
+    # By default, we'll alert
+    node_suppress_alerts = models.BooleanField('Alert supression', default=False)
+    # By default, we'll treat the node as down
+    node_state = models.BooleanField('Node state', default=False)
+    # We want to tie this into a user in the subscription object
+    node_subscriber = models.ForeignKey(Subscriber)
+
+class Subscription(models.Model):
+    """ A Subscription for a Subscriber """
+    # Our possible delay times
+    ALERT_DELAY = (
+    ('0', 'No delay'),
+    ('720', 'Half day'),
+    ('1440', 'One day'),
+    ('10080','One week'),
+    )
+    # We want a point of contact
+    subscription_email = models.EmailField('email address', max_length=75)
+    # We want to be able to suppress alerts per user
+    #subscriber_suppress_alerts = models.BooleanField('Node alert suppression', 0, blank=True, editable=False)
+    # We want to let people make arbitrary notes
+    subscription_comment = models.CharField('Subscription comment', max_length=200, blank=True)
+    # We want to be able to suppress alerts per subscription
+    subscription_suppress_alerts = models.BooleanField('Node alert suppression', 0, blank=True, editable=False)
+    # We want to tie this to a subscriber in the database
+    #subscription_user = models.ForeignKey(Subscriber)
+    # We want to know when the subscription started
+    subscription_date = models.DateTimeField('Node subscription date', blank=True, null=True, editable=False)
+    #"notify me" a) instantly b) after 6 hours of being down c) after 2 days
+    # In minutes
+    subscription_alert_delay = models.IntegerField('Alert delay (in minutes)', blank=False, choices=ALERT_DELAY, default=0)
+    # We have a list of many Tor servers, just add references to them
+    #subscription_node = models.ForeignKey(Node)
+    subscription_node = models.CharField('Node fingerprint', max_length=40)
+
+    # We want a confirmation key
+    subscription_key = models.CharField('Subscription confirmation key', max_length=40)
+
+    # By default, we'll assume they're not confirmed
+    subscriber_confirmed = models.BooleanField('Subscription Confirmed', 0)
+
+    def subscribed_today(self):
+         return self.pub_date.date() == datetime.date.today()
+    subscribed_today.short_description = 'Subscribed Today?'
+
+    def randstring():
+        # This is where we sometimes return '-' and we shouldn't
+        "Produce a random alphanumeric string for authentication"
+        theory = base64.urlsafe_b64encode(os.urandom(18))[:-1]
+        if theory[-1] == "-": # some email clients don't like URLs ending in -
+            theory[-1] = 'x'
+        return theory
+
+    def __unicode__(self):
+        return self.subscription_email
+
+class NodeStatus(models.Model):
+    """ The status of a given node """
+    def __unicode_(self):
+        return self.node_status_
+    node = models.ForeignKey(Node)
+
+def contact(request):
+    if request.method == 'POST': # If the form has been submitted...
+        form = ContactForm(request.POST) # A form bound to the POST data
+        if form.is_valid(): # All validation rules pass
+            # Process the data in form.cleaned_data
+            # ...
+            return HttpResponseRedirect('/thanks/') # Redirect after POST
+    else:
+        form = ContactForm() # An unbound form
+
+    return render_to_response('contact.html', {
+        'form': form,
+    })
+
+class SubscriberForm(ModelForm):
+    class Meta:
+        model = Subscriber
+
+class SubscriptionForm(ModelForm):
+    def clean(self):
+        pass
+
+    # Node ids are 40 digit hexidecimal numbers
+    node_okay = re.compile("(0x)?[a-fA-F0-9]{40}\Z")
+    def check_node_id(self, node):
+        if self.node_okay.match(node):
+            return True
+        else:
+            return False
+
+    # This is called when a user submits a node id
+    def clean_subscription_node(self):
+        self.check_node_id(self.cleaned_data['subscription_node'])
+
+    class Meta:
+        model = Subscription
+        fields = ('subscription_node', 'subscription_email'
+                 ,'subscription_comment','subscription_alert_delay')
+
+class NodeForm(ModelForm):
+    class Meta:
+        model = Node
+
+class NodeStatusForm(ModelForm):
+    class Meta:
+        model = NodeStatus
+

Added: weather/branches/django/torweather/relationships/urls.py
===================================================================
--- weather/branches/django/torweather/relationships/urls.py	                        (rev 0)
+++ weather/branches/django/torweather/relationships/urls.py	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,21 @@
+from django.conf.urls.defaults import *
+from torweather.relationships.models import Subscription
+from torweather.relationships.models import Subscriber
+from torweather.relationships.models import Node
+from torweather.relationships.models import NodeStatus
+
+urlpatterns = patterns('',
+    # By default, lets serve up the signup page as our index
+    #(r'^$','django.views.generic.simple.direct_to_template', {'template': 'relationships/index.html'}),
+    (r'^$','torweather.relationships.views.manage_subscription', ),
+    # Users submit and we'll thank then unless there's an error
+    (r'^subscribe$','torweather.relationships.views.subscribe', ),
+    (r'^manage_subscription$','torweather.relationships.views.manage_subscription', ),
+    # We want to only alert after we've confirmed a round trip
+    (r'^confirmation/(?P<confirmation_token>)$','torweather.relationships.views.confirmation', ),
+    (r'^pending/(?P<pending_token>)$','torweather.relationships.views.pending', ),
+    # We want to unsubscribe people with magic tokens
+    (r'^unsubscribe/(?P<unsubscribe_token>)$','torweather.relationships.views.unsubscribe', {'template': 'relationships/unsubscribe.html'}),
+    # We want to allow people a way to adjust their preferences
+    (r'^modification/(?P<modify_token>)$','direct_to_template', {'template': 'relationships/modification.html'}),
+    )

Added: weather/branches/django/torweather/relationships/views.py
===================================================================
--- weather/branches/django/torweather/relationships/views.py	                        (rev 0)
+++ weather/branches/django/torweather/relationships/views.py	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,84 @@
+from django.shortcuts import render_to_response, get_object_or_404
+from django.http import HttpResponse
+from django.http import HttpResponseRedirect
+from django import forms
+from django.forms.models import modelformset_factory
+from torweather.relationships.models import Subscriber
+from torweather.relationships.models import Subscription
+from torweather.relationships.models import Node
+from torweather.relationships.models import NodeStatus
+from torweather.relationships.models import *
+
+
+def index(request):
+    form = SubscriberForm()
+    return render_to_response('relationships/index.html', {'form': form})
+
+# We want to return a few things:
+# Error cases:
+# 	That doesn't look like a proper Tor node ID.
+# 	That doesn't look like a proper email address.
+# "That email address looks fishy to our refined sensibilities!"
+# Success cases:
+# 	Thanks for signing up
+# "Thank you for using Tor Weather. A confirmation request has been sent to jacob@xxxxxxxxxxxxxx"
+# That email has a url like:
+# https://weather.torproject.org/confirm-subscribe/u7x-9iz4ScJBRRnNQqGG5F0
+# relationships/subscription-thanks.html
+def subscribe(request):
+    if request.method == 'POST':
+        form = SubscriberForm(request.POST)
+        if form.is_valid():
+            # We need to process form.cleaned_data
+            node = form.cleaned_data['node']
+            email = form.cleaned_data['email']
+            comment = form.cleaned_data['comment']
+            delay = form.cleaned_data['delay']
+            # Lets stuff this data into a database here or error out
+            # If we error out, we should be sure to supress error info
+            saved_form = form.save()
+            return HttpResponseRedirect('/confirmation/')
+    else:
+        form = SubscriberForm()
+        render_to_response('relationships/index.html', {'form': form})
+    return render_to_response('relationships/error.html', {'form': form})
+
+# We want to return a page where people can POST an unsubscribe
+# http://weather.torproject.org/unsubscribe/8U_oqg2LrF_clTbQ7KQIGb0
+def unsubscribe(request, subscription_key):
+    if request.method == 'GET':
+    # Validate and then flag them for removal
+        print subscription_key
+    #p = get_object_or_404(Poll, pk=poll_id)
+    #return render_to_response('relationships/unsubscribe.html', {'poll': p})
+
+#
+# We have urls that look like the following:
+# https://weather.torproject.org/confirm-subscribe/u7x-9iz4ScJBRRnNQqGG5F0
+def confirmation(request, confirmation_token):
+    token = get_object_or_404(Subscriber, pk=confirmation_token)
+    # If we have a token, great! Modify their entry in the database
+    return render_to_response('relationships/confirmation.html')
+
+def pending(request, pending_token):
+    # This is just a redirect and a render_to_response place holder
+    return render_to_response('relationships/pending.html')
+
+# We want to return information we have for a given user
+# https://weather.torproject.org/confirm-subscribe/u7x-9iz4ScJBRRnNQqGG5F0
+def modification(request):
+    p = get_object_or_404(Poll, pk=poll_id)
+    return render_to_response('relationships/modification.html', {'poll': p})
+
+def manage_subscription(request):
+    form = SubscriptionForm()
+    if request.method == 'POST':
+        form = SubscriptionForm(request.POST)
+
+        # We should confirm the node id is valid
+        if form.is_valid():
+            form.save()
+            return HttpResponseRedirect('pending')
+    else:
+        form = SubscriptionForm()
+    return render_to_response("manage_subscription.html", {"form":form,})

Added: weather/branches/django/torweather/settings.py
===================================================================
--- weather/branches/django/torweather/settings.py	                        (rev 0)
+++ weather/branches/django/torweather/settings.py	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,84 @@
+# Django settings for torweather project.
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+     ('Tor Weather Administrator', 'tor-weather@xxxxxxxxxxxxxx'),
+)
+
+MANAGERS = ADMINS
+
+DATABASE_ENGINE = 'sqlite3'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+DATABASE_NAME = '/tmp/tor-weather.sqlite3'             # 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://en.wikipedia.org/wiki/List_of_tz_zones_by_name
+# although not all choices may be available 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.i18nguy.com/unicode/language-identifiers.html
+LANGUAGE_CODE = 'en-us'
+
+SITE_ID = 1
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = True
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+MEDIA_ROOT = ''
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+# Examples: "http://media.lawrence.com";, "http://example.com/media/";
+MEDIA_URL = ''
+
+# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
+# trailing slash.
+# Examples: "http://foo.com/media/";, "/media/".
+ADMIN_MEDIA_PREFIX = '/media/'
+
+# Make this unique, and don't share it with anybody.
+# this is a bogus key, just to ensure that weather will run out of svn
+# DO NOT USE THIS KEY FOR PRODUCTION! DO NOT USE THIS FOR PRODUCTION!
+SECRET_KEY = 'm5n+7vo3u*!qnzy+d9#1-u%s6+f35fpjg#$k&tjagsm&9j(ca@'
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+    'django.template.loaders.filesystem.load_template_source',
+    'django.template.loaders.app_directories.load_template_source',
+#     'django.template.loaders.eggs.load_template_source',
+)
+
+MIDDLEWARE_CLASSES = (
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+)
+
+ROOT_URLCONF = 'torweather.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.
+    "/var/www/weather/branches/django/torweather/templates/"
+)
+
+INSTALLED_APPS = (
+    'django.contrib.auth',
+    'django.contrib.admin',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    #'django.contrib.sites',
+    'torweather.relationships'
+)

Added: weather/branches/django/torweather/templates/404.html
===================================================================
--- weather/branches/django/torweather/templates/404.html	                        (rev 0)
+++ weather/branches/django/torweather/templates/404.html	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1 @@
+404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found404 not found

Added: weather/branches/django/torweather/templates/500.html
===================================================================
--- weather/branches/django/torweather/templates/500.html	                        (rev 0)
+++ weather/branches/django/torweather/templates/500.html	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1 @@
+500 error

Added: weather/branches/django/torweather/templates/admin/base_site.html
===================================================================
--- weather/branches/django/torweather/templates/admin/base_site.html	                        (rev 0)
+++ weather/branches/django/torweather/templates/admin/base_site.html	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,10 @@
+{% extends "admin/base.html" %}
+{% load i18n %}
+
+{% block title %}{{ title }} | {% trans 'Tor Weather site admin' %}{% endblock %}
+
+{% block branding %}
+<h1 id="site-name">{% trans 'Tor Weather administration' %}</h1>
+{% endblock %}
+
+{% block nav-global %}{% endblock %}

Added: weather/branches/django/torweather/templates/admin/index.html
===================================================================
--- weather/branches/django/torweather/templates/admin/index.html	                        (rev 0)
+++ weather/branches/django/torweather/templates/admin/index.html	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,68 @@
+{% extends "admin/base_site.html" %}
+{% load i18n %}
+
+{% block stylesheet %}{% load adminmedia %}{% admin_media_prefix %}css/dashboard.css{% endblock %}
+
+{% block coltype %}colMS{% endblock %}
+
+{% block bodyclass %}dashboard{% endblock %}
+
+{% block breadcrumbs %}{% endblock %}
+
+{% block content %}
+<div id="content-main">
+
+{% if app_list %}
+    {% for app in app_list %}
+        <div class="module">
+        <table summary="{% blocktrans with app.name as name %}Models available in the {{ name }} application.{% endblocktrans %}">
+        <caption><a href="{{ app.app_url }}" class="section">{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}</a></caption>
+        {% for model in app.models %}
+            <tr>
+            {% if model.perms.change %}
+                <th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
+            {% else %}
+                <th scope="row">{{ model.name }}</th>
+            {% endif %}
+
+            {% if model.perms.add %}
+                <td><a href="{{ model.admin_url }}add/" class="addlink">{% trans 'Add' %}</a></td>
+            {% else %}
+                <td>&nbsp;</td>
+            {% endif %}
+
+            {% if model.perms.change %}
+                <td><a href="{{ model.admin_url }}" class="changelink">{% trans 'Change' %}</a></td>
+            {% else %}
+                <td>&nbsp;</td>
+            {% endif %}
+            </tr>
+        {% endfor %}
+        </table>
+        </div>
+    {% endfor %}
+{% else %}
+    <p>{% trans "You don't have permission to edit anything." %}</p>
+{% endif %}
+</div>
+{% endblock %}
+
+{% block sidebar %}
+<div id="content-related">
+    <div class="module" id="recent-actions-module">
+        <h2>{% trans 'Recent Actions' %}</h2>
+        <h3>{% trans 'My Actions' %}</h3>
+            {% load log %}
+            {% get_admin_log 10 as admin_log for_user user %}
+            {% if not admin_log %}
+            <p>{% trans 'None available' %}</p>
+            {% else %}
+            <ul class="actionlist">
+            {% for entry in admin_log %}
+            <li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">{% if not entry.is_deletion %}<a href="{{ entry.get_admin_url }}">{% endif %}{{ entry.object_repr }}{% if not entry.is_deletion %}</a>{% endif %}<br /><span class="mini quiet">{% filter capfirst %}{% trans entry.content_type.name %}{% endfilter %}</span></li>
+            {% endfor %}
+            </ul>
+            {% endif %}
+    </div>
+</div>
+{% endblock %}

Added: weather/branches/django/torweather/templates/manage_subscription.html
===================================================================
--- weather/branches/django/torweather/templates/manage_subscription.html	                        (rev 0)
+++ weather/branches/django/torweather/templates/manage_subscription.html	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+  <title>Tor Weather</title>
+  <link rel="stylesheet" type="text/css" href="http://weather.torproject.org/stylesheet.css";>
+</head>
+<body>
+<div class="center">
+<table class="banner" border="0" cellpadding="0" cellspacing="0" summary="">
+    <tr>
+
+        <td class="banner-left"><a href="https://www.torproject.org/";><img src="http://weather.torproject.org/top-left.png"; alt="Click to go to home page" width="193" height="79"></a></td>
+        <td class="banner-middle">
+        &nbsp;
+        </td>
+        <td class="banner-right">
+        </td>
+    </tr>
+</table>
+<div class="main-column">
+<h2>Tor Weather</h2>
+
+<hr>
+
+<h3>Sign Up!</h3>
+
+<p>
+<form method="POST" action="">
+{{ form.as_p }}
+<input type="submit" class="submit" value="Subscribe to Tor Weather"/>
+</form>
+</p>
+<hr>
+<h3>FAQ</h3>
+<br>
+<p>Q: <b>Where can I find the fingerprint for my server?</b></p>
+<p>A: <i>Often your node fingerprint can be found on unix-like machines in the file: <tt>/var/lib/tor/fingerprint</tt></i></p>
+<p>Q: <b>Will I be overloaded with alerts that I cannot suppress?</b></p>
+<p>A: <i>No.</i>
+<p>Q: <b>Can I unsubscribe easily?</b></p>
+<p>A: <i>Yes.</i>
+<p>Q: <b>I'm having a problem, can you help me?</b></p>
+<p>A: <i>Yes. Send an email to <tt>tor-weather @ torproject dot org</tt></i>
+<br>
+<hr>
+<br>
+<p><i>Please note that while we won't ever intentionally publish them, the address/node pairs sent to this server are not protected against SMTP eavesdropping, hacking, or lawyers.</i>
+</form>
+</div>
+</div>
+</body>
+</html>

Added: weather/branches/django/torweather/templates/manage_subscription.html-old
===================================================================
--- weather/branches/django/torweather/templates/manage_subscription.html-old	                        (rev 0)
+++ weather/branches/django/torweather/templates/manage_subscription.html-old	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+  <title>Tor Weather</title>
+  <link rel="stylesheet" type="text/css" href="http://weather.torproject.org/stylesheet.css";>
+</head>
+<body>
+<div class="center">
+<table class="banner" border="0" cellpadding="0" cellspacing="0" summary="">
+    <tr>
+
+        <td class="banner-left"><a href="https://www.torproject.org/";><img src="http://weather.torproject.org/top-left.png"; alt="Click to go to home page" width="193" height="79"></a></td>
+        <td class="banner-middle">
+        &nbsp;
+        </td>
+        <td class="banner-right">
+        </td>
+    </tr>
+</table>
+<div class="main-column">
+<h2>Tor Weather</h2>
+
+<hr>
+
+<h3>Sign Up!</h3>
+
+<br>
+<p>
+<form method="POST" action="">
+    {{ formset.management_form }}
+    {% for form in formset.forms %}
+        {{ form.id }}
+        {% for field in form %}
+            {{ field.label_tag }}: {{ field }} <br>
+        {% endfor %}
+    <input type="submit" class="submit" value="Subscribe to Tor Weather" name="sa"/>
+    {% endfor %}
+</form>
+</p>
+<hr>
+<h3>FAQ</h3>
+<br>
+<p>Q: <b>Where can I find the fingerprint for my server?</b></p>
+<p>A: <i>Often your node fingerprint can be found on unix-like machines in the file: <tt>/var/lib/tor/fingerprint</tt></i></p>
+<p>Q: <b>Will I be overloaded with alerts that I cannot suppress?</b></p>
+<p>A: <i>No.</i>
+<p>Q: <b>Can I unsubscribe easily?</b></p>
+<p>A: <i>Yes.</i>
+<p>Q: <b>I'm having a problem, can you help me?</b></p>
+<p>A: <i>Yes. Send an email to <tt>tor-weather @ torproject dot org</tt></i>
+<br>
+<hr>
+<br>
+<p><i>Please note that while we won't ever intentionally publish them, the address/node pairs sent to this server are not protected against SMTP eavesdropping, hacking, or lawyers.</i>
+</form>
+</div>
+</div>
+</body>
+</html>

Added: weather/branches/django/torweather/templates/polls/poll_detail.html
===================================================================
--- weather/branches/django/torweather/templates/polls/poll_detail.html	                        (rev 0)
+++ weather/branches/django/torweather/templates/polls/poll_detail.html	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,11 @@
+<h1>{{ object.question }}</h1>
+
+{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
+
+<form action="vote/" method="post">
+{% for choice in object.choice_set.all %}
+    <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
+    <label for="choice{{ forloop.counter }}">{{ choice.choice }}</label><br />
+{% endfor %}
+<input type="submit" value="Vote" />
+</form>

Added: weather/branches/django/torweather/templates/polls/poll_list.html
===================================================================
--- weather/branches/django/torweather/templates/polls/poll_list.html	                        (rev 0)
+++ weather/branches/django/torweather/templates/polls/poll_list.html	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,10 @@
+{% if object_list %}
+    <p>Here is the full list of polls available:</p>
+    <ul>
+    {% for object in object_list %}
+        <li><a href="{{ object.id }}">{{ object.question }}</a></li>
+    {% endfor %}
+    </ul>
+{% else %}
+    <p>No polls are available.</p>
+{% endif %}

Added: weather/branches/django/torweather/templates/polls/results.html
===================================================================
--- weather/branches/django/torweather/templates/polls/results.html	                        (rev 0)
+++ weather/branches/django/torweather/templates/polls/results.html	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,9 @@
+<h1><a href="/polls/{{ object.id }}">{{ object.question }}</a></h1>
+
+<ul>
+{% for choice in object.choice_set.all %}
+    <li>{{ choice.choice }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
+{% endfor %}
+</ul>
+
+Would you like to <a href="/polls/">view other polls</a>?

Added: weather/branches/django/torweather/templates/polls/vote.html
===================================================================
--- weather/branches/django/torweather/templates/polls/vote.html	                        (rev 0)
+++ weather/branches/django/torweather/templates/polls/vote.html	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,7 @@
+<h1>{{ poll.question }}</h1>
+Please select one of the following choices:
+<ul>
+{% for choice in poll.choice_set.all %}
+    <li>{{ choice.choice }}</li>
+{% endfor %}
+</ul>

Added: weather/branches/django/torweather/templates/relationships/confirmation.html
===================================================================
--- weather/branches/django/torweather/templates/relationships/confirmation.html	                        (rev 0)
+++ weather/branches/django/torweather/templates/relationships/confirmation.html	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+  <title>Tor Weather</title>
+  <link rel="stylesheet" type="text/css" href="http://weather.torproject.org/stylesheet.css";>
+</head>
+<body>
+<div class="center">
+<table class="banner" border="0" cellpadding="0" cellspacing="0" summary="">
+    <tr>
+
+        <td class="banner-left"><a href="https://www.torproject.org/";><img src="http://weather.torproject.org/top-left.png"; alt="Click to go to home page" width="193" height="79"></a></td>
+        <td class="banner-middle">
+        &nbsp;
+        </td>
+        <td class="banner-right">
+        </td>
+    </tr>
+</table>
+<div class="main-column">
+<h2>Subscription confirmed!</h2>
+
+<hr>
+
+Thank you. You've succesfully confirmed your subscription.
+<br>
+</p>
+<hr>
+<p><i>Please note that while we won't ever intentionally publish them, the address/node pairs sent to this server are not protected against SMTP eavesdropping, hacking, or lawyers.</i></p>
+</form>
+</div>
+</div>
+</body>
+</html>

Added: weather/branches/django/torweather/templates/relationships/index.html
===================================================================
--- weather/branches/django/torweather/templates/relationships/index.html	                        (rev 0)
+++ weather/branches/django/torweather/templates/relationships/index.html	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,4 @@
+<form action="subscribe" method="POST">
+{{ form.as_p }}
+<input type="submit" value="Submit" />
+</form>

Added: weather/branches/django/torweather/templates/relationships/index.html-old
===================================================================
--- weather/branches/django/torweather/templates/relationships/index.html-old	                        (rev 0)
+++ weather/branches/django/torweather/templates/relationships/index.html-old	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,73 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+  <title>Tor Weather</title>
+  <link rel="stylesheet" type="text/css" href="http://weather.torproject.org/stylesheet.css";>
+</head>
+<body>
+<div class="center">
+<table class="banner" border="0" cellpadding="0" cellspacing="0" summary="">
+    <tr>
+
+        <td class="banner-left"><a href="https://www.torproject.org/";><img src="http://weather.torproject.org/top-left.png"; alt="Click to go to home page" width="193" height="79"></a></td>
+        <td class="banner-middle">
+        &nbsp;
+        </td>
+        <td class="banner-right">
+        </td>
+    </tr>
+</table>
+<div class="main-column">
+<h2>Tor Weather</h2>
+
+<hr>
+
+<h3>Sign Up!</h3>
+
+<br>
+<form method="post" action="/relationships/subscribe">
+You can use this form to request status updates to tell you when a particular
+Tor node has become unreachable for a sustained period of time.
+<br><br>
+
+<p>
+Email:<br>
+<input type="text" name="email" size="50" maxlength="255" value="Enter one email address" onclick="if (this.value == 'Enter one email address') {this.value = ''}" />
+</p><p>
+Node fingerprint:<br>
+<input type="text" name="node" size="50" maxlength="255" value="Enter one Tor node ID" onclick="if (this.value == 'Enter one Tor node ID') {this.value = ''}" />
+</p><p>
+Node comment:<br>
+<input type="text" name="comment" size="50" maxlength="255" value="Enter a custom reminder about this Tor node ID" onclick="if (this.value == 'Enter a custom reminder about this Tor node ID') {this.value = ''}" />
+</p><p>
+Alerting delay preference:<br>
+<select name="delay">
+<option value="0">No delay</option>
+<option value="30">Thirty minutes</option>
+<option value="60">Sixty minutes</option>
+<option value="90">Ninety minutes</option>
+</select>
+</p><p>
+
+<input type="submit" class="submit" value="Subscribe to Tor Weather" name="sa"/>
+</p>
+<hr>
+<h3>FAQ</h3>
+<br>
+<p>Q: <b>Where can I find the fingerprint for my server?</b></p>
+<p>A: <i>Often your node fingerprint can be found on unix-like machines in the file: <tt>/var/lib/tor/fingerprint</tt></i></p>
+<p>Q: <b>Will I be overloaded with alerts that I cannot suppress?</b></p>
+<p>A: <i>No.</i>
+<p>Q: <b>Can I unsubscribe easily?</b></p>
+<p>A: <i>Yes.</i>
+<p>Q: <b>I'm having a problem, can you help me?</b></p>
+<p>A: <i>Yes. Send an email to <tt>tor-weather @ torproject dot org</tt></i>
+<br>
+<hr>
+<br>
+<p><i>Please note that while we won't ever intentionally publish them, the address/node pairs sent to this server are not protected against SMTP eavesdropping, hacking, or lawyers.</i>
+</form>
+</div>
+</div>
+</body>
+</html>

Added: weather/branches/django/torweather/templates/relationships/modification.html
===================================================================
--- weather/branches/django/torweather/templates/relationships/modification.html	                        (rev 0)
+++ weather/branches/django/torweather/templates/relationships/modification.html	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+  <title>Tor Weather</title>
+  <link rel="stylesheet" type="text/css" href="http://weather.torproject.org/stylesheet.css";>
+</head>
+<body>
+<div class="center">
+<table class="banner" border="0" cellpadding="0" cellspacing="0" summary="">
+    <tr>
+
+        <td class="banner-left"><a href="https://www.torproject.org/";><img src="http://weather.torproject.org/top-left.png"; alt="Click to go to home page" width="193" height="79"></a></td>
+        <td class="banner-middle">
+        &nbsp;
+        </td>
+        <td class="banner-right">
+        </td>
+    </tr>
+</table>
+<div class="main-column">
+<h2>Tor Weather</h2>
+
+<hr>
+
+<h3>Sign Up!</h3>
+
+<br>
+<form method="post" action="/relationships/subscribe">
+You can use this form to request status updates to tell you when a particular
+Tor node has become unreachable for a sustained period of time.
+<br><br>
+
+<p>
+Email:<br>
+<input type="text" name="email" size="50" maxlength="255" value="Enter one email address" onclick="if (this.value == 'Enter one email address') {this.value = ''}" />
+</p><p>
+Node fingerprint:<br>
+<input type="text" name="node" size="50" maxlength="255" value="Enter one Tor node ID" onclick="if (this.value == 'Enter one Tor node ID') {this.value = ''}" />
+</p><p>
+Node comment:<br>
+<input type="text" name="node" size="50" maxlength="255" value="Enter a custom reminder about this Tor node ID" onclick="if (this.value == 'Enter a custom reminder about this Tor node ID') {this.value = ''}" />
+</p><p>
+<input type="submit" class="submit" value="Subscribe to Tor Weather" name="sa"/>
+</p>
+<hr>
+<h3>FAQ</h3>
+<br>
+<p>Q: <b>Where can I find the fingerprint for my server?</b></p>
+<p>A: <i>Often your node fingerprint can be found on unix-like machines in the file: <tt>/var/lib/tor/fingerprint</tt></i></p>
+<p>Q: <b>Will I be overloaded with alerts that I cannot suppress?</b></p>
+<p>A: <i>No.</i>
+<p>Q: <b>Can I unsubscribe easily?</b></p>
+<p>A: <i>Yes.</i>
+<p>Q: <b>I'm having a problem, can you help me?</b></p>
+<p>A: <i>Yes. Send an email to <tt>tor-weather @ torproject dot org</tt></i>
+<br>
+<hr>
+<br>
+<p><i>Please note that while we won't ever intentionally publish them, the address/node pairs sent to this server are not protected against SMTP eavesdropping, hacking, or lawyers.</i>
+</form>
+</div>
+</div>
+</body>
+</html>

Added: weather/branches/django/torweather/templates/relationships/pending.html
===================================================================
--- weather/branches/django/torweather/templates/relationships/pending.html	                        (rev 0)
+++ weather/branches/django/torweather/templates/relationships/pending.html	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+  <title>Tor Weather</title>
+  <link rel="stylesheet" type="text/css" href="http://weather.torproject.org/stylesheet.css";>
+</head>
+<body>
+<div class="center">
+<table class="banner" border="0" cellpadding="0" cellspacing="0" summary="">
+    <tr>
+
+        <td class="banner-left"><a href="https://www.torproject.org/";><img src="http://weather.torproject.org/top-left.png"; alt="Click to go to home page" width="193" height="79"></a></td>
+        <td class="banner-middle">
+        &nbsp;
+        </td>
+        <td class="banner-right">
+        </td>
+    </tr>
+</table>
+<div class="main-column">
+<h2>Subscription pending</h2>
+
+<hr>
+
+Thank you. You should receive a confirmation email shortly. Perhaps you'd like <a href="/relationships/manage_subscription">to add another node</a>?
+<br>
+</p>
+<hr>
+<p><i>Please note that while we won't ever intentionally publish them, the address/node pairs sent to this server are not protected against SMTP eavesdropping, hacking, or lawyers.</i></p>
+</form>
+</div>
+</div>
+</body>
+</html>

Added: weather/branches/django/torweather/templates/relationships/subscribe.html
===================================================================
--- weather/branches/django/torweather/templates/relationships/subscribe.html	                        (rev 0)
+++ weather/branches/django/torweather/templates/relationships/subscribe.html	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,73 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+  <title>Tor Weather</title>
+  <link rel="stylesheet" type="text/css" href="http://weather.torproject.org/stylesheet.css";>
+</head>
+<body>
+<div class="center">
+<table class="banner" border="0" cellpadding="0" cellspacing="0" summary="">
+    <tr>
+
+        <td class="banner-left"><a href="https://www.torproject.org/";><img src="http://weather.torproject.org/top-left.png"; alt="Click to go to home page" width="193" height="79"></a></td>
+        <td class="banner-middle">
+        &nbsp;
+        </td>
+        <td class="banner-right">
+        </td>
+    </tr>
+</table>
+<div class="main-column">
+<h2>Tor Weather</h2>
+
+<hr>
+
+<h3>Sign Up!</h3>
+
+<br>
+<form method="post" action="/relationships/subscribe">
+You can use this form to request status updates to tell you when a particular
+Tor node has become unreachable for a sustained period of time.
+<br><br>
+
+<p>
+Email:<br>
+<input type="text" name="email" size="50" maxlength="255" value="Enter one email address" onclick="if (this.value == 'Enter one email address') {this.value = ''}" />
+</p><p>
+Node fingerprint:<br>
+<input type="text" name="node" size="50" maxlength="255" value="Enter one Tor node ID" onclick="if (this.value == 'Enter one Tor node ID') {this.value = ''}" />
+</p><p>
+Node comment:<br>
+<input type="text" name="comment" size="50" maxlength="255" value="Enter a custom reminder about this Tor node ID" onclick="if (this.value == 'Enter a custom reminder about this Tor node ID') {this.value = ''}" />
+</p><p>
+Alerting delay preference:<br>
+<select name="delay">
+<option valu="0">No delay</option>
+<option valu="30">Thirty minutes</option>
+<option valu="60">Sixty minutes</option>
+<option valu="90">Ninety minutes</option>
+</select>
+</p><p>
+
+<input type="submit" class="submit" value="Subscribe to Tor Weather" name="sa"/>
+</p>
+<hr>
+<h3>FAQ</h3>
+<br>
+<p>Q: <b>Where can I find the fingerprint for my server?</b></p>
+<p>A: <i>Often your node fingerprint can be found on unix-like machines in the file: <tt>/var/lib/tor/fingerprint</tt></i></p>
+<p>Q: <b>Will I be overloaded with alerts that I cannot suppress?</b></p>
+<p>A: <i>No.</i>
+<p>Q: <b>Can I unsubscribe easily?</b></p>
+<p>A: <i>Yes.</i>
+<p>Q: <b>I'm having a problem, can you help me?</b></p>
+<p>A: <i>Yes. Send an email to <tt>tor-weather @ torproject dot org</tt></i>
+<br>
+<hr>
+<br>
+<p><i>Please note that while we won't ever intentionally publish them, the address/node pairs sent to this server are not protected against SMTP eavesdropping, hacking, or lawyers.</i>
+</form>
+</div>
+</div>
+</body>
+</html>

Added: weather/branches/django/torweather/templates/relationships/subscription-thanks.html
===================================================================
--- weather/branches/django/torweather/templates/relationships/subscription-thanks.html	                        (rev 0)
+++ weather/branches/django/torweather/templates/relationships/subscription-thanks.html	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+  <title>Tor Weather</title>
+  <link rel="stylesheet" type="text/css" href="http://weather.torproject.org/stylesheet.css";>
+</head>
+<body>
+<div class="center">
+<table class="banner" border="0" cellpadding="0" cellspacing="0" summary="">
+    <tr>
+
+        <td class="banner-left"><a href="https://www.torproject.org/";><img src="http://weather.torproject.org/top-left.png"; alt="Click to go to home page" width="193" height="79"></a></td>
+        <td class="banner-middle">
+        &nbsp;
+        </td>
+        <td class="banner-right">
+        </td>
+    </tr>
+</table>
+<div class="main-column">
+<h2>Thanks for signing Up!</h2>
+
+<hr>
+
+You should recieve an email shortly.
+<br>
+</p>
+<hr>
+<p><i>Please note that while we won't ever intentionally publish them, the address/node pairs sent to this server are not protected against SMTP eavesdropping, hacking, or lawyers.</i></p>
+</form>
+</div>
+</div>
+</body>
+</html>

Added: weather/branches/django/torweather/templates/relationships/unsubscribe.html
===================================================================
--- weather/branches/django/torweather/templates/relationships/unsubscribe.html	                        (rev 0)
+++ weather/branches/django/torweather/templates/relationships/unsubscribe.html	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+  <title>Tor Weather</title>
+  <link rel="stylesheet" type="text/css" href="http://weather.torproject.org/stylesheet.css";>
+</head>
+<body>
+<div class="center">
+<table class="banner" border="0" cellpadding="0" cellspacing="0" summary="">
+    <tr>
+
+        <td class="banner-left"><a href="https://www.torproject.org/";><img src="http://weather.torproject.org/top-left.png"; alt="Click to go to home page" width="193" height="79"></a></td>
+        <td class="banner-middle">
+        &nbsp;
+        </td>
+        <td class="banner-right">
+        </td>
+    </tr>
+</table>
+<div class="main-column">
+<h2>Unsubscription confirmed</h2>
+
+<hr>
+
+We've unsubscribed you. If you change your mind, feel free to come back!
+<br>
+</p>
+<hr>
+<p><i>Please note that while we won't ever intentionally publish them, the address/node pairs sent to this server are not protected against SMTP eavesdropping, hacking, or lawyers.</i></p>
+</form>
+</div>
+</div>
+</body>
+</html>

Added: weather/branches/django/torweather/urls.py
===================================================================
--- weather/branches/django/torweather/urls.py	                        (rev 0)
+++ weather/branches/django/torweather/urls.py	2009-05-01 05:56:47 UTC (rev 19405)
@@ -0,0 +1,19 @@
+from django.conf.urls.defaults import *
+
+# Uncomment the next two lines to enable the admin:
+from django.contrib import admin
+admin.autodiscover()
+
+urlpatterns = patterns('',
+    # Example:
+    # (r'^torweather/', include('torweather.foo.urls')),
+    #(r'^polls/', include('torweather.polls.urls')),
+    (r'^relationships/', include('torweather.relationships.urls')),
+
+    # Uncomment the admin/doc line below and add 'django.contrib.admindocs' 
+    # to INSTALLED_APPS to enable admin documentation:
+    #(r'^admin/doc/', include('django.contrib.admindocs.urls')),
+
+    # Uncomment the next line to enable the admin:
+    (r'^admin/(.*)', admin.site.root)
+    )