# HG changeset patch # User mgood # Date 1154113075 0 # Node ID 64ff134868c4dbd95fedb307ca56a56c9c128288 # Parent 230ee6a2c6b2b0fbe926cc2db73e522f089d2864 update the example TurboGears app and include an example of using TurboGears wigets diff --git a/examples/turbogears/README.txt b/examples/turbogears/README.txt --- a/examples/turbogears/README.txt +++ b/examples/turbogears/README.txt @@ -1,4 +1,4 @@ MarkupTest This is a TurboGears (http://www.turbogears.org) project. It can be -started by running the start-markuptest.py script. \ No newline at end of file +started by running the start-markuptest.py script. diff --git a/examples/turbogears/dev.cfg b/examples/turbogears/dev.cfg --- a/examples/turbogears/dev.cfg +++ b/examples/turbogears/dev.cfg @@ -24,7 +24,6 @@ # for Windows users, sqlite URIs look like: # sqlobject.dburi="sqlite:///drive_letter:/path/to/file" - # SERVER # Some server parameters that you may want to tweak diff --git a/examples/turbogears/markuptest/config/app.cfg b/examples/turbogears/markuptest/config/app.cfg --- a/examples/turbogears/markuptest/config/app.cfg +++ b/examples/turbogears/markuptest/config/app.cfg @@ -10,10 +10,7 @@ # which view (template engine) to use if one is not specified in the # template name -# tg.defaultview = "kid" tg.defaultview = "markup" -markup.search_path = ["%(current_dir_uri)s"] -markup.outputformat = "xml" # The following kid settings determine the settings used by the kid serializer. @@ -29,12 +26,92 @@ # Allow every exposed function to be called as json, # tg.allow_json = False -# Set to True if you'd like all of your pages to include MochiKit -# tg.mochikit_all = False +# List of Widgets to include on every page. +# for exemple ['turbogears.mochikit'] +# tg.include_widgets = [] # Set to True if the scheduler should be started # tg.scheduler = False +# VISIT TRACKING +# Each visit to your application will be assigned a unique visit ID tracked via +# a cookie sent to the visitor's browser. +# -------------- + +# Enable Visit tracking +visit.on=True + +# Number of minutes a visit may be idle before it expires. +# visit.timeout=20 + +# The name of the cookie to transmit to the visitor's browser. +# visit.cookie.name="tg-visit" + +# Domain name to specify when setting the cookie (must begin with . according to +# RFC 2109). The default (None) should work for most cases and will default to +# the machine to which the request was made. NOTE: localhost is NEVER a valid +# value and will NOT WORK. +# visit.cookie.domain=None + +# Specific path for the cookie +# visit.cookie.path="/" + +# The name of the VisitManager plugin to use for visitor tracking. +visit.manager="sqlobject" + +# Database class to use for visit tracking +visit.soprovider.model = "markuptest.model.Visit" + +# IDENTITY +# General configuration of the TurboGears Identity management module +# -------- + +# Switch to turn on or off the Identity management module +identity.on=True + +# [REQUIRED] URL to which CherryPy will internally redirect when an access +# control check fails. If Identity management is turned on, a value for this +# option must be specified. +identity.failure_url="/login" + +# identity.provider='sqlobject' + +# The names of the fields on the login form containing the visitor's user ID +# and password. In addition, the submit button is specified simply so its +# existence may be stripped out prior to passing the form data to the target +# controller. +# identity.form.user_name="user_name" +# identity.form.password="password" +# identity.form.submit="login" + +# What sources should the identity provider consider when determining the +# identity associated with a request? Comma separated list of identity sources. +# Valid sources: form, visit, http_auth +# identity.source="form,http_auth,visit" + +# SqlObjectIdentityProvider +# Configuration options for the default IdentityProvider +# ------------------------- + +# The classes you wish to use for your Identity model. Remember to not use reserved +# SQL keywords for class names (at least unless you specify a different table +# name using sqlmeta). +identity.soprovider.model.user="markuptest.model.User" +identity.soprovider.model.group="markuptest.model.Group" +identity.soprovider.model.permission="markuptest.model.Permission" + +# The password encryption algorithm used when comparing passwords against what's +# stored in the database. Valid values are 'md5' or 'sha1'. If you do not +# specify an encryption algorithm, passwords are expected to be clear text. +# +# The SqlObjectProvider *will* encrypt passwords supplied as part of your login +# form. If you set the password through the password property, like: +# my_user.password = 'secret' +# the password will be encrypted in the database, provided identity is up and +# running, or you have loaded the configuration specifying what encryption to +# use (in situations where identity may not yet be running, like tests). + +# identity.soprovider.encryption_algorithm=None [/static] static_filter.on = True static_filter.dir = "%(top_level_dir)s/static" diff --git a/examples/turbogears/markuptest/controllers.py b/examples/turbogears/markuptest/controllers.py --- a/examples/turbogears/markuptest/controllers.py +++ b/examples/turbogears/markuptest/controllers.py @@ -3,7 +3,8 @@ import cherrypy import turbogears -from turbogears import controllers, expose, validate, redirect +from turbogears import controllers, expose, validate, redirect, widgets +from turbogears import identity from markuptest import json @@ -14,4 +15,40 @@ def index(self): import time log.debug("Happy TurboGears Controller Responding For Duty") - return dict(now=time.ctime()) + return dict(now=time.ctime(), + widget=widgets.TextArea(name="widget_test", + default="This is a test of using " + "TurboGears widgets with " + "Markup", + rows=5, cols=40)) + + + @expose(template="markuptest.templates.login") + def login(self, forward_url=None, previous_url=None, *args, **kw): + + if not identity.current.anonymous \ + and identity.was_login_attempted() \ + and not identity.get_identity_errors(): + raise redirect(forward_url) + + forward_url=None + previous_url= cherrypy.request.path + + if identity.was_login_attempted(): + msg=_("The credentials you supplied were not correct or " + "did not grant access to this resource.") + elif identity.get_identity_errors(): + msg=_("You must provide your credentials before accessing " + "this resource.") + else: + msg=_("Please log in.") + forward_url= cherrypy.request.headers.get("Referer", "/") + cherrypy.response.status=403 + return dict(message=msg, previous_url=previous_url, logging_in=True, + original_parameters=cherrypy.request.params, + forward_url=forward_url) + + @expose() + def logout(self): + identity.current.logout() + raise redirect("/") diff --git a/examples/turbogears/markuptest/model.py b/examples/turbogears/markuptest/model.py --- a/examples/turbogears/markuptest/model.py +++ b/examples/turbogears/markuptest/model.py @@ -1,1 +1,109 @@ +from datetime import datetime +from sqlobject import * + +from turbogears import identity +from turbogears.database import PackageHub + +hub = PackageHub("markuptest") +__connection__ = hub + +# class YourDataClass(SQLObject): +# pass + +class Visit(SQLObject): + class sqlmeta: + table="visit" + + visit_key= StringCol( length=40, alternateID=True, + alternateMethodName="by_visit_key" ) + created= DateTimeCol( default=datetime.now ) + expiry= DateTimeCol() + + def lookup_visit( cls, visit_key ): + try: + return cls.by_visit_key( visit_key ) + except SQLObjectNotFound: + return None + lookup_visit= classmethod(lookup_visit) + +class VisitIdentity(SQLObject): + visit_key = StringCol(length=40, alternateID=True, + alternateMethodName="by_visit_key") + user_id = IntCol() + + +class Group(SQLObject): + """ + An ultra-simple group definition. + """ + + # names like "Group", "Order" and "User" are reserved words in SQL + # so we set the name to something safe for SQL + class sqlmeta: + table="tg_group" + + group_name = UnicodeCol(length=16, alternateID=True, + alternateMethodName="by_group_name") + display_name = UnicodeCol(length=255) + created = DateTimeCol(default=datetime.now) + + # collection of all users belonging to this group + users = RelatedJoin("User", intermediateTable="user_group", + joinColumn="group_id", otherColumn="user_id") + + # collection of all permissions for this group + permissions = RelatedJoin("Permission", joinColumn="group_id", + intermediateTable="group_permission", + otherColumn="permission_id") + + +class User(SQLObject): + """ + Reasonably basic User definition. Probably would want additional attributes. + """ + # names like "Group", "Order" and "User" are reserved words in SQL + # so we set the name to something safe for SQL + class sqlmeta: + table="tg_user" + + user_name = UnicodeCol(length=16, alternateID=True, + alternateMethodName="by_user_name") + email_address = UnicodeCol(length=255, alternateID=True, + alternateMethodName="by_email_address") + display_name = UnicodeCol(length=255) + password = UnicodeCol(length=40) + created = DateTimeCol(default=datetime.now) + + # groups this user belongs to + groups = RelatedJoin("Group", intermediateTable="user_group", + joinColumn="user_id", otherColumn="group_id") + + def _get_permissions(self): + perms = set() + for g in self.groups: + perms = perms | set(g.permissions) + return perms + + def _set_password(self, cleartext_password): + "Runs cleartext_password through the hash algorithm before saving." + hash = identity.encrypt_password(cleartext_password) + self._SO_set_password(hash) + + def set_password_raw(self, password): + "Saves the password as-is to the database." + self._SO_set_password(password) + + + +class Permission(SQLObject): + permission_name = UnicodeCol(length=16, alternateID=True, + alternateMethodName="by_permission_name") + description = UnicodeCol(length=255) + + groups = RelatedJoin("Group", + intermediateTable="group_permission", + joinColumn="permission_id", + otherColumn="group_id") + + diff --git a/examples/turbogears/markuptest/release.py b/examples/turbogears/markuptest/release.py --- a/examples/turbogears/markuptest/release.py +++ b/examples/turbogears/markuptest/release.py @@ -3,6 +3,7 @@ version = "1.0" # description = "Your plan to rule the world" +# long_description = "More description about your plan" # author = "Your Name Here" # email = "YourEmail@YourDomain" # copyright = "Vintage 2006 - a good year indeed" diff --git a/examples/turbogears/markuptest/templates/master.html b/examples/turbogears/markuptest/templates/master.html --- a/examples/turbogears/markuptest/templates/master.html +++ b/examples/turbogears/markuptest/templates/master.html @@ -1,13 +1,15 @@ + + Your title goes here - ${select('*')} +