[snowy] Refactor to use Site instead of DOMAIN_NAME and PROJECT_NAME



commit 3cf68ad9a42648def28a2dd7331a8ef94842da68
Author: Brad Taylor <brad getcoded net>
Date:   Fri Jul 24 11:50:20 2009 -0400

    Refactor to use Site instead of DOMAIN_NAME and PROJECT_NAME
    
    This includes a new template tag ({% full_url %}) and a python method for
    resolving full urls (reverse_full).

 INSTALL                                            |    7 ++-
 accounts/templates/registration/activate.html      |    8 ++--
 .../templates/registration/activation_email.txt    |    4 +-
 .../registration/registration_complete.html        |    4 +-
 api/handlers.py                                    |   21 ++++-----
 api/urls.py                                        |    2 +-
 {notes => core}/context_processors.py              |    6 ++-
 core/templatetags/urlresolvers.py                  |   47 ++++++++++++++++++++
 .../context_processors.py => core/urlresolvers.py  |   11 ++++-
 local_settings.py.in                               |    2 -
 notes/templatetags/notes.py                        |    4 +-
 notes/views.py                                     |    2 +-
 settings.py                                        |    5 +-
 templates/base.html                                |    2 +-
 templates/index.html                               |   17 ++++---
 urls.py                                            |    9 +++-
 16 files changed, 106 insertions(+), 45 deletions(-)
---
diff --git a/INSTALL b/INSTALL
index 2a93fe7..c9cab51 100644
--- a/INSTALL
+++ b/INSTALL
@@ -9,8 +9,6 @@ Running Snowy From Your Git Checkout
 
 2. Set up your local settings file (in your snowy git checkout):
 	cp local_settings.py.in local_settings.py
