First iteration of a "prototype" Melange app, along with an initial Person
Profile view.
Patch by: Augie Fackler (with some additions by Todd Larsen)
Review by: Todd Larsen
Review issue: 46
Review URL: http://codereviews.googleopensourceprograms.com/46
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/proto/app.yaml Wed May 21 16:27:35 2008 +0000
@@ -0,0 +1,27 @@
+# Copyright 2008 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# TODO(proto): uncomment and supply a Google App Engine application instance
+# application: FIXME
+version: 1
+runtime: python
+api_version: 1
+
+handlers:
+- url: /content
+ static_dir: content
+
+- url: /.*
+ script: main.py
+
Binary file apps/proto/content/logo.jpg has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/proto/content/proto.css Wed May 21 16:27:35 2008 +0000
@@ -0,0 +1,20 @@
+/*
+Copyright 2008 the Melange authors.
+
+Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ */
+
+body {
+ font-family: Verdana, Helvetica, sans-serif;
+ background-color: #DDDDDD;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/proto/main.py Wed May 21 16:27:35 2008 +0000
@@ -0,0 +1,73 @@
+#!/usr/bin/python2.5
+#
+# Copyright 2008 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+__authors__ = [
+ # alphabetical order by last name, please
+ '"Augie Fackler" <durin42@gmail.com>',
+ ]
+
+
+import logging
+import os
+import sys
+
+from google.appengine.ext.webapp import util
+
+
+# Remove the standard version of Django.
+for k in [k for k in sys.modules if k.startswith('django')]:
+ del sys.modules[k]
+
+# Force sys.path to have our own directory first, in case we want to import
+# from it. This lets us replace the built-in Django
+sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))
+
+# Force Django to reload its settings.
+from django.conf import settings
+settings._target = None
+
+# Must set this env var before importing any part of Django
+os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
+
+import django.core.handlers.wsgi
+import django.core.signals
+import django.db
+import django.dispatch.dispatcher
+
+
+# Log errors.
+def log_exception(*args, **kwds):
+ logging.exception('Exception in request:')
+
+django.dispatch.dispatcher.connect(
+ log_exception, django.core.signals.got_request_exception)
+
+# Unregister the rollback event handler.
+django.dispatch.dispatcher.disconnect(
+ django.db._rollback_on_exception,
+ django.core.signals.got_request_exception)
+
+
+def main():
+ # Create a Django application for WSGI.
+ application = django.core.handlers.wsgi.WSGIHandler()
+
+ # Run the WSGI CGI handler with that application.
+ util.run_wsgi_app(application)
+
+
+if __name__ == '__main__':
+ main()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/proto/settings.py Wed May 21 16:27:35 2008 +0000
@@ -0,0 +1,105 @@
+# Copyright 2008 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+__authors__ = [
+ '"Augie Fackler" <durin42@gmail.com>',
+ ]
+
+
+import os
+
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+ # ('Your Name', 'your_email@domain.com'),
+)
+
+MANAGERS = ADMINS
+
+# 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+DATABASE_ENGINE = 'dummy'
+# None of the following are used with appengine
+DATABASE_NAME = '' # Or path to database file if using sqlite3.
+DATABASE_USER = '' # Not used with sqlite3.
+DATABASE_PASSWORD = '' # Not used with sqlite3.
+# Set to empty string for localhost. Not used with sqlite3.
+DATABASE_HOST = ''
+# Set to empty string for default. Not used with sqlite3.
+DATABASE_PORT = ''
+
+# 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 = 'UTC'
+
+# 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/'
+
+# TODO Make this unique, and don't share it with anybody.
+SECRET_KEY = 'hvhxfm5u=^*v&doo#oq8x*eg8+1&9sxbye@=umutgn^t_sg_nx'
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+ 'django.template.loaders.filesystem.load_template_source',
+ 'django.template.loaders.app_directories.load_template_source',
+# 'django.template.loaders.eggs.load_template_source',
+)
+
+MIDDLEWARE_CLASSES = (
+# 'django.middleware.common.CommonMiddleware',
+# 'django.contrib.sessions.middleware.SessionMiddleware',
+# 'django.contrib.auth.middleware.AuthenticationMiddleware',
+# 'django.middleware.doc.XViewMiddleware',
+)
+
+ROOT_URLCONF = 'urls'
+
+ROOT_PATH = os.path.dirname(__file__)
+TEMPLATE_DIRS = (
+ # TODO(proto): customize the template search directories
+ os.path.join(ROOT_PATH, 'proto', 'templates'),
+ os.path.join(ROOT_PATH, 'soc', 'templates'),
+)
+
+INSTALLED_APPS = (
+# 'django.contrib.auth',
+# 'django.contrib.contenttypes',
+# 'django.contrib.sessions',
+# 'django.contrib.sites',
+)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/proto/urls.py Wed May 21 16:27:35 2008 +0000
@@ -0,0 +1,27 @@
+# Copyright 2008 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+__authors__ = [
+ '"Augie Fackler" <durin42@gmail.com>',
+ ]
+
+
+from django.conf.urls.defaults import *
+
+
+urlpatterns = patterns(
+ '',
+ (r'^person/profile/$', 'soc.views.person.profile',
+ {'template': 'proto/profile.html'}),
+)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/soc/templates/soc/profile.html Wed May 21 16:27:35 2008 +0000
@@ -0,0 +1,30 @@
+{% comment %}
+Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+{% endcomment %}
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<html lang="en">
+ <head>
+ <title>Profile</title>
+ {% block 'stylesheet' %}{% endblock %}
+ </head>
+ <body>
+ <p>
+ {% block 'logo' %}{% endblock %}
+ Welcome, {{user.nickname}}. Please update your profile:
+ <form method="POST">
+ <table>{{form.as_table}}</table>
+ <input type="submit" />
+ </form>
+ </p>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/soc/views/person.py Wed May 21 16:27:35 2008 +0000
@@ -0,0 +1,65 @@
+#!/usr/bin/python2.5
+#
+# Copyright 2008 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Views relevant to the Person role.
+"""
+
+__authors__ = [
+ '"Augie Fackler" <durin42@gmail.com>',
+ ]
+
+
+from google.appengine.api import users
+from google.appengine.ext.db import djangoforms
+from django import http
+from django import shortcuts
+from django import newforms as forms
+
+from soc.models import person
+
+
+class ProfileForm(djangoforms.ModelForm):
+ class Meta:
+ """Inner Meta class that defines some behavior for the form.
+
+ """
+ #: the db.Model subclass for which the form will gather information.
+ model = person.Person
+ #: the list of model fields which will *not* be gathered by the form.
+ exclude = ['user', ]
+
+
+def profile(request, template='soc/profile.html'):
+ """View for a Person to modify the properties of a PersonModel.
+
+ Args:
+ request: the standard django request object.
+ template: the template path to use for rendering the template.
+
+ Returns:
+ A subclass of django.http.HttpResponse which either contains the form to
+ be filled out, or a redirect to the correct view in the interface.
+ """
+ user = users.get_current_user()
+ if not user:
+ return http.HttpResponseRedirect(users.create_login_url(request.path))
+ form = ProfileForm()
+ if request.method=='POST':
+ form = ProfileForm(request.POST)
+ if not form.errors:
+ return http.HttpResponse('This would update the model')
+ return shortcuts.render_to_response(
+ template, dictionary={'template': template, 'form': form, 'user': user})