1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/.hgtags Wed Feb 03 23:20:47 2010 +0100
1.3 @@ -0,0 +1,2 @@
1.4 +092dbb058c6ab26f579eaff90a1a6f652a34dace 0.7
1.5 +8e22e67400ce23fb7e36bca1b77f69969c80e2a3 0.8
2.1 --- a/CHANGES.txt Fri Aug 07 18:14:37 2009 +0200
2.2 +++ b/CHANGES.txt Wed Feb 03 23:20:47 2010 +0100
2.3 @@ -1,3 +1,15 @@
2.4 +0.8 (2009-02-20)
2.5 +----------------
2.6 +
2.7 +- fix installation problem
2.8 +
2.9 +0.7 (2009-02-08)
2.10 +----------------
2.11 +
2.12 +- fix #1. bug in js when the environ have a SCRIPT_NAME
2.13 +
2.14 +- storage improvement. (by trollfot)
2.15 +
2.16 0.6 (2008-11-24)
2.17 ----------------
2.18
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/MANIFEST.in Wed Feb 03 23:20:47 2010 +0100
3.3 @@ -0,0 +1,3 @@
3.4 +include gp/fileupload/static/*
3.5 +include docs/*txt
3.6 +include *txt
4.1 --- a/README.txt Fri Aug 07 18:14:37 2009 +0200
4.2 +++ b/README.txt Wed Feb 03 23:20:47 2010 +0100
4.3 @@ -3,6 +3,8 @@
4.4 A `demo <http://www.gawel.org/docs/gp.fileupload/demo.html>`_ page is also
4.5 available.
4.6
4.7 +If you found a bug submit an `issue <http://www.bitbucket.org/gawel/gpfileupload/issues/?status=new>`.
4.8 +
4.9 .. contents::
4.10
4.11 Description
5.1 --- a/docs/conf.py Fri Aug 07 18:14:37 2009 +0200
5.2 +++ b/docs/conf.py Wed Feb 03 23:20:47 2010 +0100
5.3 @@ -42,9 +42,9 @@
5.4 # other places throughout the built documents.
5.5 #
5.6 # The short X.Y version.
5.7 -version = '0.6'
5.8 +version = '0.8'
5.9 # The full version, including alpha/beta/rc tags.
5.10 -release = '0.6'
5.11 +release = version
5.12
5.13 # There are two options for replacing |today|: either, you set today to some
5.14 # non-false value, then it is used:
6.1 --- a/docs/index.txt Fri Aug 07 18:14:37 2009 +0200
6.2 +++ b/docs/index.txt Wed Feb 03 23:20:47 2010 +0100
6.3 @@ -21,6 +21,10 @@
6.4 demo
6.5 contributors
6.6
6.7 +Bug Tracker
6.8 +===========
6.9 +
6.10 +If you found a bug submit an `issue <http://www.bitbucket.org/gawel/gpfileupload/issues/?status=new>`_.
6.11
6.12 Indices and tables
6.13 ==================
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/examples/samplepylons/MANIFEST.in Wed Feb 03 23:20:47 2010 +0100
7.3 @@ -0,0 +1,3 @@
7.4 +include samplepylons/config/deployment.ini_tmpl
7.5 +recursive-include samplepylons/public *
7.6 +recursive-include samplepylons/templates *
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/examples/samplepylons/README.txt Wed Feb 03 23:20:47 2010 +0100
8.3 @@ -0,0 +1,19 @@
8.4 +This file is for you to describe the samplepylons application. Typically
8.5 +you would include information such as the information below:
8.6 +
8.7 +Installation and Setup
8.8 +======================
8.9 +
8.10 +Install ``samplepylons`` using easy_install::
8.11 +
8.12 + easy_install samplepylons
8.13 +
8.14 +Make a config file as follows::
8.15 +
8.16 + paster make-config samplepylons config.ini
8.17 +
8.18 +Tweak the config file as appropriate and then setup the application::
8.19 +
8.20 + paster setup-app config.ini
8.21 +
8.22 +Then you are ready to go.
9.1 --- a/examples/samplepylons/development.ini Fri Aug 07 18:14:37 2009 +0200
9.2 +++ b/examples/samplepylons/development.ini Wed Feb 03 23:20:47 2010 +0100
9.3 @@ -11,10 +11,9 @@
9.4 error_email_from = paste@localhost
9.5
9.6 [server:main]
9.7 -use = egg:PasteScript#cherrypy
9.8 -host = 0.0.0.0
9.9 -port = 8080
9.10 -numthreads=4
9.11 +use = egg:Paste#http
9.12 +host = 127.0.0.1
9.13 +port = 5000
9.14
9.15 [pipeline:main]
9.16 pipeline = fileupload sample
9.17 @@ -26,6 +25,8 @@
9.18 [app:sample]
9.19 use = egg:samplepylons
9.20 full_stack = true
9.21 +static_files = true
9.22 +
9.23 cache_dir = %(here)s/data
9.24 beaker.session.key = samplepylons
9.25 beaker.session.secret = somesecret
9.26 @@ -44,7 +45,7 @@
9.27
9.28 # Logging configuration
9.29 [loggers]
9.30 -keys = root, samplepylons
9.31 +keys = root, routes, samplepylons
9.32
9.33 [handlers]
9.34 keys = console
9.35 @@ -56,6 +57,12 @@
9.36 level = INFO
9.37 handlers = console
9.38
9.39 +[logger_routes]
9.40 +level = INFO
9.41 +handlers =
9.42 +qualname = routes.middleware
9.43 +# "level = DEBUG" logs the route matched and routing variables.
9.44 +
9.45 [logger_samplepylons]
9.46 level = DEBUG
9.47 handlers =
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/examples/samplepylons/docs/index.txt Wed Feb 03 23:20:47 2010 +0100
10.3 @@ -0,0 +1,19 @@
10.4 +samplepylons
10.5 +++++++++++++
10.6 +
10.7 +This is the main index page of your documentation. It should be written in
10.8 +`reStructuredText format <http://docutils.sourceforge.net/rst.html>`_.
10.9 +
10.10 +You can generate your documentation in HTML format by running this command::
10.11 +
10.12 + setup.py pudge
10.13 +
10.14 +For this to work you will need to download and install `buildutils`_,
10.15 +`pudge`_, and `pygments`_. The ``pudge`` command is disabled by
10.16 +default; to ativate it in your project, run::
10.17 +
10.18 + setup.py addcommand -p buildutils.pudge_command
10.19 +
10.20 +.. _buildutils: http://pypi.python.org/pypi/buildutils
10.21 +.. _pudge: http://pudge.lesscode.org/
10.22 +.. _pygments: http://pygments.org/
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/examples/samplepylons/ez_setup.py Wed Feb 03 23:20:47 2010 +0100
11.3 @@ -0,0 +1,275 @@
11.4 +#!python
11.5 +"""Bootstrap setuptools installation
11.6 +
11.7 +If you want to use setuptools in your package's setup.py, just include this
11.8 +file in the same directory with it, and add this to the top of your setup.py::
11.9 +
11.10 + from ez_setup import use_setuptools
11.11 + use_setuptools()
11.12 +
11.13 +If you want to require a specific version of setuptools, set a download
11.14 +mirror, or use an alternate download directory, you can do so by supplying
11.15 +the appropriate options to ``use_setuptools()``.
11.16 +
11.17 +This file can also be run as a script to install or upgrade setuptools.
11.18 +"""
11.19 +import sys
11.20 +DEFAULT_VERSION = "0.6c9"
11.21 +DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
11.22 +
11.23 +md5_data = {
11.24 + 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
11.25 + 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
11.26 + 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
11.27 + 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
11.28 + 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
11.29 + 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
11.30 + 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
11.31 + 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
11.32 + 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
11.33 + 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
11.34 + 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
11.35 + 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
11.36 + 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
11.37 + 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
11.38 + 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
11.39 + 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
11.40 + 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
11.41 + 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
11.42 + 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
11.43 + 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
11.44 + 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
11.45 + 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
11.46 + 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
11.47 + 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
11.48 + 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
11.49 + 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
11.50 + 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
11.51 + 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
11.52 + 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
11.53 + 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
11.54 + 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03',
11.55 + 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a',
11.56 + 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6',
11.57 +}
11.58 +
11.59 +import sys, os
11.60 +try: from hashlib import md5
11.61 +except ImportError: from md5 import md5
11.62 +
11.63 +def _validate_md5(egg_name, data):
11.64 + if egg_name in md5_data:
11.65 + digest = md5(data).hexdigest()
11.66 + if digest != md5_data[egg_name]:
11.67 + print >>sys.stderr, (
11.68 + "md5 validation of %s failed! (Possible download problem?)"
11.69 + % egg_name
11.70 + )
11.71 + sys.exit(2)
11.72 + return data
11.73 +
11.74 +def use_setuptools(
11.75 + version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
11.76 + download_delay=15
11.77 +):
11.78 + """Automatically find/download setuptools and make it available on sys.path
11.79 +
11.80 + `version` should be a valid setuptools version number that is available
11.81 + as an egg for download under the `download_base` URL (which should end with
11.82 + a '/'). `to_dir` is the directory where setuptools will be downloaded, if
11.83 + it is not already available. If `download_delay` is specified, it should
11.84 + be the number of seconds that will be paused before initiating a download,
11.85 + should one be required. If an older version of setuptools is installed,
11.86 + this routine will print a message to ``sys.stderr`` and raise SystemExit in
11.87 + an attempt to abort the calling script.
11.88 + """
11.89 + was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
11.90 + def do_download():
11.91 + egg = download_setuptools(version, download_base, to_dir, download_delay)
11.92 + sys.path.insert(0, egg)
11.93 + import setuptools; setuptools.bootstrap_install_from = egg
11.94 + try:
11.95 + import pkg_resources
11.96 + except ImportError:
11.97 + return do_download()
11.98 + try:
11.99 + pkg_resources.require("setuptools>="+version); return
11.100 + except pkg_resources.VersionConflict, e:
11.101 + if was_imported:
11.102 + print >>sys.stderr, (
11.103 + "The required version of setuptools (>=%s) is not available, and\n"
11.104 + "can't be installed while this script is running. Please install\n"
11.105 + " a more recent version first, using 'easy_install -U setuptools'."
11.106 + "\n\n(Currently using %r)"
11.107 + ) % (version, e.args[0])
11.108 + sys.exit(2)
11.109 + else:
11.110 + del pkg_resources, sys.modules['pkg_resources'] # reload ok
11.111 + return do_download()
11.112 + except pkg_resources.DistributionNotFound:
11.113 + return do_download()
11.114 +
11.115 +def download_setuptools(
11.116 + version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
11.117 + delay = 15
11.118 +):
11.119 + """Download setuptools from a specified location and return its filename
11.120 +
11.121 + `version` should be a valid setuptools version number that is available
11.122 + as an egg for download under the `download_base` URL (which should end
11.123 + with a '/'). `to_dir` is the directory where the egg will be downloaded.
11.124 + `delay` is the number of seconds to pause before an actual download attempt.
11.125 + """
11.126 + import urllib2, shutil
11.127 + egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
11.128 + url = download_base + egg_name
11.129 + saveto = os.path.join(to_dir, egg_name)
11.130 + src = dst = None
11.131 + if not os.path.exists(saveto): # Avoid repeated downloads
11.132 + try:
11.133 + from distutils import log
11.134 + if delay:
11.135 + log.warn("""
11.136 +---------------------------------------------------------------------------
11.137 +This script requires setuptools version %s to run (even to display
11.138 +help). I will attempt to download it for you (from
11.139 +%s), but
11.140 +you may need to enable firewall access for this script first.
11.141 +I will start the download in %d seconds.
11.142 +
11.143 +(Note: if this machine does not have network access, please obtain the file
11.144 +
11.145 + %s
11.146 +
11.147 +and place it in this directory before rerunning this script.)
11.148 +---------------------------------------------------------------------------""",
11.149 + version, download_base, delay, url
11.150 + ); from time import sleep; sleep(delay)
11.151 + log.warn("Downloading %s", url)
11.152 + src = urllib2.urlopen(url)
11.153 + # Read/write all in one block, so we don't create a corrupt file
11.154 + # if the download is interrupted.
11.155 + data = _validate_md5(egg_name, src.read())
11.156 + dst = open(saveto,"wb"); dst.write(data)
11.157 + finally:
11.158 + if src: src.close()
11.159 + if dst: dst.close()
11.160 + return os.path.realpath(saveto)
11.161 +
11.162 +
11.163 +
11.164 +
11.165 +
11.166 +
11.167 +
11.168 +
11.169 +
11.170 +
11.171 +
11.172 +
11.173 +
11.174 +
11.175 +
11.176 +
11.177 +
11.178 +
11.179 +
11.180 +
11.181 +
11.182 +
11.183 +
11.184 +
11.185 +
11.186 +
11.187 +
11.188 +
11.189 +
11.190 +
11.191 +
11.192 +
11.193 +
11.194 +
11.195 +
11.196 +
11.197 +def main(argv, version=DEFAULT_VERSION):
11.198 + """Install or upgrade setuptools and EasyInstall"""
11.199 + try:
11.200 + import setuptools
11.201 + except ImportError:
11.202 + egg = None
11.203 + try:
11.204 + egg = download_setuptools(version, delay=0)
11.205 + sys.path.insert(0,egg)
11.206 + from setuptools.command.easy_install import main
11.207 + return main(list(argv)+[egg]) # we're done here
11.208 + finally:
11.209 + if egg and os.path.exists(egg):
11.210 + os.unlink(egg)
11.211 + else:
11.212 + if setuptools.__version__ == '0.0.1':
11.213 + print >>sys.stderr, (
11.214 + "You have an obsolete version of setuptools installed. Please\n"
11.215 + "remove it from your system entirely before rerunning this script."
11.216 + )
11.217 + sys.exit(2)
11.218 +
11.219 + req = "setuptools>="+version
11.220 + import pkg_resources
11.221 + try:
11.222 + pkg_resources.require(req)
11.223 + except pkg_resources.VersionConflict:
11.224 + try:
11.225 + from setuptools.command.easy_install import main
11.226 + except ImportError:
11.227 + from easy_install import main
11.228 + main(list(argv)+[download_setuptools(delay=0)])
11.229 + sys.exit(0) # try to force an exit
11.230 + else:
11.231 + if argv:
11.232 + from setuptools.command.easy_install import main
11.233 + main(argv)
11.234 + else:
11.235 + print "Setuptools version",version,"or greater has been installed."
11.236 + print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
11.237 +
11.238 +def update_md5(filenames):
11.239 + """Update our built-in md5 registry"""
11.240 +
11.241 + import re
11.242 +
11.243 + for name in filenames:
11.244 + base = os.path.basename(name)
11.245 + f = open(name,'rb')
11.246 + md5_data[base] = md5(f.read()).hexdigest()
11.247 + f.close()
11.248 +
11.249 + data = [" %r: %r,\n" % it for it in md5_data.items()]
11.250 + data.sort()
11.251 + repl = "".join(data)
11.252 +
11.253 + import inspect
11.254 + srcfile = inspect.getsourcefile(sys.modules[__name__])
11.255 + f = open(srcfile, 'rb'); src = f.read(); f.close()
11.256 +
11.257 + match = re.search("\nmd5_data = {\n([^}]+)}", src)
11.258 + if not match:
11.259 + print >>sys.stderr, "Internal error!"
11.260 + sys.exit(2)
11.261 +
11.262 + src = src[:match.start(1)] + repl + src[match.end(1):]
11.263 + f = open(srcfile,'w')
11.264 + f.write(src)
11.265 + f.close()
11.266 +
11.267 +
11.268 +if __name__=='__main__':
11.269 + if len(sys.argv)>2 and sys.argv[1]=='--md5update':
11.270 + update_md5(sys.argv[2:])
11.271 + else:
11.272 + main(sys.argv[1:])
11.273 +
11.274 +
11.275 +
11.276 +
11.277 +
11.278 +
12.1 --- a/examples/samplepylons/samplepylons/config/environment.py Fri Aug 07 18:14:37 2009 +0200
12.2 +++ b/examples/samplepylons/samplepylons/config/environment.py Wed Feb 03 23:20:47 2010 +0100
12.3 @@ -1,7 +1,9 @@
12.4 """Pylons environment configuration"""
12.5 import os
12.6
12.7 +from mako.lookup import TemplateLookup
12.8 from pylons import config
12.9 +from pylons.error import handle_mako_error
12.10
12.11 import samplepylons.lib.app_globals as app_globals
12.12 import samplepylons.lib.helpers
12.13 @@ -19,15 +21,19 @@
12.14 templates=[os.path.join(root, 'templates')])
12.15
12.16 # Initialize config with the basic options
12.17 - config.init_app(global_conf, app_conf, package='samplepylons',
12.18 - template_engine='mako', paths=paths)
12.19 + config.init_app(global_conf, app_conf, package='samplepylons', paths=paths)
12.20
12.21 config['routes.map'] = make_map()
12.22 - config['pylons.g'] = app_globals.Globals()
12.23 + config['pylons.app_globals'] = app_globals.Globals()
12.24 config['pylons.h'] = samplepylons.lib.helpers
12.25
12.26 - # Customize templating options via this variable
12.27 - tmpl_options = config['buffet.template_options']
12.28 -
12.29 + # Create the Mako TemplateLookup, with the default auto-escaping
12.30 + config['pylons.app_globals'].mako_lookup = TemplateLookup(
12.31 + directories=paths['templates'],
12.32 + error_handler=handle_mako_error,
12.33 + module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
12.34 + input_encoding='utf-8', default_filters=['escape'],
12.35 + imports=['from webhelpers.html import escape'])
12.36 +
12.37 # CONFIGURATION OPTIONS HERE (note: all config options will override
12.38 # any Pylons config options)
13.1 --- a/examples/samplepylons/samplepylons/config/middleware.py Fri Aug 07 18:14:37 2009 +0200
13.2 +++ b/examples/samplepylons/samplepylons/config/middleware.py Wed Feb 03 23:20:47 2010 +0100
13.3 @@ -1,18 +1,17 @@
13.4 """Pylons middleware initialization"""
13.5 +from beaker.middleware import CacheMiddleware, SessionMiddleware
13.6 from paste.cascade import Cascade
13.7 from paste.registry import RegistryManager
13.8 from paste.urlparser import StaticURLParser
13.9 from paste.deploy.converters import asbool
13.10 -
13.11 from pylons import config
13.12 -from pylons.error import error_template
13.13 -from pylons.middleware import error_mapper, ErrorDocuments, ErrorHandler, \
13.14 - StaticJavascripts
13.15 +from pylons.middleware import ErrorHandler, StatusCodeRedirect
13.16 from pylons.wsgiapp import PylonsApp
13.17 +from routes.middleware import RoutesMiddleware
13.18
13.19 from samplepylons.config.environment import load_environment
13.20
13.21 -def make_app(global_conf, full_stack=True, **app_conf):
13.22 +def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
13.23 """Create a Pylons WSGI application and return it
13.24
13.25 ``global_conf``
13.26 @@ -20,15 +19,20 @@
13.27 the [DEFAULT] section of the Paste ini file.
13.28
13.29 ``full_stack``
13.30 - Whether or not this application provides a full WSGI stack (by
13.31 - default, meaning it handles its own exceptions and errors).
13.32 - Disable full_stack when this application is "managed" by
13.33 - another WSGI middleware.
13.34 + Whether this application provides a full WSGI stack (by default,
13.35 + meaning it handles its own exceptions and errors). Disable
13.36 + full_stack when this application is "managed" by another WSGI
13.37 + middleware.
13.38 +
13.39 + ``static_files``
13.40 + Whether this application serves its own static files; disable
13.41 + when another web server is responsible for serving them.
13.42
13.43 ``app_conf``
13.44 - The application's local configuration. Normally specified in the
13.45 - [app:<name>] section of the Paste ini file (where <name>
13.46 + The application's local configuration. Normally specified in
13.47 + the [app:<name>] section of the Paste ini file (where <name>
13.48 defaults to main).
13.49 +
13.50 """
13.51 # Configure the Pylons environment
13.52 load_environment(global_conf, app_conf)
13.53 @@ -36,22 +40,30 @@
13.54 # The Pylons WSGI app
13.55 app = PylonsApp()
13.56
13.57 + # Routing/Session/Cache Middleware
13.58 + app = RoutesMiddleware(app, config['routes.map'])
13.59 + app = SessionMiddleware(app, config)
13.60 + app = CacheMiddleware(app, config)
13.61 +
13.62 # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
13.63
13.64 if asbool(full_stack):
13.65 # Handle Python exceptions
13.66 - app = ErrorHandler(app, global_conf, error_template=error_template,
13.67 - **config['pylons.errorware'])
13.68 + app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
13.69
13.70 # Display error documents for 401, 403, 404 status codes (and
13.71 # 500 when debug is disabled)
13.72 - app = ErrorDocuments(app, global_conf, mapper=error_mapper, **app_conf)
13.73 + if asbool(config['debug']):
13.74 + app = StatusCodeRedirect(app)
13.75 + else:
13.76 + app = StatusCodeRedirect(app, [400, 401, 403, 404, 500])
13.77
13.78 # Establish the Registry for this application
13.79 app = RegistryManager(app)
13.80
13.81 - # Static files
13.82 - javascripts_app = StaticJavascripts()
13.83 - static_app = StaticURLParser(config['pylons.paths']['static_files'])
13.84 - app = Cascade([static_app, javascripts_app, app])
13.85 + if asbool(static_files):
13.86 + # Serve static files
13.87 + static_app = StaticURLParser(config['pylons.paths']['static_files'])
13.88 + app = Cascade([static_app, app])
13.89 +
13.90 return app
14.1 --- a/examples/samplepylons/samplepylons/config/routing.py Fri Aug 07 18:14:37 2009 +0200
14.2 +++ b/examples/samplepylons/samplepylons/config/routing.py Wed Feb 03 23:20:47 2010 +0100
14.3 @@ -11,14 +11,16 @@
14.4 """Create, configure and return the routes Mapper"""
14.5 map = Mapper(directory=config['pylons.paths']['controllers'],
14.6 always_scan=config['debug'])
14.7 + map.minimization = False
14.8
14.9 # The ErrorController route (handles 404/500 error pages); it should
14.10 # likely stay at the top, ensuring it can always be resolved
14.11 - map.connect('error/:action/:id', controller='error')
14.12 + map.connect('/error/{action}', controller='error')
14.13 + map.connect('/error/{action}/{id}', controller='error')
14.14
14.15 # CUSTOM ROUTES HERE
14.16
14.17 - map.connect(':controller/:action/:id')
14.18 - map.connect('*url', controller='template', action='view')
14.19 + map.connect('/{controller}/{action}')
14.20 + map.connect('/{controller}/{action}/{id}')
14.21
14.22 return map
15.1 --- a/examples/samplepylons/samplepylons/controllers/error.py Fri Aug 07 18:14:37 2009 +0200
15.2 +++ b/examples/samplepylons/samplepylons/controllers/error.py Wed Feb 03 23:20:47 2010 +0100
15.3 @@ -1,12 +1,15 @@
15.4 import cgi
15.5 -import os.path
15.6
15.7 -from paste.urlparser import StaticURLParser
15.8 -from pylons.middleware import error_document_template, media_path
15.9 +from paste.urlparser import PkgResourcesParser
15.10 +from pylons import request
15.11 +from pylons.controllers.util import forward
15.12 +from pylons.middleware import error_document_template
15.13 +from webhelpers.html.builder import literal
15.14
15.15 -from samplepylons.lib.base import *
15.16 +from samplepylons.lib.base import BaseController
15.17
15.18 class ErrorController(BaseController):
15.19 +
15.20 """Generates error documents as and when they are required.
15.21
15.22 The ErrorDocuments middleware forwards to ErrorController when error
15.23 @@ -14,28 +17,30 @@
15.24
15.25 This behaviour can be altered by changing the parameters to the
15.26 ErrorDocuments middleware in your config/middleware.py file.
15.27 -
15.28 +
15.29 """
15.30 +
15.31 def document(self):
15.32 """Render the error document"""
15.33 + resp = request.environ.get('pylons.original_response')
15.34 + content = literal(resp.body) or cgi.escape(request.GET.get('message', ''))
15.35 page = error_document_template % \
15.36 dict(prefix=request.environ.get('SCRIPT_NAME', ''),
15.37 - code=cgi.escape(request.params.get('code', '')),
15.38 - message=cgi.escape(request.params.get('message', '')))
15.39 + code=cgi.escape(request.GET.get('code', str(resp.status_int))),
15.40 + message=content)
15.41 return page
15.42
15.43 def img(self, id):
15.44 """Serve Pylons' stock images"""
15.45 - return self._serve_file(os.path.join(media_path, 'img'), id)
15.46 + return self._serve_file('/'.join(['media/img', id]))
15.47
15.48 def style(self, id):
15.49 """Serve Pylons' stock stylesheets"""
15.50 - return self._serve_file(os.path.join(media_path, 'style'), id)
15.51 + return self._serve_file('/'.join(['media/style', id]))
15.52
15.53 - def _serve_file(self, root, path):
15.54 + def _serve_file(self, path):
15.55 """Call Paste's FileApp (a WSGI application) to serve the file
15.56 at the specified path
15.57 """
15.58 - static = StaticURLParser(root)
15.59 request.environ['PATH_INFO'] = '/%s' % path
15.60 - return static(request.environ, self.start_response)
15.61 + return forward(PkgResourcesParser('pylons', 'pylons'))
16.1 --- a/examples/samplepylons/samplepylons/lib/app_globals.py Fri Aug 07 18:14:37 2009 +0200
16.2 +++ b/examples/samplepylons/samplepylons/lib/app_globals.py Wed Feb 03 23:20:47 2010 +0100
16.3 @@ -1,14 +1,15 @@
16.4 """The application's Globals object"""
16.5 -from pylons import config
16.6
16.7 class Globals(object):
16.8 +
16.9 """Globals acts as a container for objects available throughout the
16.10 life of the application
16.11 +
16.12 """
16.13
16.14 def __init__(self):
16.15 """One instance of Globals is created during application
16.16 - initialization and is available during requests via the 'g'
16.17 - variable
16.18 + initialization and is available during requests via the
16.19 + 'app_globals' variable
16.20 +
16.21 """
16.22 - pass
17.1 --- a/examples/samplepylons/samplepylons/lib/base.py Fri Aug 07 18:14:37 2009 +0200
17.2 +++ b/examples/samplepylons/samplepylons/lib/base.py Wed Feb 03 23:20:47 2010 +0100
17.3 @@ -1,17 +1,9 @@
17.4 """The base Controller API
17.5
17.6 -Provides the BaseController class for subclassing, and other objects
17.7 -utilized by Controllers.
17.8 +Provides the BaseController class for subclassing.
17.9 """
17.10 -from pylons import c, cache, config, g, request, response, session
17.11 from pylons.controllers import WSGIController
17.12 -from pylons.controllers.util import abort, etag_cache, redirect_to
17.13 -from pylons.decorators import jsonify, validate
17.14 -from pylons.i18n import _, ungettext, N_
17.15 -from pylons.templating import render
17.16 -
17.17 -import samplepylons.lib.helpers as h
17.18 -import samplepylons.model as model
17.19 +from pylons.templating import render_mako as render
17.20
17.21 class BaseController(WSGIController):
17.22
17.23 @@ -21,7 +13,3 @@
17.24 # the request is routed to. This routing information is
17.25 # available in environ['pylons.routes_dict']
17.26 return WSGIController.__call__(self, environ, start_response)
17.27 -
17.28 -# Include the '_' function in the public names
17.29 -__all__ = [__name for __name in locals().keys() if not __name.startswith('_') \
17.30 - or __name == '_']
18.1 --- a/examples/samplepylons/samplepylons/lib/helpers.py Fri Aug 07 18:14:37 2009 +0200
18.2 +++ b/examples/samplepylons/samplepylons/lib/helpers.py Wed Feb 03 23:20:47 2010 +0100
18.3 @@ -1,6 +1,9 @@
18.4 """Helper functions
18.5
18.6 Consists of functions to typically be used within templates, but also
18.7 -available to Controllers. This module is available to both as 'h'.
18.8 +available to Controllers. This module is available to templates as 'h'.
18.9 """
18.10 -from webhelpers import *
18.11 +# Import helpers as desired, or define your own, ie:
18.12 +#from webhelpers.html.tags import checkbox, password
18.13 +from webhelpers.rails.asset_tag import javascript_include_tag
18.14 +from webhelpers.rails.javascript import javascript_tag
19.1 --- a/examples/samplepylons/samplepylons/templates/index.mak Fri Aug 07 18:14:37 2009 +0200
19.2 +++ b/examples/samplepylons/samplepylons/templates/index.mak Wed Feb 03 23:20:47 2010 +0100
19.3 @@ -14,13 +14,13 @@
19.4 a:visited { color: #666; }
19.5 a:hover { color: #fff; background-color:#000; }
19.6 </style>
19.7 - ${h.javascript_include_tag('/gp.fileupload.static/jquery.js')}
19.8 + ${h.javascript_include_tag('/gp.fileupload.static/jquery.js')|n}
19.9 ${h.javascript_tag('''
19.10 jQuery(document).ready(function() {
19.11 jQuery("form[enctype^='multipart/form-data']").fileUpload();
19.12 jQuery("#sample").fileUpload({action: "/upload/save"});
19.13 });
19.14 - ''')}
19.15 + ''')|n}
19.16
19.17 </head>
19.18 <body>
20.1 --- a/examples/samplepylons/samplepylons/tests/__init__.py Fri Aug 07 18:14:37 2009 +0200
20.2 +++ b/examples/samplepylons/samplepylons/tests/__init__.py Wed Feb 03 23:20:47 2010 +0100
20.3 @@ -1,40 +1,36 @@
20.4 """Pylons application test package
20.5
20.6 -When the test runner finds and executes tests within this directory,
20.7 -this file will be loaded to setup the test environment.
20.8 +This package assumes the Pylons environment is already loaded, such as
20.9 +when this script is imported from the `nosetests --with-pylons=test.ini`
20.10 +command.
20.11
20.12 -It registers the root directory of the project in sys.path and
20.13 -pkg_resources, in case the project hasn't been installed with
20.14 -setuptools. It also initializes the application via websetup (paster
20.15 -setup-app) with the project's test.ini configuration file.
20.16 +This module initializes the application via ``websetup`` (`paster
20.17 +setup-app`) and provides the base testing objects.
20.18 """
20.19 -import os
20.20 -import sys
20.21 from unittest import TestCase
20.22
20.23 -import pkg_resources
20.24 -import paste.fixture
20.25 -import paste.script.appinstall
20.26 from paste.deploy import loadapp
20.27 -from routes import url_for
20.28 +from paste.script.appinstall import SetupCommand
20.29 +from pylons import config, url
20.30 +from routes.util import URLGenerator
20.31 +from webtest import TestApp
20.32
20.33 -__all__ = ['url_for', 'TestController']
20.34 +import pylons.test
20.35
20.36 -here_dir = os.path.dirname(os.path.abspath(__file__))
20.37 -conf_dir = os.path.dirname(os.path.dirname(here_dir))
20.38 +__all__ = ['environ', 'url', 'TestController']
20.39
20.40 -sys.path.insert(0, conf_dir)
20.41 -pkg_resources.working_set.add_entry(conf_dir)
20.42 -pkg_resources.require('Paste')
20.43 -pkg_resources.require('PasteScript')
20.44 +# Invoke websetup with the current config file
20.45 +SetupCommand('setup-app').run([config['__file__']])
20.46
20.47 -test_file = os.path.join(conf_dir, 'test.ini')
20.48 -cmd = paste.script.appinstall.SetupCommand('setup-app')
20.49 -cmd.run([test_file])
20.50 +environ = {}
20.51
20.52 class TestController(TestCase):
20.53
20.54 def __init__(self, *args, **kwargs):
20.55 - wsgiapp = loadapp('config:test.ini', relative_to=conf_dir)
20.56 - self.app = paste.fixture.TestApp(wsgiapp)
20.57 + if pylons.test.pylonsapp:
20.58 + wsgiapp = pylons.test.pylonsapp
20.59 + else:
20.60 + wsgiapp = loadapp('config:%s' % config['__file__'])
20.61 + self.app = TestApp(wsgiapp)
20.62 + url._push_object(URLGenerator(config['routes.map'], environ))
20.63 TestCase.__init__(self, *args, **kwargs)
21.1 --- a/examples/samplepylons/samplepylons/websetup.py Fri Aug 07 18:14:37 2009 +0200
21.2 +++ b/examples/samplepylons/samplepylons/websetup.py Wed Feb 03 23:20:47 2010 +0100
21.3 @@ -1,14 +1,10 @@
21.4 """Setup the samplepylons application"""
21.5 import logging
21.6
21.7 -from paste.deploy import appconfig
21.8 -from pylons import config
21.9 -
21.10 from samplepylons.config.environment import load_environment
21.11
21.12 log = logging.getLogger(__name__)
21.13
21.14 -def setup_config(command, filename, section, vars):
21.15 +def setup_app(command, conf, vars):
21.16 """Place any commands to setup samplepylons here"""
21.17 - conf = appconfig('config:' + filename)
21.18 load_environment(conf.global_conf, conf.local_conf)
22.1 --- a/examples/samplepylons/setup.cfg Fri Aug 07 18:14:37 2009 +0200
22.2 +++ b/examples/samplepylons/setup.cfg Wed Feb 03 23:20:47 2010 +0100
22.3 @@ -5,36 +5,8 @@
22.4 [easy_install]
22.5 find_links = http://www.pylonshq.com/download/
22.6
22.7 -[pudge]
22.8 -theme = pythonpaste.org
22.9 -
22.10 -# Add extra doc files here with spaces between them
22.11 -docs = docs/index.txt
22.12 -
22.13 -# Doc Settings
22.14 -doc_base = docs/
22.15 -dest = docs/html
22.16 -
22.17 -# Add extra modules here separated with commas
22.18 -modules = samplepylons
22.19 -title = Samplepylons
22.20 -organization = Pylons
22.21 -
22.22 -# Highlight code-block sections with Pygments
22.23 -highlighter = pygments
22.24 -
22.25 -# Optionally add extra links
22.26 -#organization_url = http://pylonshq.com/
22.27 -#trac_url = http://pylonshq.com/project
22.28 -settings = no_about=true
22.29 -
22.30 -# Optionally add extra settings
22.31 -# link1=/community/ Community
22.32 -# link2=/download/ Download
22.33 -
22.34 -[publish]
22.35 -doc-dir=docs/html
22.36 -make-dirs=1
22.37 +[nosetests]
22.38 +with-pylons = test.ini
22.39
22.40 # Babel configuration
22.41 [compile_catalog]
23.1 --- a/examples/samplepylons/setup.py Fri Aug 07 18:14:37 2009 +0200
23.2 +++ b/examples/samplepylons/setup.py Wed Feb 03 23:20:47 2010 +0100
23.3 @@ -7,20 +7,25 @@
23.4
23.5 setup(
23.6 name='samplepylons',
23.7 - version="",
23.8 - #description='',
23.9 - #author='',
23.10 - #author_email='',
23.11 - #url='',
23.12 - install_requires=["Pylons>=0.9.6.2"],
23.13 + version='0.1',
23.14 + description='',
23.15 + author='',
23.16 + author_email='',
23.17 + url='',
23.18 + install_requires=[
23.19 + "Pylons>=0.9.7rc6",
23.20 + ],
23.21 + setup_requires=["PasteScript>=1.6.3"],
23.22 packages=find_packages(exclude=['ez_setup']),
23.23 include_package_data=True,
23.24 test_suite='nose.collector',
23.25 package_data={'samplepylons': ['i18n/*/LC_MESSAGES/*.mo']},
23.26 - #message_extractors = {'samplepylons': [
23.27 + #message_extractors={'samplepylons': [
23.28 # ('**.py', 'python', None),
23.29 - # ('templates/**.mako', 'mako', None),
23.30 + # ('templates/**.mako', 'mako', {'input_encoding': 'utf-8'}),
23.31 # ('public/**', 'ignore', None)]},
23.32 + zip_safe=False,
23.33 + paster_plugins=['PasteScript', 'Pylons'],
23.34 entry_points="""
23.35 [paste.app_factory]
23.36 main = samplepylons.config.middleware:make_app
24.1 --- a/examples/samplepylons/test.ini Fri Aug 07 18:14:37 2009 +0200
24.2 +++ b/examples/samplepylons/test.ini Wed Feb 03 23:20:47 2010 +0100
24.3 @@ -12,7 +12,7 @@
24.4
24.5 [server:main]
24.6 use = egg:Paste#http
24.7 -host = 0.0.0.0
24.8 +host = 127.0.0.1
24.9 port = 5000
24.10
24.11 [app:main]
25.1 --- a/gp/fileupload/static/jquery.fileupload.js Fri Aug 07 18:14:37 2009 +0200
25.2 +++ b/gp/fileupload/static/jquery.fileupload.js Wed Feb 03 23:20:47 2010 +0100
25.3 @@ -11,6 +11,7 @@
25.4 $.fn.fileUpload = function(options) {
25.5
25.6 // default settings
25.7 + var action = document.location.href.split('#')[0].split('?')[0];
25.8 var settings = $.extend({
25.9 replace_existing_form: false,
25.10 add_submit: true,
25.11 @@ -20,12 +21,12 @@
25.12 field_name: 'file',
25.13 submit_empty_forms: true,
25.14 use_iframes: true,
25.15 - stat_url: './gp.fileupload.stat/',
25.16 + stat_url: action+'/gp.fileupload.stat/',
25.17 stat_delay: 1500,
25.18 stat_timeout: 7000,
25.19 success: function() {},
25.20 error: function() {},
25.21 - action: window.location.href.split('#')[0].split('?')[0]
25.22 + action: action
25.23 }, options);
25.24
25.25 // console logging
26.1 --- a/gp/fileupload/storage.py Fri Aug 07 18:14:37 2009 +0200
26.2 +++ b/gp/fileupload/storage.py Wed Feb 03 23:20:47 2010 +0100
26.3 @@ -104,7 +104,7 @@
26.4 # need to consume so see how many block we have to read
26.5 length = req.content_length
26.6 if length > self.max_size:
26.7 - return exc.HTTPServerError('File is to big')
26.8 + return exc.HTTPServerError('File is too big')
26.9
26.10 bsize = 1024
26.11 if length < bsize:
26.12 @@ -203,10 +203,12 @@
26.13
26.14 resp = req.get_response(self.application)
26.15
26.16 - # if no status set, the operation failed. (unauthorised, error, etc.)
26.17 - # delete the file
26.18 + # We have to test the response status.
26.19 + # 2XX and 3XX status as successes.
26.20 + # Clients error or Servers error (4XX and 5XX)
26.21 + # will trigger the file deletion.
26.22 status = resp.status.split()[0]
26.23 - if status != '200':
26.24 + if status[0] not in '23':
26.25 for f,n,p in files:
26.26 os.remove(p)
26.27
27.1 --- a/gp/fileupload/tests.py Fri Aug 07 18:14:37 2009 +0200
27.2 +++ b/gp/fileupload/tests.py Wed Feb 03 23:20:47 2010 +0100
27.3 @@ -113,7 +113,7 @@
27.4 response = app.post('/?gp.fileupload.id=1',
27.5 upload_files=(('test_file', 'test.txt', '_'*500),))
27.6 except Exception, e:
27.7 - assert 'File is to big' in str(e), str(e)
27.8 + assert 'File is too big' in str(e), str(e)
27.9
27.10 @with_setup(setup_func, teardown_func)
27.11 def test_storage():
27.12 @@ -152,7 +152,7 @@
27.13 response = req.get_response(app)
27.14
27.15 # check correct output
27.16 - assert 'var test = null;' in response.body, output
27.17 + assert 'var test = null;' in response.body, response.body
27.18
27.19 # check temp files
27.20 tempfiles = glob.glob(os.path.join(TEMP_DIR, '*.dump'))
27.21 @@ -163,7 +163,7 @@
27.22 response = TestApp(app).post('/?gp.fileupload.id=1',
27.23 upload_files=(('test_file', 'test.txt', '_'*500),))
27.24 except Exception, e:
27.25 - assert 'File is to big' in str(e), str(e)
27.26 + assert 'File is too big' in str(e), str(e)
27.27
27.28 ###############
27.29 ## Doc tests ##
28.1 --- a/gp/fileupload/upload.py Fri Aug 07 18:14:37 2009 +0200
28.2 +++ b/gp/fileupload/upload.py Wed Feb 03 23:20:47 2010 +0100
28.3 @@ -126,7 +126,7 @@
28.4 sfile = open(statfile, 'w')
28.5 sfile.write('-1')
28.6 sfile.close()
28.7 - return exc.HTTPServerError('File is to big')
28.8 + return exc.HTTPServerError('File is too big')
28.9
28.10 log.debug('Start session "%s", length: %s', session, length)
28.11
28.12 @@ -195,7 +195,7 @@
28.13 resp.body = str(data)
28.14 return resp
28.15
28.16 -def make_app(application, global_conf, tempdir=None, max_size=None,
28.17 +def make_app(application, global_conf, tempdir=None, max_size=0,
28.18 upload_to=None, exclude_paths=None, include_files=None):
28.19 """build a FileUpload application
28.20 """
28.21 @@ -213,7 +213,8 @@
28.22 else:
28.23 if isinstance(exclude_paths, basestring):
28.24 exclude_paths = [f for f in exclude_paths.split(' ') if f]
28.25 - application = Storage(application, upload_to, tempdir, exclude_paths)
28.26 + application = Storage(application, upload_to, tempdir, exclude_paths,
28.27 + max_size)
28.28
28.29 if include_files:
28.30 if isinstance(include_files, basestring):
28.31 @@ -221,4 +222,3 @@
28.32 application = ResourceInjection(application, include_files)
28.33
28.34 return FileUpload(application, tempdir=tempdir, max_size=max_size)
28.35 -
29.1 --- a/setup.py Fri Aug 07 18:14:37 2009 +0200
29.2 +++ b/setup.py Wed Feb 03 23:20:47 2010 +0100
29.3 @@ -4,7 +4,7 @@
29.4 from setuptools import setup, find_packages
29.5 import sys, os
29.6
29.7 -version = '0.7'
29.8 +version = '0.8'
29.9
29.10 long_description = ''
29.11 long_description += open('README.txt').read()
29.12 @@ -41,10 +41,11 @@
29.13 keywords='wsgi middleware upload progress bar',
29.14 author='Gael Pasgrimaud',
29.15 author_email='gael@gawel.org',
29.16 - url='http://www.gawel.org',
29.17 + url='http://www.gawel.org/docs/gp.fileupload/',
29.18 license='MIT',
29.19 namespace_packages=['gp'],
29.20 packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
29.21 + package_data={'gp/fileupload': ['static/*',]},
29.22 include_package_data=True,
29.23 zip_safe=False,
29.24 install_requires=[