-	(Make sure to set DOMAIN_NAME appropriately in this file. It should come
-	from http://DOMAIN_NAME/myusername/notes , and defaults to 'localhost:8000'.)
 
 3. Setup snowy database (in your snowy git checkout):
 	python manage.py syncdb
@@ -21,6 +19,11 @@ Running Snowy From Your Git Checkout
 5. Admin your snowy:
 	http://localhost:8000/admin
 
+	- In the Sites table, make sure to set the domain and name properly, e.g.:
+
+		Domain name:  localhost:8000
+		Display name: Snowy
+
 6. Play with snowy:
 	http://localhost:8000/myusername/notes (for example)
 
diff --git a/accounts/templates/registration/activate.html b/accounts/templates/registration/activate.html
index 72859b2..80a7cc2 100644
--- a/accounts/templates/registration/activate.html
+++ b/accounts/templates/registration/activate.html
@@ -7,11 +7,11 @@
 {% block content %}
 {% if account %}
 {% url auth_login as login_url %}
-{% blocktrans with PROJECT_NAME as p and login_url as u %}
-<h1>Welcome to {{ p }}!</h1>
+{% blocktrans with site.name as n and login_url as u %}
+<h1>Welcome to {{ n }}!</h1>
 <p>Your registration is now complete.  You may now <a href="{{ u }}">log in</a>.</p>
-<p>To get more use out of your {{ p }} account, you can configure Tomboy to
-synchronize notes between {{ p }} and your computer.
+<p>To get more use out of your {{ n }} account, you can configure Tomboy to
+synchronize notes between {{ n }} and your computer.
 <a href="">Find out how</a>.</p>
 {% endblocktrans %}
 {% else %}
diff --git a/accounts/templates/registration/activation_email.txt b/accounts/templates/registration/activation_email.txt
index 5d22ac9..cefbaff 100644
--- a/accounts/templates/registration/activation_email.txt
+++ b/accounts/templates/registration/activation_email.txt
@@ -1,4 +1,4 @@
-{% load i18n %}
+{% load i18n %}{% load urlresolvers %}
 {% blocktrans with site.name as n %}Hello from {{ n }}!{% endblocktrans %}
 
 {% blocktrans %}In order to use your new account, you need to confirm that your email address
@@ -7,7 +7,7 @@ announcements of cool new features.{% endblocktrans %}
 
 {% trans "To confirm your email address, go to:" %}
 
-http://{{ site.domain }}{% url registration_activate activation_key %}
+{% full_url registration_activate activation_key %}
 
 {% blocktrans count expiration_days as days %}If you don't, or think you've recieved this email by mistake, the temporary
 account we created for you will be automatically deleted in {{ expiration_days }} day.
diff --git a/accounts/templates/registration/registration_complete.html b/accounts/templates/registration/registration_complete.html
index b7d6377..6cee298 100644
--- a/accounts/templates/registration/registration_complete.html
+++ b/accounts/templates/registration/registration_complete.html
@@ -3,10 +3,10 @@
 {% load i18n %}
 
 {% block content %}
-{% blocktrans with PROJECT_NAME as p %}
+{% blocktrans with site.name as n %}
 <h1>Your account is pending activation</h1>
 <p>An activation link has been sent to the email address you provided, along
 with instructions for activating your account.  Your account must be activated
-before you can use {{ p }}.</p>
+before you can use {{ n }}.</p>
 {% endblocktrans %}
 {% endblock %}
diff --git a/api/handlers.py b/api/handlers.py
index 9e2fd6c..c92387f 100644
--- a/api/handlers.py
+++ b/api/handlers.py
@@ -16,7 +16,6 @@
 #
 
 from django.core.exceptions import ObjectDoesNotExist
-from django.core.urlresolvers import reverse
 from django.contrib.auth.models import User
 from django.db import transaction
 from django.db.models import Max
@@ -27,6 +26,7 @@ from piston.utils import rc, HttpStatusCode
 from datetime import datetime
 from dateutil import parser
 
+from snowy.core.urlresolvers import reverse_full
 from snowy.notes.models import Note
 from snowy.notes.models import NoteTag
 from snowy import settings
@@ -57,10 +57,11 @@ class RootHandler(BaseHandler):
     allow_methods = ('GET')
 
     def read(self, request):
+        kwargs = {'username': request.user.username}
         return {
             'user-ref': {
-                'api-ref' : 'http://%s%s' % (settings.DOMAIN_NAME, '/api/1.0/' + request.user.username),
-                'href' : 'http://%s%s' % (settings.DOMAIN_NAME, '/' + request.user.username)
+                'api-ref' : reverse_full('user_api_index', kwargs=kwargs),
+                'href' : reverse_full('user_index', kwargs=kwargs),
             },
             'api-version': '1.0'
         }
@@ -73,14 +74,14 @@ class UserHandler(AnonymousBaseHandler):
     def read(self, request, username):
         user = User.objects.get(username=username)
         profile = user.get_profile()
-        reverse_args = {'username': username}
+        kwargs = {'username': username}
         return {
             'user-name': user.username,
             'first-name': user.first_name,
             'last-name': user.last_name,
             'notes-ref': {
-                'api-ref': 'http://%s%s' % (settings.DOMAIN_NAME, reverse('note_api_index', kwargs=reverse_args)),
-                'href': 'http://%s%s' % (settings.DOMAIN_NAME, reverse('note_index', kwargs=reverse_args)),
+                'api-ref': reverse_full('note_api_index', kwargs=kwargs),
+                'href': reverse_full('note_index', kwargs=kwargs),
             },
             'latest-sync-revision' : profile.latest_sync_rev,
             'current-sync-guid' : profile.current_sync_uuid
@@ -202,14 +203,12 @@ def describe_note(note):
     }
 
 def simple_describe_note(note):
+    kwargs = {'username': note.author.username, 'note_id': note.pk}
     return {
         'guid': note.guid,
         'ref': {
-            'api-ref': 'http://%s%s' % (settings.DOMAIN_NAME, reverse('note_api_detail', kwargs={
-                'username': note.author.username,
-                'note_id': note.pk,
-            })),
-            'href': 'http://%s%s' % (settings.DOMAIN_NAME, note.get_absolute_url()),
+            'api-ref': reverse_full('note_api_detail', kwargs=kwargs),
+            'href': reverse_full('note_detail_no_slug', kwargs=kwargs),
         },
         'title': note.title
     }
diff --git a/api/urls.py b/api/urls.py
index 40c9cf7..524beb8 100644
--- a/api/urls.py
+++ b/api/urls.py
@@ -35,6 +35,6 @@ urlpatterns = patterns('',
     # 1.0 API methods
     url(r'1.0/(?P<username>\w+)/notes/(?P<note_id>\d+)/$', note_handler, name='note_api_detail'),
     url(r'1.0/(?P<username>\w+)/notes/$', notes_handler, name='note_api_index'),
-    url(r'1.0/(?P<username>\w+)/$', user_handler),
+    url(r'1.0/(?P<username>\w+)/$', user_handler, name='user_api_index'),
     url(r'1.0/$', root_handler),
 )
diff --git a/core/__init__.py b/core/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/notes/context_processors.py b/core/context_processors.py
similarity index 84%
copy from notes/context_processors.py
copy to core/context_processors.py
index ab73ddf..2deec89 100644
--- a/notes/context_processors.py
+++ b/core/context_processors.py
@@ -15,7 +15,9 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
+from django.contrib.sites.models import Site
 from django.conf import settings
 
-def project_name(context):
-    return { 'PROJECT_NAME': settings.PROJECT_NAME }
+def current_site(context):
+    site = Site.objects.get_current()
+    return { 'site': site }
diff --git a/core/templatetags/__init__.py b/core/templatetags/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/core/templatetags/urlresolvers.py b/core/templatetags/urlresolvers.py
new file mode 100644
index 0000000..aa77c43
--- /dev/null
+++ b/core/templatetags/urlresolvers.py
@@ -0,0 +1,47 @@
+#
+# Copyright (c) 2009 Brad Taylor <brad getcoded net>
+#
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+from snowy.core.urlresolvers import reverse_full
+
+from django import template
+
+register = template.Library()
+
+ register tag
+def full_url(parser, tokens):
+    """ Usage:
+        {% full_url view <same args as for url> %}
+    """
+    tokens = tokens.split_contents()
+    if len(tokens) < 3:
+        raise template.TemplateSyntaxError, \
+            "%r tag requires at least two arguments" % tokens[0]
+
+    args = []
+    for arg in tokens[2:]:
+        args.append(parser.compile_filter(arg))
+
+    return FullUrlNode(tokens[1], args)
+
+class FullUrlNode(template.Node):
+    def __init__(self, view, args):
+        self.view = view
+        self.args = args
+
+    def render(self, context):
+        args = [arg.resolve(context) for arg in self.args]
+        return reverse_full(self.view, args=args)
diff --git a/notes/context_processors.py b/core/urlresolvers.py
similarity index 68%
rename from notes/context_processors.py
rename to core/urlresolvers.py
index ab73ddf..42b7b7f 100644
--- a/notes/context_processors.py
+++ b/core/urlresolvers.py
@@ -15,7 +15,14 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
+from django.contrib.sites.models import Site
+from django.core.urlresolvers import reverse
 from django.conf import settings
+from urlparse import urlunparse
 
-def project_name(context):
-    return { 'PROJECT_NAME': settings.PROJECT_NAME }
+def reverse_full(name, args=(), kwargs={}):
+    site = Site.objects.get_current()
+    return urlunparse([
+        settings.URI_SCHEME, site.domain, 
+        reverse(name, args=args, kwargs=kwargs), '', '', ''
+    ])
diff --git a/local_settings.py.in b/local_settings.py.in
index 4329833..b7cb5ad 100644
--- a/local_settings.py.in
+++ b/local_settings.py.in
@@ -6,8 +6,6 @@ TEMPLATE_DEBUG = DEBUG
 DATABASE_ENGINE = 'sqlite3'    # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
 DATABASE_NAME = 'snowy.db'  # Or path to database file if using sqlite3.
 
-DOMAIN_NAME = 'localhost:8000'
-
 # Fill in this information from
 # http://recaptcha.net/api/getkey?app=snowy
 RECAPTCHA_ENABLED = False
diff --git a/notes/templatetags/notes.py b/notes/templatetags/notes.py
index 6734e56..d26db38 100644
--- a/notes/templatetags/notes.py
+++ b/notes/templatetags/notes.py
@@ -45,7 +45,7 @@ class UserNotesListNode(template.Node):
 
     def render(self, context):
         request = self.request.resolve(context)
-	author = self.author.resolve(context)
+        author = self.author.resolve(context)
 
         # XXX: Replace this with a NotesManager
         all_notes = Note.objects.filter(author=author) \
@@ -80,7 +80,7 @@ class UserNotebookListNode(template.Node):
 
     def render(self, context):
         request = self.request.resolve(context)
-	author = self.author.resolve(context)
+        author = self.author.resolve(context)
 
         context[self.dest] = NoteTag.objects.filter(author=author,
 	                                            is_notebook=True)[:5]
diff --git a/notes/views.py b/notes/views.py
index 3a85c90..f5b10aa 100644
--- a/notes/views.py
+++ b/notes/views.py
@@ -52,7 +52,7 @@ def note_detail(request, username, note_id, slug='',
         doc = minidom.parseString(xml)
 
         for link in doc.getElementsByTagName('link:internal'):
-            if not link.hasChildNodes: continue
+            if len(link.childNodes) < 1: continue
 
             title = link.childNodes[0].nodeValue
             try:
diff --git a/settings.py b/settings.py
index da2295e..8b0ea42 100644
--- a/settings.py
+++ b/settings.py
@@ -23,7 +23,7 @@ RECAPTCHA_ENABLED = False
 RECAPTCHA_PUBLIC_KEY = ''
 RECAPTCHA_PRIVATE_KEY = ''
 
-PROJECT_NAME = 'Snowy'
+URI_SCHEME = 'http'
 
 # Local time zone for this installation. Choices can be found here:
 # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
@@ -77,7 +77,7 @@ TEMPLATE_CONTEXT_PROCESSORS = (
     'django.core.context_processors.debug',
     'django.core.context_processors.i18n',
     'django.core.context_processors.media',
-    'snowy.notes.context_processors.project_name',
+    'snowy.core.context_processors.current_site',
 )
 
 MIDDLEWARE_CLASSES = (
@@ -110,6 +110,7 @@ sys.path.append(EXTERNAL_APPS_PATH)
 
 INSTALLED_APPS = (
     # Local apps
+    'core',
     'api',
     'accounts',
     'notes',
diff --git a/templates/base.html b/templates/base.html
index 1ee011d..8e2dfe7 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -5,7 +5,7 @@
 
 <head>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-    <title>{% block title %}{{ PROJECT_NAME }}{% endblock %}</title>
+    <title>{% block title %}{{ site.name }}{% endblock %}</title>
     <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/screen.css" media="screen">
     <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/print.css" media="print">
 {% if DEBUG %}
diff --git a/templates/index.html b/templates/index.html
index 52722b4..7a08792 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -1,23 +1,24 @@
 {% extends "base.html" %}
 
 {% load i18n %}
+{% load urlresolvers %}
 
 {% block content %}
-{% blocktrans %}
-<h1>Welcome to {{ PROJECT_NAME }}!</h1>
-<p>{{ PROJECT_NAME }} is Tomboy's best friend on the web.  {{ PROJECT_NAME }}
-is an online service that allows you to view, edit and share the notes you
-create in Tomboy on your desktop computer.  Powered by <a
+{% blocktrans with site.name as n %}
+<h1>Welcome to {{ n }}!</h1>
+<p>{{ n }} is Tomboy's best friend on the web.  {{ n }} is an online service
+that allows you to view, edit and share the notes you create in Tomboy on your
+desktop computer.  Powered by <a
 href="http://www.djangoproject.com";>Django</a>, it features a REST-based API
 for synchronizing notes, an intuitive editor and moxie; lots of moxie.</p>
 
-<p>Thank you for your interest in {{ PROJECT_NAME }}.  {{ PROJECT_NAME }} is
+<p>Thank you for your interest in {{ n }}.  {{ n }} is
 currently under heavy development and is <strike>not
 ready</strike><b>REALLY</b> not ready for production use.  Like any good K9
-companion, {{ PROJECT_NAME }} will file your taxes improperly, reconcile with
+companion, {{ n }} will file your taxes improperly, reconcile with
 your ex-girlfriends and burn risotto if not watched carefully.</p>
 
-<p>If you want to house-train {{ PROJECT_NAME }} and teach him some new tricks,
+<p>If you want to house-train {{ n }} and teach him some new tricks,
 check out the TODO and start contributing.  P.S., Have I told you how much you
 rock?</p>
 {% endblocktrans %}
diff --git a/urls.py b/urls.py
index f5dea31..1898a48 100644
--- a/urls.py
+++ b/urls.py
@@ -15,14 +15,15 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
-from django.views.generic.simple import direct_to_template
+from django.views.generic.simple import direct_to_template, redirect_to
+from django.core.urlresolvers import reverse
 from django.conf.urls.defaults import *
 
 from django.contrib import admin
 admin.autodiscover()
 
 urlpatterns = patterns('',
-    url(r'^$', 'django.views.generic.simple.direct_to_template', {'template': 'index.html'},
+    url(r'^$', direct_to_template, {'template': 'index.html'},
         name='snowy_index'),
 
     (r'^api/', include('snowy.api.urls')),
@@ -31,6 +32,9 @@ urlpatterns = patterns('',
     (r'^admin/doc/', include('django.contrib.admindocs.urls')),
     (r'^admin/', include(admin.site.urls)),
 
+    url(r'^(?P<username>\w+)/$', redirect_to,
+        {'url': None, 'permanent': False}, name='user_index'),
+
     (r'^(?P<username>\w+)/notes/', include('snowy.notes.urls')),
 )
 
@@ -49,4 +53,3 @@ urlpatterns += patterns('piston.authentication',
     url(r'^oauth/authenticate/$', 'oauth_user_auth'),
     url(r'^oauth/access_token/$', 'oauth_access_token'),
 )
-



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