1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/examples/samplepylons/MANIFEST.in Sat Feb 21 17:23:45 2009 +0100
1.3 @@ -0,0 +1,3 @@
1.4 +include samplepylons/config/deployment.ini_tmpl
1.5 +recursive-include samplepylons/public *
1.6 +recursive-include samplepylons/templates *
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/examples/samplepylons/README.txt Sat Feb 21 17:23:45 2009 +0100
2.3 @@ -0,0 +1,19 @@
2.4 +This file is for you to describe the samplepylons application. Typically
2.5 +you would include information such as the information below:
2.6 +
2.7 +Installation and Setup
2.8 +======================
2.9 +
2.10 +Install ``samplepylons`` using easy_install::
2.11 +
2.12 + easy_install samplepylons
2.13 +
2.14 +Make a config file as follows::
2.15 +
2.16 + paster make-config samplepylons config.ini
2.17 +
2.18 +Tweak the config file as appropriate and then setup the application::
2.19 +
2.20 + paster setup-app config.ini
2.21 +
2.22 +Then you are ready to go.
3.1 --- a/examples/samplepylons/development.ini Sat Feb 21 11:13:24 2009 +0100
3.2 +++ b/examples/samplepylons/development.ini Sat Feb 21 17:23:45 2009 +0100
3.3 @@ -11,10 +11,9 @@
3.4 error_email_from = paste@localhost
3.5
3.6 [server:main]
3.7 -use = egg:PasteScript#cherrypy
3.8 -host = 0.0.0.0
3.9 -port = 8080
3.10 -numthreads=4
3.11 +use = egg:Paste#http
3.12 +host = 127.0.0.1
3.13 +port = 5000
3.14
3.15 [pipeline:main]
3.16 pipeline = fileupload sample
3.17 @@ -26,6 +25,8 @@
3.18 [app:sample]
3.19 use = egg:samplepylons
3.20 full_stack = true
3.21 +static_files = true
3.22 +
3.23 cache_dir = %(here)s/data
3.24 beaker.session.key = samplepylons
3.25 beaker.session.secret = somesecret
3.26 @@ -44,7 +45,7 @@
3.27
3.28 # Logging configuration
3.29 [loggers]
3.30 -keys = root, samplepylons
3.31 +keys = root, routes, samplepylons
3.32
3.33 [handlers]
3.34 keys = console
3.35 @@ -56,6 +57,12 @@
3.36 level = INFO
3.37 handlers = console
3.38
3.39 +[logger_routes]
3.40 +level = INFO
3.41 +handlers =
3.42 +qualname = routes.middleware
3.43 +# "level = DEBUG" logs the route matched and routing variables.
3.44 +
3.45 [logger_samplepylons]
3.46 level = DEBUG
3.47 handlers =
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/examples/samplepylons/docs/index.txt Sat Feb 21 17:23:45 2009 +0100
4.3 @@ -0,0 +1,19 @@
4.4 +samplepylons
4.5 +++++++++++++
4.6 +
4.7 +This is the main index page of your documentation. It should be written in
4.8 +`reStructuredText format <http://docutils.sourceforge.net/rst.html>`_.
4.9 +
4.10 +You can generate your documentation in HTML format by running this command::
4.11 +
4.12 + setup.py pudge
4.13 +
4.14 +For this to work you will need to download and install `buildutils`_,
4.15 +`pudge`_, and `pygments`_. The ``pudge`` command is disabled by
4.16 +default; to ativate it in your project, run::
4.17 +
4.18 + setup.py addcommand -p buildutils.pudge_command
4.19 +
4.20 +.. _buildutils: http://pypi.python.org/pypi/buildutils
4.21 +.. _pudge: http://pudge.lesscode.org/
4.22 +.. _pygments: http://pygments.org/
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/examples/samplepylons/ez_setup.py Sat Feb 21 17:23:45 2009 +0100
5.3 @@ -0,0 +1,275 @@
5.4 +#!python
5.5 +"""Bootstrap setuptools installation
5.6 +
5.7 +If you want to use setuptools in your package's setup.py, just include this
5.8 +file in the same directory with it, and add this to the top of your setup.py::
5.9 +
5.10 + from ez_setup import use_setuptools
5.11 + use_setuptools()
5.12 +
5.13 +If you want to require a specific version of setuptools, set a download
5.14 +mirror, or use an alternate download directory, you can do so by supplying
5.15 +the appropriate options to ``use_setuptools()``.
5.16 +
5.17 +This file can also be run as a script to install or upgrade setuptools.
5.18 +"""
5.19 +import sys
5.20 +DEFAULT_VERSION = "0.6c9"
5.21 +DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
5.22 +
5.23 +md5_data = {
5.24 + 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
5.25 + 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
5.26 + 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
5.27 + 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
5.28 + 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
5.29 + 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
5.30 + 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
5.31 + 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
5.32 + 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
5.33 + 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
5.34 + 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
5.35 + 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
5.36 + 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
5.37 + 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
5.38 + 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
5.39 + 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
5.40 + 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
5.41 + 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
5.42 + 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
5.43 + 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
5.44 + 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
5.45 + 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
5.46 + 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
5.47 + 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
5.48 + 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
5.49 + 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
5.50 + 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
5.51 + 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
5.52 + 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
5.53 + 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
5.54 + 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03',
5.55 + 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a',
5.56 + 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6',
5.57 +}
5.58 +
5.59 +import sys, os
5.60 +try: from hashlib import md5
5.61 +except ImportError: from md5 import md5
5.62 +
5.63 +def _validate_md5(egg_name, data):
5.64 + if egg_name in md5_data:
5.65 + digest = md5(data).hexdigest()
5.66 + if digest != md5_data[egg_name]:
5.67 + print >>sys.stderr, (
5.68 + "md5 validation of %s failed! (Possible download problem?)"
5.69 + % egg_name
5.70 + )
5.71 + sys.exit(2)
5.72 + return data
5.73 +
5.74 +def use_setuptools(
5.75 + version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
5.76 + download_delay=15
5.77 +):
5.78 + """Automatically find/download setuptools and make it available on sys.path
5.79 +
5.80 + `version` should be a valid setuptools version number that is available
5.81 + as an egg for download under the `download_base` URL (which should end with
5.82 + a '/'). `to_dir` is the directory where setuptools will be downloaded, if
5.83 + it is not already available. If `download_delay` is specified, it should
5.84 + be the number of seconds that will be paused before initiating a download,
5.85 + should one be required. If an older version of setuptools is installed,
5.86 + this routine will print a message to ``sys.stderr`` and raise SystemExit in
5.87 + an attempt to abort the calling script.
5.88 + """
5.89 + was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
5.90 + def do_download():
5.91 + egg = download_setuptools(version, download_base, to_dir, download_delay)
5.92 + sys.path.insert(0, egg)
5.93 + import setuptools; setuptools.bootstrap_install_from = egg
5.94 + try:
5.95 + import pkg_resources
5.96 + except ImportError:
5.97 + return do_download()
5.98 + try:
5.99 + pkg_resources.require("setuptools>="+version); return
5.100 + except pkg_resources.VersionConflict, e:
5.101 + if was_imported:
5.102 + print >>sys.stderr, (
5.103 + "The required version of setuptools (>=%s) is not available, and\n"
5.104 + "can't be installed while this script is running. Please install\n"
5.105 + " a more recent version first, using 'easy_install -U setuptools'."
5.106 + "\n\n(Currently using %r)"
5.107 + ) % (version, e.args[0])
5.108 + sys.exit(2)
5.109 + else:
5.110 + del pkg_resources, sys.modules['pkg_resources'] # reload ok
5.111 + return do_download()
5.112 + except pkg_resources.DistributionNotFound:
5.113 + return do_download()
5.114 +
5.115 +def download_setuptools(
5.116 + version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
5.117 + delay = 15
5.118 +):
5.119 + """Download setuptools from a specified location and return its filename
5.120 +
5.121 + `version` should be a valid setuptools version number that is available
5.122 + as an egg for download under the `download_base` URL (which should end
5.123 + with a '/'). `to_dir` is the directory where the egg will be downloaded.
5.124 + `delay` is the number of seconds to pause before an actual download attempt.
5.125 + """
5.126 + import urllib2, shutil
5.127 + egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
5.128 + url = download_base + egg_name
5.129 + saveto = os.path.join(to_dir, egg_name)
5.130 + src = dst = None
5.131 + if not os.path.exists(saveto): # Avoid repeated downloads
5.132 + try:
5.133 + from distutils import log
5.134 + if delay:
5.135 + log.warn("""
5.136 +---------------------------------------------------------------------------
5.137 +This script requires setuptools version %s to run (even to display
5.138 +help). I will attempt to download it for you (from
5.139 +%s), but
5.140 +you may need to enable firewall access for this script first.
5.141 +I will start the download in %d seconds.
5.142 +
5.143 +(Note: if this machine does not have network access, please obtain the file
5.144 +
5.145 + %s
5.146 +
5.147 +and place it in this directory before rerunning this script.)
5.148 +---------------------------------------------------------------------------""",
5.149 + version, download_base, delay, url
5.150 + ); from time import sleep; sleep(delay)
5.151 + log.warn("Downloading %s", url)
5.152 + src = urllib2.urlopen(url)
5.153 + # Read/write all in one block, so we don't create a corrupt file
5.154 + # if the download is interrupted.
5.155 + data = _validate_md5(egg_name, src.read())
5.156 + dst = open(saveto,"wb"); dst.write(data)
5.157 + finally:
5.158 + if src: src.close()
5.159 + if dst: dst.close()
5.160 + return os.path.realpath(saveto)
5.161 +
5.162 +
5.163 +
5.164 +
5.165 +
5.166 +
5.167 +
5.168 +
5.169 +
5.170 +
5.171 +
5.172 +
5.173 +
5.174 +
5.175 +
5.176 +
5.177 +
5.178 +
5.179 +
5.180 +
5.181 +
5.182 +
5.183 +
5.184 +
5.185 +
5.186 +
5.187 +
5.188 +
5.189 +
5.190 +
5.191 +
5.192 +
5.193 +
5.194 +
5.195 +
5.196 +
5.197 +def main(argv, version=DEFAULT_VERSION):
5.198 + """Install or upgrade setuptools and EasyInstall"""
5.199 + try:
5.200 + import setuptools
5.201 + except ImportError:
5.202 + egg = None
5.203 + try:
5.204 + egg = download_setuptools(version, delay=0)
5.205 + sys.path.insert(0,egg)
5.206 + from setuptools.command.easy_install import main
5.207 + return main(list(argv)+[egg]) # we're done here
5.208 + finally:
5.209 + if egg and os.path.exists(egg):
5.210 + os.unlink(egg)
5.211 + else:
5.212 + if setuptools.__version__ == '0.0.1':
5.213 + print >>sys.stderr, (
5.214 + "You have an obsolete version of setuptools installed. Please\n"
5.215 + "remove it from your system entirely before rerunning this script."
5.216 + )
5.217 + sys.exit(2)
5.218 +
5.219 + req = "setuptools>="+version
5.220 + import pkg_resources
5.221 + try:
5.222 + pkg_resources.require(req)
5.223 + except pkg_resources.VersionConflict:
5.224 + try:
5.225 + from setuptools.command.easy_install import main
5.226 + except ImportError:
5.227 + from easy_install import main
5.228 + main(list(argv)+[download_setuptools(delay=0)])
5.229 + sys.exit(0) # try to force an exit
5.230 + else:
5.231 + if argv:
5.232 + from setuptools.command.easy_install import main
5.233 + main(argv)
5.234 + else:
5.235 + print "Setuptools version",version,"or greater has been installed."
5.236 + print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
5.237 +
5.238 +def update_md5(filenames):
5.239 + """Update our built-in md5 registry"""
5.240 +
5.241 + import re
5.242 +
5.243 + for name in filenames:
5.244 + base = os.path.basename(name)
5.245 + f = open(name,'rb')
5.246 + md5_data[base] = md5(f.read()).hexdigest()
5.247 + f.close()
5.248 +
5.249 + data = [" %r: %r,\n" % it for it in md5_data.items()]
5.250 + data.sort()
5.251 + repl = "".join(data)
5.252 +
5.253 + import inspect
5.254 + srcfile = inspect.getsourcefile(sys.modules[__name__])
5.255 + f = open(srcfile, 'rb'); src = f.read(); f.close()
5.256 +
5.257 + match = re.search("\nmd5_data = {\n([^}]+)}", src)
5.258 + if not match:
5.259 + print >>sys.stderr, "Internal error!"
5.260 + sys.exit(2)
5.261 +
5.262 + src = src[:match.start(1)] + repl + src[match.end(1):]
5.263 + f = open(srcfile,'w')
5.264 + f.write(src)
5.265 + f.close()
5.266 +
5.267 +
5.268 +if __name__=='__main__':
5.269 + if len(sys.argv)>2 and sys.argv[1]=='--md5update':
5.270 + update_md5(sys.argv[2:])
5.271 + else:
5.272 + main(sys.argv[1:])
5.273 +
5.274 +
5.275 +
5.276 +
5.277 +
5.278 +
6.1 --- a/examples/samplepylons/samplepylons/config/environment.py Sat Feb 21 11:13:24 2009 +0100
6.2 +++ b/examples/samplepylons/samplepylons/config/environment.py Sat Feb 21 17:23:45 2009 +0100
6.3 @@ -1,7 +1,9 @@
6.4 """Pylons environment configuration"""
6.5 import os
6.6
6.7 +from mako.lookup import TemplateLookup
6.8 from pylons import config
6.9 +from pylons.error import handle_mako_error
6.10
6.11 import samplepylons.lib.app_globals as app_globals
6.12 import samplepylons.lib.helpers
6.13 @@ -19,15 +21,19 @@
6.14 templates=[os.path.join(root, 'templates')])
6.15
6.16 # Initialize config with the basic options
6.17 - config.init_app(global_conf, app_conf, package='samplepylons',
6.18 - template_engine='mako', paths=paths)
6.19 + config.init_app(global_conf, app_conf, package='samplepylons', paths=paths)
6.20
6.21 config['routes.map'] = make_map()
6.22 - config['pylons.g'] = app_globals.Globals()
6.23 + config['pylons.app_globals'] = app_globals.Globals()
6.24 config['pylons.h'] = samplepylons.lib.helpers
6.25
6.26 - # Customize templating options via this variable
6.27 - tmpl_options = config['buffet.template_options']
6.28 -
6.29 + # Create the Mako TemplateLookup, with the default auto-escaping
6.30 + config['pylons.app_globals'].mako_lookup = TemplateLookup(
6.31 + directories=paths['templates'],
6.32 + error_handler=handle_mako_error,
6.33 + module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
6.34 + input_encoding='utf-8', default_filters=['escape'],
6.35 + imports=['from webhelpers.html import escape'])
6.36 +
6.37 # CONFIGURATION OPTIONS HERE (note: all config options will override
6.38 # any Pylons config options)
7.1 --- a/examples/samplepylons/samplepylons/config/middleware.py Sat Feb 21 11:13:24 2009 +0100
7.2 +++ b/examples/samplepylons/samplepylons/config/middleware.py Sat Feb 21 17:23:45 2009 +0100
7.3 @@ -1,18 +1,17 @@
7.4 """Pylons middleware initialization"""
7.5 +from beaker.middleware import CacheMiddleware, SessionMiddleware
7.6 from paste.cascade import Cascade
7.7 from paste.registry import RegistryManager
7.8 from paste.urlparser import StaticURLParser
7.9 from paste.deploy.converters import asbool
7.10 -
7.11 from pylons import config
7.12 -from pylons.error import error_template
7.13 -from pylons.middleware import error_mapper, ErrorDocuments, ErrorHandler, \
7.14 - StaticJavascripts
7.15 +from pylons.middleware import ErrorHandler, StatusCodeRedirect
7.16 from pylons.wsgiapp import PylonsApp
7.17 +from routes.middleware import RoutesMiddleware
7.18
7.19 from samplepylons.config.environment import load_environment
7.20
7.21 -def make_app(global_conf, full_stack=True, **app_conf):
7.22 +def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
7.23 """Create a Pylons WSGI application and return it
7.24
7.25 ``global_conf``
7.26 @@ -20,15 +19,20 @@
7.27 the [DEFAULT] section of the Paste ini file.
7.28
7.29 ``full_stack``
7.30 - Whether or not this application provides a full WSGI stack (by
7.31 - default, meaning it handles its own exceptions and errors).
7.32 - Disable full_stack when this application is "managed" by
7.33 - another WSGI middleware.
7.34 + Whether this application provides a full WSGI stack (by default,
7.35 + meaning it handles its own exceptions and errors). Disable
7.36 + full_stack when this application is "managed" by another WSGI
7.37 + middleware.
7.38 +
7.39 + ``static_files``
7.40 + Whether this application serves its own static files; disable
7.41 + when another web server is responsible for serving them.
7.42
7.43 ``app_conf``
7.44 - The application's local configuration. Normally specified in the
7.45 - [app:<name>] section of the Paste ini file (where <name>
7.46 + The application's local configuration. Normally specified in
7.47 + the [app:<name>] section of the Paste ini file (where <name>
7.48 defaults to main).
7.49 +
7.50 """
7.51 # Configure the Pylons environment
7.52 load_environment(global_conf, app_conf)
7.53 @@ -36,22 +40,30 @@
7.54 # The Pylons WSGI app
7.55 app = PylonsApp()
7.56
7.57 + # Routing/Session/Cache Middleware
7.58 + app = RoutesMiddleware(app, config['routes.map'])
7.59 + app = SessionMiddleware(app, config)
7.60 + app = CacheMiddleware(app, config)
7.61 +
7.62 # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
7.63
7.64 if asbool(full_stack):
7.65 # Handle Python exceptions
7.66 - app = ErrorHandler(app, global_conf, error_template=error_template,
7.67 - **config['pylons.errorware'])
7.68 + app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
7.69
7.70 # Display error documents for 401, 403, 404 status codes (and
7.71 # 500 when debug is disabled)
7.72 - app = ErrorDocuments(app, global_conf, mapper=error_mapper, **app_conf)
7.73 + if asbool(config['debug']):
7.74 + app = StatusCodeRedirect(app)
7.75 + else:
7.76 + app = StatusCodeRedirect(app, [400, 401, 403, 404, 500])
7.77
7.78 # Establish the Registry for this application
7.79 app = RegistryManager(app)
7.80
7.81 - # Static files
7.82 - javascripts_app = StaticJavascripts()
7.83 - static_app = StaticURLParser(config['pylons.paths']['static_files'])
7.84 - app = Cascade([static_app, javascripts_app, app])
7.85 + if asbool(static_files):
7.86 + # Serve static files
7.87 + static_app = StaticURLParser(config['pylons.paths']['static_files'])
7.88 + app = Cascade([static_app, app])
7.89 +
7.90 return app
8.1 --- a/examples/samplepylons/samplepylons/config/routing.py Sat Feb 21 11:13:24 2009 +0100
8.2 +++ b/examples/samplepylons/samplepylons/config/routing.py Sat Feb 21 17:23:45 2009 +0100
8.3 @@ -11,14 +11,16 @@
8.4 """Create, configure and return the routes Mapper"""
8.5 map = Mapper(directory=config['pylons.paths']['controllers'],
8.6 always_scan=config['debug'])
8.7 + map.minimization = False
8.8
8.9 # The ErrorController route (handles 404/500 error pages); it should
8.10 # likely stay at the top, ensuring it can always be resolved
8.11 - map.connect('error/:action/:id', controller='error')
8.12 + map.connect('/error/{action}', controller='error')
8.13 + map.connect('/error/{action}/{id}', controller='error')
8.14
8.15 # CUSTOM ROUTES HERE
8.16
8.17 - map.connect(':controller/:action/:id')
8.18 - map.connect('*url', controller='template', action='view')
8.19 + map.connect('/{controller}/{action}')
8.20 + map.connect('/{controller}/{action}/{id}')
8.21
8.22 return map
9.1 --- a/examples/samplepylons/samplepylons/controllers/error.py Sat Feb 21 11:13:24 2009 +0100
9.2 +++ b/examples/samplepylons/samplepylons/controllers/error.py Sat Feb 21 17:23:45 2009 +0100
9.3 @@ -1,12 +1,15 @@
9.4 import cgi
9.5 -import os.path
9.6
9.7 -from paste.urlparser import StaticURLParser
9.8 -from pylons.middleware import error_document_template, media_path
9.9 +from paste.urlparser import PkgResourcesParser
9.10 +from pylons import request
9.11 +from pylons.controllers.util import forward
9.12 +from pylons.middleware import error_document_template
9.13 +from webhelpers.html.builder import literal
9.14
9.15 -from samplepylons.lib.base import *
9.16 +from samplepylons.lib.base import BaseController
9.17
9.18 class ErrorController(BaseController):
9.19 +
9.20 """Generates error documents as and when they are required.
9.21
9.22 The ErrorDocuments middleware forwards to ErrorController when error
9.23 @@ -14,28 +17,30 @@
9.24
9.25 This behaviour can be altered by changing the parameters to the
9.26 ErrorDocuments middleware in your config/middleware.py file.
9.27 -
9.28 +
9.29 """
9.30 +
9.31 def document(self):
9.32 """Render the error document"""
9.33 + resp = request.environ.get('pylons.original_response')
9.34 + content = literal(resp.body) or cgi.escape(request.GET.get('message', ''))
9.35 page = error_document_template % \
9.36 dict(prefix=request.environ.get('SCRIPT_NAME', ''),
9.37 - code=cgi.escape(request.params.get('code', '')),
9.38 - message=cgi.escape(request.params.get('message', '')))
9.39 + code=cgi.escape(request.GET.get('code', str(resp.status_int))),
9.40 + message=content)
9.41 return page
9.42
9.43 def img(self, id):
9.44 """Serve Pylons' stock images"""
9.45 - return self._serve_file(os.path.join(media_path, 'img'), id)
9.46 + return self._serve_file('/'.join(['media/img', id]))
9.47
9.48 def style(self, id):
9.49 """Serve Pylons' stock stylesheets"""
9.50 - return self._serve_file(os.path.join(media_path, 'style'), id)
9.51 + return self._serve_file('/'.join(['media/style', id]))
9.52
9.53 - def _serve_file(self, root, path):
9.54 + def _serve_file(self, path):
9.55 """Call Paste's FileApp (a WSGI application) to serve the file
9.56 at the specified path
9.57 """
9.58 - static = StaticURLParser(root)
9.59 request.environ['PATH_INFO'] = '/%s' % path
9.60 - return static(request.environ, self.start_response)
9.61 + return forward(PkgResourcesParser('pylons', 'pylons'))
10.1 --- a/examples/samplepylons/samplepylons/lib/app_globals.py Sat Feb 21 11:13:24 2009 +0100
10.2 +++ b/examples/samplepylons/samplepylons/lib/app_globals.py Sat Feb 21 17:23:45 2009 +0100
10.3 @@ -1,14 +1,15 @@
10.4 """The application's Globals object"""
10.5 -from pylons import config
10.6
10.7 class Globals(object):
10.8 +
10.9 """Globals acts as a container for objects available throughout the
10.10 life of the application
10.11 +
10.12 """
10.13
10.14 def __init__(self):
10.15 """One instance of Globals is created during application
10.16 - initialization and is available during requests via the 'g'
10.17 - variable
10.18 + initialization and is available during requests via the
10.19 + 'app_globals' variable
10.20 +
10.21 """
10.22 - pass
11.1 --- a/examples/samplepylons/samplepylons/lib/base.py Sat Feb 21 11:13:24 2009 +0100
11.2 +++ b/examples/samplepylons/samplepylons/lib/base.py Sat Feb 21 17:23:45 2009 +0100
11.3 @@ -1,17 +1,9 @@
11.4 """The base Controller API
11.5
11.6 -Provides the BaseController class for subclassing, and other objects
11.7 -utilized by Controllers.
11.8 +Provides the BaseController class for subclassing.
11.9 """
11.10 -from pylons import c, cache, config, g, request, response, session
11.11 from pylons.controllers import WSGIController
11.12 -from pylons.controllers.util import abort, etag_cache, redirect_to
11.13 -from pylons.decorators import jsonify, validate
11.14 -from pylons.i18n import _, ungettext, N_
11.15 -from pylons.templating import render
11.16 -
11.17 -import samplepylons.lib.helpers as h
11.18 -import samplepylons.model as model
11.19 +from pylons.templating import render_mako as render
11.20
11.21 class BaseController(WSGIController):
11.22
11.23 @@ -21,7 +13,3 @@
11.24 # the request is routed to. This routing information is
11.25 # available in environ['pylons.routes_dict']
11.26 return WSGIController.__call__(self, environ, start_response)
11.27 -
11.28 -# Include the '_' function in the public names
11.29 -__all__ = [__name for __name in locals().keys() if not __name.startswith('_') \
11.30 - or __name == '_']
12.1 --- a/examples/samplepylons/samplepylons/lib/helpers.py Sat Feb 21 11:13:24 2009 +0100
12.2 +++ b/examples/samplepylons/samplepylons/lib/helpers.py Sat Feb 21 17:23:45 2009 +0100
12.3 @@ -1,6 +1,9 @@
12.4 """Helper functions
12.5
12.6 Consists of functions to typically be used within templates, but also
12.7 -available to Controllers. This module is available to both as 'h'.
12.8 +available to Controllers. This module is available to templates as 'h'.
12.9 """
12.10 -from webhelpers import *
12.11 +# Import helpers as desired, or define your own, ie:
12.12 +#from webhelpers.html.tags import checkbox, password
12.13 +from webhelpers.rails.asset_tag import javascript_include_tag
12.14 +from webhelpers.rails.javascript import javascript_tag
13.1 --- a/examples/samplepylons/samplepylons/templates/index.mak Sat Feb 21 11:13:24 2009 +0100
13.2 +++ b/examples/samplepylons/samplepylons/templates/index.mak Sat Feb 21 17:23:45 2009 +0100
13.3 @@ -14,13 +14,13 @@
13.4 a:visited { color: #666; }
13.5 a:hover { color: #fff; background-color:#000; }
13.6 </style>
13.7 - ${h.javascript_include_tag('/gp.fileupload.static/jquery.js')}
13.8 + ${h.javascript_include_tag('/gp.fileupload.static/jquery.js')|n}
13.9 ${h.javascript_tag('''
13.10 jQuery(document).ready(function() {
13.11 jQuery("form[enctype^='multipart/form-data']").fileUpload();
13.12 jQuery("#sample").fileUpload({action: "/upload/save"});
13.13 });
13.14 - ''')}
13.15 + ''')|n}
13.16
13.17 </head>
13.18 <body>
14.1 --- a/examples/samplepylons/samplepylons/tests/__init__.py Sat Feb 21 11:13:24 2009 +0100
14.2 +++ b/examples/samplepylons/samplepylons/tests/__init__.py Sat Feb 21 17:23:45 2009 +0100
14.3 @@ -1,40 +1,36 @@
14.4 """Pylons application test package
14.5
14.6 -When the test runner finds and executes tests within this directory,
14.7 -this file will be loaded to setup the test environment.
14.8 +This package assumes the Pylons environment is already loaded, such as
14.9 +when this script is imported from the `nosetests --with-pylons=test.ini`
14.10 +command.
14.11
14.12 -It registers the root directory of the project in sys.path and
14.13 -pkg_resources, in case the project hasn't been installed with
14.14 -setuptools. It also initializes the application via websetup (paster
14.15 -setup-app) with the project's test.ini configuration file.
14.16 +This module initializes the application via ``websetup`` (`paster
14.17 +setup-app`) and provides the base testing objects.
14.18 """
14.19 -import os
14.20 -import sys
14.21 from unittest import TestCase
14.22
14.23 -import pkg_resources
14.24 -import paste.fixture
14.25 -import paste.script.appinstall
14.26 from paste.deploy import loadapp
14.27 -from routes import url_for
14.28 +from paste.script.appinstall import SetupCommand
14.29 +from pylons import config, url
14.30 +from routes.util import URLGenerator
14.31 +from webtest import TestApp
14.32
14.33 -__all__ = ['url_for', 'TestController']
14.34 +import pylons.test
14.35
14.36 -here_dir = os.path.dirname(os.path.abspath(__file__))
14.37 -conf_dir = os.path.dirname(os.path.dirname(here_dir))
14.38 +__all__ = ['environ', 'url', 'TestController']
14.39
14.40 -sys.path.insert(0, conf_dir)
14.41 -pkg_resources.working_set.add_entry(conf_dir)
14.42 -pkg_resources.require('Paste')
14.43 -pkg_resources.require('PasteScript')
14.44 +# Invoke websetup with the current config file
14.45 +SetupCommand('setup-app').run([config['__file__']])
14.46
14.47 -test_file = os.path.join(conf_dir, 'test.ini')
14.48 -cmd = paste.script.appinstall.SetupCommand('setup-app')
14.49 -cmd.run([test_file])
14.50 +environ = {}
14.51
14.52 class TestController(TestCase):
14.53
14.54 def __init__(self, *args, **kwargs):
14.55 - wsgiapp = loadapp('config:test.ini', relative_to=conf_dir)
14.56 - self.app = paste.fixture.TestApp(wsgiapp)
14.57 + if pylons.test.pylonsapp:
14.58 + wsgiapp = pylons.test.pylonsapp
14.59 + else:
14.60 + wsgiapp = loadapp('config:%s' % config['__file__'])
14.61 + self.app = TestApp(wsgiapp)
14.62 + url._push_object(URLGenerator(config['routes.map'], environ))
14.63 TestCase.__init__(self, *args, **kwargs)
15.1 --- a/examples/samplepylons/samplepylons/websetup.py Sat Feb 21 11:13:24 2009 +0100
15.2 +++ b/examples/samplepylons/samplepylons/websetup.py Sat Feb 21 17:23:45 2009 +0100
15.3 @@ -1,14 +1,10 @@
15.4 """Setup the samplepylons application"""
15.5 import logging
15.6
15.7 -from paste.deploy import appconfig
15.8 -from pylons import config
15.9 -
15.10 from samplepylons.config.environment import load_environment
15.11
15.12 log = logging.getLogger(__name__)
15.13
15.14 -def setup_config(command, filename, section, vars):
15.15 +def setup_app(command, conf, vars):
15.16 """Place any commands to setup samplepylons here"""
15.17 - conf = appconfig('config:' + filename)
15.18 load_environment(conf.global_conf, conf.local_conf)
16.1 --- a/examples/samplepylons/setup.cfg Sat Feb 21 11:13:24 2009 +0100
16.2 +++ b/examples/samplepylons/setup.cfg Sat Feb 21 17:23:45 2009 +0100
16.3 @@ -5,36 +5,8 @@
16.4 [easy_install]
16.5 find_links = http://www.pylonshq.com/download/
16.6
16.7 -[pudge]
16.8 -theme = pythonpaste.org
16.9 -
16.10 -# Add extra doc files here with spaces between them
16.11 -docs = docs/index.txt
16.12 -
16.13 -# Doc Settings
16.14 -doc_base = docs/
16.15 -dest = docs/html
16.16 -
16.17 -# Add extra modules here separated with commas
16.18 -modules = samplepylons
16.19 -title = Samplepylons
16.20 -organization = Pylons
16.21 -
16.22 -# Highlight code-block sections with Pygments
16.23 -highlighter = pygments
16.24 -
16.25 -# Optionally add extra links
16.26 -#organization_url = http://pylonshq.com/
16.27 -#trac_url = http://pylonshq.com/project
16.28 -settings = no_about=true
16.29 -
16.30 -# Optionally add extra settings
16.31 -# link1=/community/ Community
16.32 -# link2=/download/ Download
16.33 -
16.34 -[publish]
16.35 -doc-dir=docs/html
16.36 -make-dirs=1
16.37 +[nosetests]
16.38 +with-pylons = test.ini
16.39
16.40 # Babel configuration
16.41 [compile_catalog]
17.1 --- a/examples/samplepylons/setup.py Sat Feb 21 11:13:24 2009 +0100
17.2 +++ b/examples/samplepylons/setup.py Sat Feb 21 17:23:45 2009 +0100
17.3 @@ -7,20 +7,25 @@
17.4
17.5 setup(
17.6 name='samplepylons',
17.7 - version="",
17.8 - #description='',
17.9 - #author='',
17.10 - #author_email='',
17.11 - #url='',
17.12 - install_requires=["Pylons>=0.9.6.2"],
17.13 + version='0.1',
17.14 + description='',
17.15 + author='',
17.16 + author_email='',
17.17 + url='',
17.18 + install_requires=[
17.19 + "Pylons>=0.9.7rc6",
17.20 + ],
17.21 + setup_requires=["PasteScript>=1.6.3"],
17.22 packages=find_packages(exclude=['ez_setup']),
17.23 include_package_data=True,
17.24 test_suite='nose.collector',
17.25 package_data={'samplepylons': ['i18n/*/LC_MESSAGES/*.mo']},
17.26 - #message_extractors = {'samplepylons': [
17.27 + #message_extractors={'samplepylons': [
17.28 # ('**.py', 'python', None),
17.29 - # ('templates/**.mako', 'mako', None),
17.30 + # ('templates/**.mako', 'mako', {'input_encoding': 'utf-8'}),
17.31 # ('public/**', 'ignore', None)]},
17.32 + zip_safe=False,
17.33 + paster_plugins=['PasteScript', 'Pylons'],
17.34 entry_points="""
17.35 [paste.app_factory]
17.36 main = samplepylons.config.middleware:make_app
18.1 --- a/examples/samplepylons/test.ini Sat Feb 21 11:13:24 2009 +0100
18.2 +++ b/examples/samplepylons/test.ini Sat Feb 21 17:23:45 2009 +0100
18.3 @@ -12,7 +12,7 @@
18.4
18.5 [server:main]
18.6 use = egg:Paste#http
18.7 -host = 0.0.0.0
18.8 +host = 127.0.0.1
18.9 port = 5000
18.10
18.11 [app:main]