Showing preview only (1,209K chars total). Download the full file or copy to clipboard to get everything.
Repository: Pylons/pylons
Branch: master
Commit: 8625d5af7905
Files: 231
Total size: 1.1 MB
Directory structure:
gitextract_jwapr307/
├── .gitignore
├── .hgignore
├── .hgtags
├── .travis.yml
├── CHANGELOG
├── LICENSE
├── MANIFEST.in
├── README.rst
├── UPGRADING
├── ez_setup.py
├── pylons/
│ ├── __init__.py
│ ├── commands.py
│ ├── configuration.py
│ ├── controllers/
│ │ ├── __init__.py
│ │ ├── core.py
│ │ ├── jsonrpc.py
│ │ ├── util.py
│ │ └── xmlrpc.py
│ ├── decorators/
│ │ ├── __init__.py
│ │ ├── cache.py
│ │ ├── rest.py
│ │ ├── secure.py
│ │ └── util.py
│ ├── docs/
│ │ ├── en/
│ │ │ ├── .gitignore
│ │ │ ├── Makefile
│ │ │ ├── _oldstatic/
│ │ │ │ ├── akhet.css
│ │ │ │ ├── default.css
│ │ │ │ ├── pygments.css
│ │ │ │ └── pylons_as_onion.ai
│ │ │ ├── _oldtemplates/
│ │ │ │ ├── genindex.html
│ │ │ │ ├── layout.html
│ │ │ │ ├── modindex.html
│ │ │ │ └── page.html
│ │ │ ├── advanced_models.rst
│ │ │ ├── advanced_pylons/
│ │ │ │ ├── creating_paste_templates.rst
│ │ │ │ ├── entry_points_and_plugins.rst
│ │ │ │ ├── index.rst
│ │ │ │ ├── paster.rst
│ │ │ │ └── paster_commands.rst
│ │ │ ├── caching.rst
│ │ │ ├── concepts.rst
│ │ │ ├── conf.py
│ │ │ ├── configuration.rst
│ │ │ ├── controllers.rst
│ │ │ ├── debugging.rst
│ │ │ ├── deployment.rst
│ │ │ ├── events.rst
│ │ │ ├── execution.rst
│ │ │ ├── forms.rst
│ │ │ ├── gettingstarted.rst
│ │ │ ├── glossary.rst
│ │ │ ├── helpers.rst
│ │ │ ├── i18n.rst
│ │ │ ├── index.rst
│ │ │ ├── jython.rst
│ │ │ ├── logging.rst
│ │ │ ├── models.rst
│ │ │ ├── modules/
│ │ │ │ ├── commands.rst
│ │ │ │ ├── configuration.rst
│ │ │ │ ├── controllers.rst
│ │ │ │ ├── controllers_core.rst
│ │ │ │ ├── controllers_util.rst
│ │ │ │ ├── controllers_xmlrpc.rst
│ │ │ │ ├── decorators.rst
│ │ │ │ ├── decorators_cache.rst
│ │ │ │ ├── decorators_rest.rst
│ │ │ │ ├── decorators_secure.rst
│ │ │ │ ├── error.rst
│ │ │ │ ├── i18n_translation.rst
│ │ │ │ ├── index.rst
│ │ │ │ ├── log.rst
│ │ │ │ ├── middleware.rst
│ │ │ │ ├── templating.rst
│ │ │ │ ├── test.rst
│ │ │ │ ├── util.rst
│ │ │ │ └── wsgiapp.rst
│ │ │ ├── objects.inv
│ │ │ ├── python23_install.rst
│ │ │ ├── security_policy_for_bugs.rst
│ │ │ ├── sessions.rst
│ │ │ ├── testing.rst
│ │ │ ├── thirdparty/
│ │ │ │ ├── formencode_api.rst
│ │ │ │ ├── index.rst
│ │ │ │ ├── weberror.rst
│ │ │ │ ├── webob.rst
│ │ │ │ └── webtest.rst
│ │ │ ├── tutorials/
│ │ │ │ ├── index.rst
│ │ │ │ ├── quickwiki_tutorial.rst
│ │ │ │ └── understanding_unicode.rst
│ │ │ ├── upgrading.rst
│ │ │ ├── views.rst
│ │ │ ├── windowsnotes.rst
│ │ │ └── wsgi_support.rst
│ │ └── uploader.py
│ ├── error.py
│ ├── i18n/
│ │ ├── __init__.py
│ │ └── translation.py
│ ├── log.py
│ ├── media/
│ │ ├── javascripts/
│ │ │ └── traceback.js
│ │ └── style/
│ │ ├── black.css
│ │ ├── itraceback.css
│ │ └── orange.css
│ ├── middleware.py
│ ├── templates/
│ │ ├── __init__.py
│ │ ├── controller.py_tmpl
│ │ ├── default_project/
│ │ │ ├── +package+/
│ │ │ │ ├── __init__.py_tmpl
│ │ │ │ ├── config/
│ │ │ │ │ ├── __init__.py_tmpl
│ │ │ │ │ ├── deployment.ini_tmpl_tmpl
│ │ │ │ │ ├── environment.py_tmpl
│ │ │ │ │ ├── middleware.py_tmpl
│ │ │ │ │ └── routing.py_tmpl
│ │ │ │ ├── controllers/
│ │ │ │ │ ├── __init__.py_tmpl
│ │ │ │ │ └── error.py_tmpl
│ │ │ │ ├── lib/
│ │ │ │ │ ├── __init__.py_tmpl
│ │ │ │ │ ├── app_globals.py_tmpl
│ │ │ │ │ ├── base.py_tmpl
│ │ │ │ │ └── helpers.py_tmpl
│ │ │ │ ├── model/
│ │ │ │ │ ├── __init__.py_tmpl
│ │ │ │ │ └── meta.py_tmpl
│ │ │ │ ├── public/
│ │ │ │ │ └── index.html_tmpl
│ │ │ │ ├── templates/
│ │ │ │ │ ├── .distutils_placeholder
│ │ │ │ │ └── __init__.py_tmpl
│ │ │ │ ├── tests/
│ │ │ │ │ ├── __init__.py_tmpl
│ │ │ │ │ ├── functional/
│ │ │ │ │ │ └── __init__.py_tmpl
│ │ │ │ │ └── test_models.py_tmpl
│ │ │ │ └── websetup.py_tmpl
│ │ │ ├── MANIFEST.in_tmpl
│ │ │ ├── README.txt_tmpl
│ │ │ ├── development.ini_tmpl
│ │ │ ├── ez_setup.py
│ │ │ ├── setup.cfg_tmpl
│ │ │ ├── setup.py_tmpl
│ │ │ └── test.ini_tmpl
│ │ ├── minimal_project/
│ │ │ ├── +package+/
│ │ │ │ ├── __init__.py_tmpl
│ │ │ │ ├── config/
│ │ │ │ │ └── deployment.ini_tmpl_tmpl
│ │ │ │ ├── controllers/
│ │ │ │ │ └── __init__.py_tmpl
│ │ │ │ ├── helpers.py_tmpl
│ │ │ │ ├── public/
│ │ │ │ │ └── index.html_tmpl
│ │ │ │ ├── routing.py_tmpl
│ │ │ │ ├── templates/
│ │ │ │ │ ├── .distutils_placeholder
│ │ │ │ │ └── __init__.py_tmpl
│ │ │ │ ├── tests/
│ │ │ │ │ └── __init__.py_tmpl
│ │ │ │ └── wsgiapp.py_tmpl
│ │ │ ├── MANIFEST.in_tmpl
│ │ │ ├── README.txt_tmpl
│ │ │ ├── development.ini_tmpl
│ │ │ ├── ez_setup.py
│ │ │ ├── setup.cfg_tmpl
│ │ │ ├── setup.py_tmpl
│ │ │ └── test.ini_tmpl
│ │ ├── restcontroller.py_tmpl
│ │ ├── test_controller.py_tmpl
│ │ └── test_restcontroller.py_tmpl
│ ├── templating.py
│ ├── test.py
│ ├── testutil.py
│ ├── url.py
│ ├── util.py
│ └── wsgiapp.py
├── rtd.txt
├── scripts/
│ ├── gen-go-pylons.py
│ ├── go-pylons.py
│ └── pylintrc
├── setup.cfg
├── setup.py
├── test_files/
│ ├── __init__.py
│ ├── event_file.py
│ └── sample_controllers/
│ ├── __init__.py
│ ├── controllers/
│ │ ├── __init__.py
│ │ ├── goodbye.py
│ │ ├── hello.py
│ │ └── i18nc.py
│ ├── i18n/
│ │ ├── es/
│ │ │ └── LC_MESSAGES/
│ │ │ ├── sample_controllers.mo
│ │ │ └── sample_controllers.po
│ │ ├── fr/
│ │ │ └── LC_MESSAGES/
│ │ │ ├── sample_controllers.mo
│ │ │ └── sample_controllers.po
│ │ └── ja/
│ │ └── LC_MESSAGES/
│ │ ├── sample_controllers.mo
│ │ └── sample_controllers.po
│ └── templates/
│ ├── hello.html
│ └── time.html
└── tests/
├── __init__.py
├── conftest.py
├── test_units/
│ ├── __init__.py
│ ├── test_basic_app.py
│ ├── test_controller.py
│ ├── test_decorator_authenticate_form.py
│ ├── test_decorator_cache.py
│ ├── test_decorator_https.py
│ ├── test_decorator_jsonify.py
│ ├── test_decorator_validate.py
│ ├── test_helpers.py
│ ├── test_i18n.py
│ ├── test_jsonrpc.py
│ ├── test_middleware.py
│ ├── test_templating.py
│ └── test_xmlrpc.py
└── test_webapps/
├── __init__.py
├── filestotest/
│ ├── app_globals.py
│ ├── base_with_xmlrpc.py
│ ├── cache_controller.py
│ ├── controller_sample.py
│ ├── controller_sqlatest.py
│ ├── controller_xmlrpc.py
│ ├── development.ini
│ ├── development_sqlatesting.ini
│ ├── environment_def_engine.py
│ ├── environment_def_sqlamodel.py
│ ├── functional_controller_cache_decorator.py
│ ├── functional_controller_xmlrpc.py
│ ├── functional_sample_controller_i18n.py
│ ├── functional_sample_controller_jinja2.py
│ ├── functional_sample_controller_mako.py
│ ├── functional_sample_controller_sample1.py
│ ├── functional_sample_controller_sample2.py
│ ├── functional_sample_controller_sample3.py
│ ├── functional_sample_controller_sample4.py
│ ├── functional_sample_controller_sqlatesting.py
│ ├── helpers_sample.py
│ ├── messages.ja.mo
│ ├── messages.ja.po
│ ├── messages.pot
│ ├── middleware_mako.py
│ ├── model__init__.py
│ ├── rest_routing.py
│ ├── test_mako.html
│ ├── test_sqlalchemy.html
│ ├── testgenshi.html
│ ├── testjinja2.html
│ ├── tests__init__.py
│ └── websetup.py
└── test_make_project.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.pyc
*.egg-info
*.egg
tests/test_units/cache/
tests/test_units/session/
================================================
FILE: .hgignore
================================================
# Automatically generated by `hgimportsvn`
syntax:glob
*.DS_Store
.svn
.coverage
*.pyc
*.egg-info
*.egg
ez_setup
pylons/docs/*/_build
container_file
container_dbm*
*~
build/
dist/
docs/html/docs
output/ProjectName
tests/html_coverage
syntax: glob
================================================
FILE: .hgtags
================================================
b7002f68d541940f32fa5d5fecb83483008fd489 v0.9.6
88112f696d4aba81405753713ca06070a92ebcf9 v0.9.5
1bc21f0b2820a39801278b322aab939da893ed4d v0.9.4.1
a8e89fafa6d836c5ec9de712db4afd68acd02b30 v0.9.4
896da05e4c2679f39756194d65c3e87eb92bc2f1 v0.9.3
a71e37726e2909c358a6fb699f26a314643d1c89 v0.9.2
37614170faa944723382bf885023085bc3ece616 v0.9.1
f650ccf099785af6be11d3e91f66e4dc5178dc1b v0.9
0da35cd7624a67c43948c00f60b35eb9202e2b8d v0.8.2
0fa5a7b12de0795c95a425e89d802f09e8e709ab v0.8.1
1880858f1fb30fbf4b1717ac49d172712dfc5b9d v0.8
9e6916dca073e83deb25ed401a928e834bc0d262 v0.9.6rc2
f2b68bd9f177d08f8caf7e5d33629190d097fbc0 v0.9.6rc1
f04d465aa10861b96c1050a4c6347c4aa12247c1 v0.9.6rc3
a7749485525a8aade8dbe089abae9a539af24682 v0.9.7beta1
46c5edc17b643e07158dc4c6b5e14a7d839fe066 v0.9.7beta1
9cb761f0f0476dad15b370765919ae96a968fea4 v0.9.7beta2
3819db8d2307f8f5725b2a27c6a34e8f5738d687 v0.9.7beta3
e546c53613c2c0647ab94ee0d376a5bc8e28dcb4 v0.9.7beta5
ca3cbefec25e0e9ec7b579123cf97ed98934ccd8 v0.9.7rc1
a6f56791a83a53db7a7484fb8bd8821ffba740c4 v0.9.7rc2
7ceef102aff2cce44634132d21638358b4129197 v0.9.7rc3
4a94734906711e56f9d34a34527f4b8a6e9811a8 v0.9.7rc4
fa5aad0d57deb99f8a25596e9c7d601b1ced1d5d v0.9.7rc5
e7a19deba3f66b4e6dfc050f070295a0a622308a v0.9.7rc6
2154554f4ffb458555023afd6e810ce88e58e64b v0.9.7
165565778a3c518d6b5c383095fffdf6e154fa78 v0.10b1
25eb46de0380e20799c419557a86c61f144101a2 v1.0b1
cd08f0df626b89f3e6ee9df71539e009d9be1ba9 v0.10rc1
================================================
FILE: .travis.yml
================================================
language: python
python:
- "2.6"
- "2.7"
install:
- python setup.py develop
script:
- python setup.py test
================================================
FILE: CHANGELOG
================================================
Pylons Changelog
================
1.0.2 (July 21, 2015)
* In the event of a NilAccept for the language, request.languages() would
throw an AttributeError exception. Fixes #24.
* Encode Location HTTP header in redirect responses in UTF-8. Per
RFC 3987. Refers to #15.
* Remove "Post Traceback" as it was a possible XSS vector with prior versions
of WebError, and the PylonsHQ site is no longer in existence to support them.
1.0.1 (August 13th, 2012)
* No changes since RC1.
1.0.1RC1 (December 12, 2011)
* WARNING: pylons.lib.decorators has had two functions removed:
``determine_response_charset`` and ``encode_formencode_errors``.
* Updated dependencies to latest versions of Paste, PasteDeploy, and
compatibility for the latest WebOb 1.2 betas.
* authenticate_form allows for GET. Patch by Domen Kožar.
* jsonify now properly sets charset to utf-8.
* Add ability for jsonify to handle objects with a __json__ attribute using
custom JSONEncoder class similar to TG2. Patch by Bob Farrell.
* Added ability for __before__ to reference a callable function. Patch
contributed by mverdone.
* Pulled in JSON-RPC support from agentultra's pylons fork.
* Apply patch for proper pylons.__version__ under Windows. Contributed by
Christoph Zwerschke.
* Utilize MarkupSafe for faster HTML escaping.
* Fix signed cookies by using standard base64 alphabet, and prevent timing
attacks on signature comparison.
* Added setup of app_globals and config to Pylons config.init_app to ensure
as long as the Pylons application is loaded, the app_globals and config
will be appropriately initialized.
* Documentation updates.
1.0 (May 27, 2010)
* Minor tweak to allow proper importing of pylons.
1.0RC1 (March 1, 2010)
* Switched to using Routes 1.12 with support for no longer using the odd
routes singleton.
* Removed pylons.middleware.StaticJavascripts, this is not used anymore.
* Added more unit tests.
1.0b1 (February 5, 2010)
* Removed CacheMiddleware. cache object is now setup as an attribute on the
app_globals object for use where needed.
* WARNING: config only supports dict access
* WARNING: Method arguments no longer assigned to 'tmpl_context' by default.
* WARNING: Changed default to strict_tmpl_context.
* WARNING: Removed legacy pylons.c and pylons.g globals.
* WARNING: Removed legacy pylons.database module.
* WARNING: Removed legacy pylons.config module.
* WARNING: Removed Buffet options, setup, and legacy render/render_response
function from pylons.templating. This also means config no longer accepts
the add_template_engine option.
* WARNING: Removed legacy redirect_to function.
* WARNING: @https decorator no longer accepts url_for-like arguments.
* Add a "paster routes" command. This prints the mapper, which from Routes
1.12 onwards gives sensibly formatted output.
* Fix unit tests on Windows
* Prepare for Routes 1.12, ensure tests don't assume implicit routing
0.10 (May 27, 2010)
* Fix legacy warning replacement.
0.10RC1 (March 1, 2010)
* No changes to Pylons core since b1.
0.10b1 (February 5, 2010)
* redirect_to is now deprecated, use redirect(url(*args, **kwargs)) instead.
* url_for like args to the https decorator are now deprecated, pass it a url
or a callable returning a url instead.
* Changed 1.0 deprecated pylons.c, pylons.g, pylons.buffet instances to
throw deprecation warnings.
* Fixed etag_cache matching when the If-None-Match header contains a comma
separated list of etags. Fixes #557. Thanks magicbronson.
* Added tests for restcontroller with sub-directory, and fixed generated unit
tests. Patches supplied by Michael van Tellingen, fixes #571.
* Retain the original controller exception when thrown under
environ['pylons.controller.exception'] for use in the error controller.
* Fixed bug with unit tests running the app load twice during testing.
Fixes #620.
* Updated project templates to use actual config instance, rather than the
StackedObjectProxy classes.
* Changed PylonsConfig to be dict subclass, rather than DispatchingConfig
subclass.
0.9.7 (February 23, 2009)
* WARNING: A new option is available to determine whether or not an actions
arguments should be automatically attached to 'c'. To turn off this implicit
behavior in environment.py:
config['pylons.c_attach_args'] = False
This is set to True by default.
* WARNING: Fixed a minor security hole in the default Pylons error page that
could result in an XSS security hole.
* WARNING: Fixed a security hole in the default project template to use the
StaticURLParser to ensure arbitrary files can't be sent.
* WARNING: Refactored PylonsApp to remove legacy PylonsApp, moved
session/cache and routes middleware into the project template. This will
require projects to be updated to include those 3 middleware in the projects
middleware.py.
* Added redirect, preferred over redirect_to. Takes an explicit url instead of
url_for like arguments
* Changed to using WebTest instead of paste.fixture for app testing.
* Added render_mako_def to render def blocks within a mako template.
* Changes to cache_decorator and cached_template to support Beaker API
changes in version 1.1. 1.0.3 is still supported.
* Fix HEAD requests causing an Exception as if no content was returned
by the controller. Fixes #507. Thanks mvtellingen, Petr Kobalicek.
* Fix a crash when returning the result of ``etag_cache`` in a controller.
Fixes #508.
* "response" flag has been removed from pylons.decorators.cache.beaker_cache,
as it sends all headers along unconditionally including cookies;
additionally, the flag was taking effect in all cases previously
so prior versions of beaker_cache are not secure.
In its place, a new option "cache_headers" is provided, which is a
tuple of specific header names to be cached. It defaults
to ('content-type','content-length').
* "invalidate_on_startup" flag added to beaker_cache, which provides a
"starttime" to the cache such that when the application is started
or restarted, the cache entry is invalidated.
* Updating host to use 127.0.0.1 for development binding.
* Added option to specify the controller name with a __controller__ variable
in the controller's module. This name will be used for the controller class
rather than the default naming scheme.
* setup.py egg_info now restores projects' paster_plugins.txt,
allowing paster shell to work again after the egg-info directory was
lost. fixes #282. Thanks sevkin.
* The paste_deploy_config.ini_tmpl template is now located at
package/config/deployment.ini_tmpl for new projects.
* Project's default test fixtures no longer hardcode test.ini; the ini
file used can now be specified via the nosetests --with-pylons
argument (defaults to test.ini in setup.cfg). fixes #400.
* @validate now defaults to translating FormEncode error messages via
Pylons' gettext catalog, then falls back to FormEncode's. fixes #296.
Thanks Max Ischenko.
* Fixed SQLAlchemy logging not working in paster shell. Fixes #363. Thanks
Christoph Haas.
* Added optionally engine initialization, to prevent Buffet from loading
if there's no 'buffet.template_engines' in the config.
* Updated minimal template to work with Tempita and other new templating
changes.
* Fixed websetup to parse location config file properly when the section
isn't 'main'. Fixes #399.
* Added default Mako filter of escape for all template rendering.
* Fixed template for Session.remove inclusion when using SA. Fixed
render_genshi to properly use fragment/format options. Thanks Antonin
Enfrun.
* Remove template engine from load_environment call.
* Removing template controller from projects. Fixes #383.
* Added signed_cookie method to WebOb Request/Response sub-classes.
* Updated project template to setup appropriate template loader and controller
template to doc how to import render.
* Added documentation for render functions in pylons.templating.
* Adding specific render functions that don't require Buffet.
* Added forward controller.util function for forwarding the request to WSGI
apps. Fixes #355.
* Added default input encoding for Mako to utf-8. Suggested in #348.
* Fixed paster controller to raise an error if the controller for it already
exists. Fixes #279.
* Added __init__.py to template dir in project template if the template engine
is genshi or kid. Fixes #353.
* Fixed jsonify to use application/json as its the proper mime-type and now
used all over the net.
* Fixed minimal template not replacing variables properly. Fixes #377.
* Fixed @validate decorator to no longer catch exceptions should they be
raised in the action that is supposed to display a form. Fixes #374.
* Fixed paster shell command to no longer search for egg_info dir. Allows
usage of paster shell with installed packages. Suggested by Gavin Carothers.
* Added mimetype function and MIMETypes class for registering mimetypes.
* WARNING: Usage of pylons.Response is now deprecated. Please use
pylons.response instead.
* Removed use of WSGIRequest/WSGIResponse and replaced with WebOb subclasses
that implement methods to make it backwards compatible with the Paste
wsgiwrappers.
* Fixed missing import in template controller.
* Deprecated function uses string substitution to avoid Nonetype error when
Python optimization is on. Fixes #334.
* E-tag cache no longer returns Content-Type in the headers. Fixes #323.
* XMLRPCController now properly includes the Content-Length of the response.
Fixes #310, thanks Nicholas.
* Added SQLAlchemy option to template, which adds SQLAlchemy setup to the
project template.
* Switched project templating to use Tempita.
* Updated abort/redirect_to to use appropriate Response object when WebOb is
used.
* Updated so that 404's properly return as Response objects when WebOb is in
use instead of WSGIResponse.
* Added beaker_cache option to avoid caching/restoring global Response values
that were present during the first cache operation.
* Adding StatusCodeRedirect to handle internal redirects based on the status
code returned by the app. This replaces the use of ErrorDocuments in
projects.
* Refactored error exceptions to use WebError.
* WSGIController now uses the environ references to response, request, and
the c object for higher performance.
* Added optional use of WebOb instead of paste.wsgiwrapper objects.
* Fixed bug with beaker_cache defaulting to dbm rather than the beaker
cache app-wide default.
* The --with-pylons nose plugin no longer requires a project to have been
registered with setuptools to work.
* The config object is now included in the template namespace.
* StaticJavascripts now accepts keyword arguments for StaticURLParser.
Suggested by Marcin Kasperski.
* Fix pylons.database.AutoConnectHub's doInTransaction not automatically
connecting when necessary. Fixes #327.
0.9.6.1 (September 27th, 2007)
* Fixed validate decorator to resume pre-0.9.6 behavior of only validating
POST requests by default. Added option to validate during GET as well and
a recursion avoidance check to prevent validate from running more than once.
* WARNING: Fixed a security hole allowing private controller methods (those
beginning with an underscore) to be accessed from the outside. Found by
Tomasz Nazar.
* Added nose plugin '--with-pylons=test.ini' option to load the Pylons app
before scanning for unit tests. This enables Pylons apps to be unit tested
with doc tests.
* PylonsBaseWSGIApp now caches controller lookup and the effective logging
level for a little better performance.
0.9.6 (September 8th, 2007)
* Updated requirements for newer WebHelpers for SQLAlchemy 0.4 compatibility.
Fixes #300.
* Fixed pylons.templating to not pull session objects if there are none in use
for the request. Thanks Bob Ippolito.
* Catch UnicodeEncodeErrors when finding the Controller action method and fail
gracefully. Thanks max. Fixes #298.
* Allow passing of a state keyword to the validate decorator for the
to_python methods. Fixes #297.
* paster shell now configures logging from the config file, like paster serve
and setup-app. This can be disabled via the -q option. Thanks Yannick
Gingras.
0.9.6rc3 (August 18, 2007)
* Fixed controllers.core to allow responses of None (empty bodies). Logs a
message indicating the response was empty.
* pylons.helpers has been moved to pylons.controllers.util, to differentiate
between controller utility functions and projects' helpers modules.
* Fixed non-basestring/generator/WSGIResponse objects returned from
Controllers not being set as the response content. Thanks Alex Conrad.
* development.ini now configures the app's Logger level to DEBUG by default.
Thanks Christoph Haas
0.9.6rc2 (August 2, 2007)
* Projects now include a MANIFEST.in file: it directs distutils to recursively
include all files in the project's public/ and templates/ dir. This fixes
these dirs not being included in dists unless they were checked into an RCS
recognized by setuptools. This is at the expense of dists now globbing all
files in those dirs (even those not checked into your RCS). Thanks Christoph
Haas.
* Fixed the validate decorator not setting c.form_errors in certain
circumstances. Thanks max. Fixes #286.
* email_to lines commented out in development.ini and test.ini files to avoid
emails being sent to a non-existent address by mistake. If an error occurs
it is logged but no email is sent unless email_to is specified.
* [paste.app_factory] entry points changed to point to the actual make_app()
function to make it simpler for someone to work out how Pylons works (tests
updated accordingly too).
* All use of the ez_setup module is now tested by an ImportError to make
Pylons compatible with Buildout. Note: Tags and releases should be made
using an svn export and an svn add to ensure a real copy of the ez_setup
module is included and not just an svn:external so that the module is tied
to time of the release.
* More full-featured README.txt included.
* Updated beaker_cache to cache global response cookies/status/headers.
Fixes #280.
* Fixed missing abort name import in restrict rest decorator. Fixes #281.
* Added cheetah as a supported template language for template_engine option.
* Fixed public/ and templates/ directories not being created with paster
create.
0.9.6rc1 (July 15, 2007)
* Fixed cookie header addition to use add instead of append. Thanks to
anonymous patcher. Fixes #268, again.
* Added ability to pass _code option to specify the status code type for
redirect_to.
* Fixed redirect_to to not copy all headers into redirect for old _response
usage. Fixes #268.
* WARNING: By default, the Pylons request object now returns unicode
parameter (pylons.GET/POST/params) values (and assumes those parameters
were sent to Pylons as utf-8). Unicode parameters can cause major
problems if your application is not setup to handle unicode. To disable
unicode parameters (0.9.5 default behavior), add the following to your
load_environment function (0.9.6 syntax):
config['request_options']['charset'] = None
or, if still using the deprecated pre-0.9.6 pylons.config syntax, add:
request_settings = pylons.config.request_defaults.copy()
request_settings['charset'] = None
return pylons.config.Config(tmpl_options, map, paths,
request_settings=request_settings)
* WARNING: Template names beginning with a / (or the OS's path separator)
will now result in the name not having the separator's replaced with '.'s
for the template engine. This shouldn't affect most projects as they usually
assume a dot notation will be used with dot notation template engines (Kid,
Genshi, etc.). This change allows template engines that can take filename
paths to function properly. Fixes #233.
* WARNING: The pylons.util.get_prefix(environ) function is deprecated. Please
use:
environ.get('SCRIPT_NAME', '')
instead (the get_prefix function is used in the default ErrorController).
Fixes #243.
* WARNING: The paths dictionary's 'root_path' has moved to the less
redundant 'root'.
* Fixed the Error Documents/EvalException css referencing non-existent images.
Thanks Shannon -jj Behrens. Fixes #238.
* Added ability to pass _code option to specify the status code type for
redirect_to.
* Fixed redirect_to to not copy all headers into redirect for old _response
usage. Fixes #268.
* Added logging statements throughout Pylons code, added logging setup to
default template. Fixes #98.
* Refactored global response to be setup in wsgiapp along with the other
globals. Updated WSGIController to copy in global response headers and
cookies into a WSGI app's output.
* Added global pylons.response object. Thanks Shannon -jj Behrens and Damjan
Georgievski. Fixes #268 and #201.
* Updated default project template files for new configuration layout. Options
to handle config now just in environment.py, and middleware.py handling just
middleware. Fixes #203.
* Removing mako tests, as its now the default. Default test changed from
Myghty to Mako.
* Changing default templating to mako.
* Added the https decorator. It requires an action to be loaded via
https. Patch by ido. Fixes #241.
* Added upgrade instructions, and posted a copy on the wiki. Fixes #230.
* Added deprecation warnings for usage of the Pylons Controller class, all
controllers should inherit from WSGIController instead. Fixes #239.
* Removed deprecated attach_locals function from Controller class.
* Added an authenticate_form decorator for use with WebHelpers'
secure_form_tag functions for preventing CSRF attacks. Original patch
by David Turner. Fixes #157.
* Fix Buffet's include_pylons_variables not being upheld. Thanks Jonathan
LaCour.
* The validate decorator now accepts extra keyword arguments (**htmlfill_kwargs)
to pass along to formencode's htmlfill.render function.
* Removed POST-only restriction on validate decorator, now handles GET
requests. No form arg required during a GET request, which will run the
current action with c.form_errors set to the errors. Fixes #246.
* Added PylonsConfig, which gets accessed as pylons.config dict. Contains
all the merged ini options, in addition to the Config options such as
'routes.map', 'pylons.paths', 'buffet.template_options', etc. Check the
pylons.config docs on PylonsConfig for dict keys populated by it.
* Split up resolution stages in wsgiapp, so that controller lookup is a
separate function making it easier to subclass. PylonsApp now takes a
base_wsgi_app argument which is then used for the BaseWSGIApp instead of the
one from wsgiapp.py.
* Added mako template render tests.
* Added storage of the action func used to handle a call, for later code that
might need a reference to the action that originally handled the request.
Fixes #253.
* Updated config object to optionally take a single merged conf dict, updated
project templates to pass around the single merged conf dict.
* Changed project template to use new Beaker session keys.
* Changed default routing for raw template matching to not unicode decode the
route argument. Fixes #242.
* Catch any exceptions raised by template engine entry points and emit a
warning instead of crashing. Thanks markbradley. Fixes #249
* Fixed the validate decorator not working with formencode's
CompoundValidators when variable_decode=False. Fixes #209.
* Fixed the validate decorator failing with a KeyError when no value is
specified to validate against for separate validators (as opposed to a
schema). Reported by Graham Stratton.
* Fixed paster shell not merging app_conf and global_conf into the main CONFIG
dict namespace. Original patch by David Smith. Fixes #244.
* Added logging to decorators. Refs #98.
* Fixed paster restcontroller to test for lib.base and only add that import
statement when its present. This fixes the restcontroller template when used
with minimal Pylons project templates. Fixes #237.
* Fixed the EvalException debugger showing broken links and buttons when the
app's ErrorController was broken (such as when BaseController's __before__
raises an exception). Suggested by Ian Bicking. Fixes #228.
* paster create now accepts a 'template_engine' option to setup the new
project's default template engine. E.g. to create a new project that
uses Genshi by default, use:
paster create --template=pylons mygenshiproj template_engine=genshi
Suggested by Ian Bicking. Fixes #141.
* Fixed the validate decorator triggering the following error with
FormEncode>=0.7 and non-ascii rendered form content:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 10:
ordinal not in range(128) the form was passed in as an encoded string, but
some data or error messages were unicode strings; the form should be passed
in as a unicode string
Reported by Christoph Haas.
* HTTPExceptions are now converted to Response objects (for __after__),
making the httpexceptions middleware no longer required.
* Added Warning to jsonify to warn about cross-site attacks when returning
a list as the outer-most element to jsonify. Fixes #232.
* Fixed beaker_cache decorator to take optional keyword arguments intended
for the backend cache container (such as url for memcached).
* Fixed paster controller assuming the minimal template was in use when
the lib.base module existed but raised an exception.
* Fixed bug in XMLRPC Controller not setting proper Content-Type. Fixes #236.
* Added the '-d' ('--disable-ipython') option to paster shell for
disabling IPython.
* Allow creation of controllers named 'setup' via paster controller.
Reported by Matt Good.
* Added support for generic arguments to SQLAlchemy's create_engine of
the form sqlalchemy.* from the PasteDeploy config file.
0.9.5 (Apr 11th, 2007)
* Fixed a Python 2.3 incompatibility with paster shell, causing the
Exception:
File "Pylons-0.9.5-py2.3.egg/pylons/commands.py", line 357, in command
locs.update([(name, getattr(base, name)) for name in base_public])
AttributeError: keys
* Fixed paster shell breaking for projects where the base package was not
the first package listed in top_level.txt. Patch from Alberto Valverde.
Fixes #229.
* Fixed doc references to config['app_conf']. Fixes #116.
* Changed `get_engine_conf` to properly evaluate sqlalchemy echo statement
when its 'debug'. Fixes #226.
* make_session and create_engine now accept keyword arguments to pass to
SQLAlchemy's create_engine.
* make_session now accepts the keyword argument 'session_kwargs' to pass
to SQLAlchemy's create_session.
* Fixed _inspect_call to call function with keyword arguments instead of list
args. Corrects issue with action defaults that caused the value for the
latter args to be in the wrong spots. Spotted by Topher. Fixes #223.
* Added the allow_none option (passed to xmlrpc.dumps) to XMLRPCController.
Suggested by Jaroslaw Zabiello.
* Updated XMLRPC Controller with patch for name lookup and additional unit
tests for the patch. Fixes #216.
* Updated docs for validate decorator to more clearly illustrate what the
post_only args apply to. Fixes #221.
* Added ability to return strings in the WSGIController. Fixes #218.
* Added lazy i18n translation functions. Patch from David Smith. Fixes #181.
* Added fix for XMLRPCController system.methodHelp function and unit test.
Patch and unit test submitted by Graham Higgins.
* Fixed bug in validate decorator with new UnicodeMultiDict response content
not properly retaining form content as unicode for formencode's htmlfill.
* Fixed bug in XMLRPC Controller with xmlrpclib Faults not being properly
transformed into a WSGI response within the controller.
* WARNING: Pylons now requires the decorator module: it no longer packages
it as pylons.decorator. Code relying on the pylons.decorator.decorator
function will trigger a deprecation warning and should be changed to use
decorator.decorator.
* WARNING: pylons.h was deprecated for using projects' lib.helpers module
directly in 0.9.3. pylons.h is now formally deprecated (emits
DeprecationWarnings). Projects still accessing pylons.h must change the
following import:
from pylons import h
to:
import MYPROJ.lib.helpers as h
* pylons.jsonify and pylons.Controller references have been deprecated
(they are misplaced references). They continue to be available at
pylons.decorators.jsonify and pylons.controllers.Controller, as they always
have been.
* Updated templating Buffet to recognize format parameter and properly pass it
to the template engine.
* Updated LICENSE for new year and to indicate license covering templates
generated. Fixes #188.
* Interactive debugger now supports Mako. After r1780 if you are using a
custom theme you will need to change '%(myghty_data)s' to
'%(template_data)s' in your template. If you are using JavaScript the tab
id is now "template_data".
* Fixed bug in WSGIController with private function attempts not returning a
valid WSGI response.
* Added full unit test coverage of cache decorator.
* Adding messages binary file, enabling i18n unit tests. Updating pylons.i18n
to import LanguageError. Fixes #193.
* Adding i18n tests, not active yet as they're waiting on a binary file from a
patch. Refs #193.
* Updated tests so that they now work with nose, removing py.test requirement.
* Switching config setup to load keys into main config dict with app_conf and
global_conf keys set for any code looking for those keys. Fixes #116.
* PylonsInstaller is now the default paste.app_install entry point for new
projects: this makes Cheetah no longer required for the paster make-config
command. (Thanks Alexander Schremmer, Ian Bicking)
* Added custom redirect_to function in pylons.helpers that will take an
optional _response arg to pull headers and cookies out for preservation
during a redirect. Fixes #136.
* Changed config.Config.__init__ to take all options as keyword args so
unused args can be skipped. Fixes #162.
* The request object can now automatically decode GET/POST/params vars to
unicode, when its charset attribute is set.
* Added a new request_settings keyword arg to Config's constructor. Allows
setting the default charset and errors values of of the request object.
* Deprecated Config constructor's default_charset keyword arg. Use Config's
response_settings keyword arg instead.
* Fixed paster controller to test for lib.base and only add that import
statement when its present. This fixes the controller template when used with
minimal Pylons project templates. Fixes #140 and fixes #139.
* Fixed the paster shell error: KeyError: 'pylons.routes_dict' when calling
app.get and app.post.
* Fixed paster shell not working on projects with names containing hyphens.
* Fixed the config directive 'sqlalchemy.echo' set to False being interpreted
as True. Patch by Alex Conrad.
* Fixed paster shell not restoring CONFIG['global_conf'].
0.9.4.1 (Jan. 5th, 2007)
* Added restcontroller command that generates a RESTful controller template
and provides the appropriate map.resource command to add. Suggested by
Matthew Scott.
* Fixed SQLObject pylons.database.PackageHub error:
exceptions.NameError: global name 'CONFIG' is not defined
* Fixed pylons.database.session_context not working outside of requests
(such as in websetup.py).
* Updated template options config to take template options for multiple
engines for less binding to Myghty.
* Fixed paster shell incorrectly importing the the tuple (model,) as the
model object.
0.9.4 (Dec. 29th, 2006)
* WARNING: Removed the lang_extract and lang_compile commands. They used
pygettext.py and its associated msgfmt.py, which lacked the ability to
extract ngettext style function calls and had issues with unicode strings.
The new I18NToolBox project aims to provide this functionality (and more)
via the gettext command line utilities. http://i18ntoolbox.ufsoft.org
* All Pylons special objects are now available within paster shell (not just
h and g).
* WARNING: Myghty's allow_globals config var has changed, causing the
following when running pre-compiled templates:
Error(TypeError): do_run_component() takes exactly 13 non-keyword
arguments (5 given)
Delete the compiled Myghty templates directory (specified by cache_dir or
myghty_data_dir in the config file) to resolve the error.
* Changed i18n functions in templates to use proxy objects so that using
set_lang in a template works right. Fixes #153.
* Now allowing any template plugin to overwrite global PYLONS_VARS (such as c,
g), not just pylonsmyghty.
* Adding SQLAlchemy support to the database.py file. Saves the session engine
to g to maintain it during the apps lifetime. Uses SessionContext plugin for
management of the current session.
* Updated config object so that init_app can take an optional template engine
argument to declare the default template engine.
* Updated Myghty plugin to use extra_vars_func when passed in.
* Fixed Buffet to use extra_vars_func properly.
* Fixed the validate decorator when there are validation errors and
variable_decode=True: now passing the original params to htmlfill.render
instead of the varable_decode'd version. Patch by FlimFlamMan.
* Added ungettext function for use with pluralized i18n, and the N_ function
(gettext_noop) to mark global strings for translation. Added ungettext, N_
and translator objects to be globals for templates. Refs #126.
* WARNING: The localization function '_' now uses ugettext (returns unicode
strings) instead of gettext. To preserve the old behavior, append the
following line to your project's lib.base and lib.helpers imports:
from pylons.helpers import gettext as _
* Pylons special objects are now available within the interactive debugger
(deprecating _attach_locals).
* Added setup-app run before unit tests run so that webapp has proper setup
tasks handled. Fixes #113.
* Added paste.deploy.CONFIG setup to middleware.py, websetup.py and testing
files in the Pylons project templates. Closes #112.
* Added security policy doc to index for use as Pylons security policy.
Closes #91.
* Improved the repr() of the c context object to show attributes.
* Set environ['paste.testing_variables'] whenever that key is available, not
just in testing mode.
* Added capability to have an action be a generator function.
* Added introspection capability to XMLRPCController and signature checking.
* Updated Controller to use additional arg lookup scheme so that the source of
the function args for _inspect_call can be easily overridden.
* Updated RPCController, renamed to XMLRPCController. XMLRPCController now
functions properly and will automatically return proper xmlrpc responses.
* Added test configuration ini file to default template. Closes #114.
* Fixed problem with pylons.database.PackageHub.__get__ raising errors
other than AttributeError when the database isn't configured. Added
new UnconfiguredConnectionError exception, instead of just KeyError
or TypeError (depending on what part of the configuration failed).
* Fixed default g init, since bare object has no init method. Reported by Ian
Bicking.
* Fixed issue with SQLObject method override having wrong name. Reported by
climbus with patch. Fixes #133.
* Moved log function to pylons.helpers and translation functions to
pylons.i18n. using pylons.util purely for Pylons internal util functions.
* WARNING: Removed 0.8.x legacy code and backwards compatibility functions.
* PylonsApp now has option to not use Routes middleware, default resolving
uses new wsgi.org routing_args spec.
* Refactored routes dispatching to use new Routes middleware.
* Fixed paster shell command to properly acquire mapper object without
relying on the template being configured in a specific manner.
* Added keyword argument pool_connection to
pylons.database.PackageHub; if set to false then SQLObject connections
won't use pooled database connections (a new connection will be
opened for each request).
0.9.3 (Nov 1st, 2006)
* Updated project template to support full_stack option to make it easier to
use Pylons apps within larger WSGI stacks.
* Added deprecation warnings to legacy objects and for 1.0 functionality that
will change.
* Added cache decorator and Cheetah template functional tests. Patch and unit
tests provided by Climbus.
* Fixed readline support in the stock interactive console paster shell.
Reported by Alex Conrad.
* A controller's __after__ method will now be called after actions invoke
redirect_to (or raise any HTTPException). Reported by David Turner.
* Fixed config to use myghty_data_dir instead of cache_dir setting if its
set as well. Reported by Shannon -jj Behrens.
* Added traceback hiding so that more of the traceback relating to Pylons code
is removed from the default traceback making it easier to focus on the code
in an app that actually caused the problem. Closes #119.
* Added ability to use '_' translation method directly from templates and in
the controller without having to use it under h._.
* Added 's' and 'l' Myghty escaping flags to default project templates.
Suggested by Jamie Wilkinson. Closes #110.
* Fixed SCGI bug with QUERY_STRING test when WSGI states it doesn't have to
exist. Reported by Riklaunim.
* Added pylons_minimal template, prone to fine-tuning.
* Added option for PylonsApp to take a globals object to avoid checking a
hardcoded path for a Globals object.
* Removed old Helpers legacy object entirely, replaced pylons.h with proper
StackedObjectProxy. Cleaned up PylonsApp and PylonsBaseApp to accept a
helpers reference so that Pylons can be ignorant of where the helpers came
from.
* Fixed bug with lang app_conf option being set improperly. Reported
by Laurent.
* Fixed pylons.h to work proper with new and old-style helper imports.
* Fixed render functions always passing disable_unicode=False to Myghty.
0.9.2 (Sept. 7th, 2006)
* Fixed problem with dashes in controller names, resolves #107.
* Updated default ini file to use localhost from address. Refs #104.
* Updated default development.ini to use a single cache_dir setting which
is the base dir that cache files, session files, and template caching will
be saved in. Config object now looks to cache_dir setting properly for
Myghty templates. Fixes #104.
* Updated default template controller to provide better example of directly
serving Myghty templates.
* Fixed legacy (0.8) controller methods' **ARGS (also m.request_args and
pylons.params) to be of the expected mixed dictionary instead of MultiDict.
* Fixed _attach_locals not attaching g and cache objects.
* Added g object to the shell. Works as long as the Pylons app can respond
to a path of '/'. The pylons.g variable will also be setup properly for
use in the shell.
* Myghty template options are now passed properly to the template creation, and
allow_globals now works to add Myghty template globals.
* Re-organized helpers, switched Helpers class to use static methods to reduce
code duplication.
* Helpers cleanup:
- Old-style Helper object uses StackedObjectProxy just like the new
scheme, thus avoiding possible WSGI stack issues.
- New project templates use new-style Helpers scheme.
- Updated wsgiapp to utilize new Helpers cleanup style. The 'h' object
is now friendlier to use, and maps directly to a projects lib.helpers
file. No more wacky Helpers object proxying to it.
- Added translator global to __init__.py for use with new Helpers cleanup.
- Copied Helpers function methods directly into util so they can be used
stand-alone.
- Deprecated h.lang (for h.set_lang/h.get_lang)
* Moved the 'default_charset' option from PylonsApp's constructor to
Config's.
* Added 'error' controller route to the top of the Pylons template to avoid
the common issue people discover when removing the generic default route.
* Changing validate decorator to have variable_decode option, which will
also run formencode's variable_decode function over the form input.
* Switched to using Context obj classes instead of RequestLocal which is
being phased out.
* Added an 'encode_variables' option to the validate decorator.
* Switched all current_obj calls to _current_obj to avoid triggering
deprecation warnings.
* Added is_xhr to Request object in Paste.
* Bumping up dependency to latest Paste.
* Switching back to prior controller import check, throwing a more detailed
error with a suggest fix should the user really want a URL with that name
in it. (refs #67)
* Fixes bug with prior fix for #67. Wasn't properly testing the full package
name to include the current project which would incorrectly restrict
valid controller names (refs #67).
* Fixed '_method_' checking to test in a more efficient manner.
* Added deprecation warning for legacy mode activation. Not necessary to
update multiple files, as all of legacy mode is enabled via the Legacy
WSGI app. Fixes #89.
* Fixed controller command to check controller name and refuse to create
controllers that have name clashes with existing modules that could be
imported. Reported (with patch) by Chuck Adams. Fixes #67.
* Added capability for 'c' object to throw an exception when an attribute
is used that doesn't exist. Closes #84.
* Fix for endless error document call when an error document controller
wants to throw a error that the error_mapper catches.
0.9.1 (August 11th, 2006)
* Fixed __all__ export typo in templating.py. Added example of render
with a template.
* Fixed issue with set_lang not using proper CONFIG var.
* Minor tweaks to update docs in pylons.helpers and move remaining legacy
code into legacy module. Updated wsgiapp to refer to new locations of
legacy compatibility objects.
* The interactive debugger's 'full traceback' link is now only displayed
when the full traceback differs from the regular (includes hidden
frames).
* Providing an optional text version of exception tracebacks and the
associated extra data within the interactive debugger.
* The 'Debug at: http://hostname/_debug/view/XXXXX' URLs now display the
interactive debugger properly skinned.
* Fixed issue in PasteScript with new controller sub-directories lacking a
__init__.py file. This fixes an import error when using the controller.
PasteScript dependency updated to fixed version. Reported by Artur Lew.
* Removed lowercasing of the module name during resolver import.
* Removed [full] recommendation from docs.
0.9 (July 28th, 2006)
* config file option 'debug' now defaults to false when undefined
* Removed the components directory from the template
* Updated paste.errordocuments support
* Fix for multi-word controller names such that front_page /
FrontPageController can be used as a controller name. Patch contributed
by Timo Mihaljov.
* Cleaned up imports in wsgiapp and new project to better reflect where
things really come from.
* Removed unnecessary myghty usage from wsgiapp for url unescaping, now
uses urllib as the myghty function did.
* Removing 'response' to import, sticking with Response as its more
consistent with the fact that Response is a class/factory and not an
instance like request, and the other lower-case objects.
* Added redirect_to under pylons.helpers, and added import from helpers
directly into lib/base.py for use in controllers.
* Consolidated legacy objects into legacy module.
* Adding abort method that raises the appropriate exception for the status
code.
* Removing form_fill, obsolete by the validate decorator.
* Relocated 'params' object to only take effect in legacy mode.
* Updated Pylons template to use WSGIController as the new default Controller.
* Altered the wsgi dispatch to examine the controller, and instantiate it if
it's just a class. Otherwise, if the controller is a subclass of Controller
but not of WSGIController, it assumes its an older Controller class that
may return a WSGIResponse, and calls it appropriately.
* Dispatch now fixes up environ to move 'path_info' Route var into the WSGI
PATH_INFO, and the rest is pushed into SCRIPT_NAME. This is for use with
other WSGI apps under controller mount points.
* Added WSGIController which takes a normal WSGI interface call and returns
the appropriate WSGI response.
* Added automatic copying of Route variables declared in an action's
function definition to the 'c' object.
* WebHelpers' .js files are now automatically published under the
'/javascripts/' URL path. Individual WebHelpers' .js files can be
overridden by other .js files inside the project's 'public/javascripts'
directory
* Added exception toss when a template engine doesn't exist.
* Added alias option to Buffet to support aliasing more template engines
to other engine names
* Buffet enhancements to support caching of any template with any template
engine
* All render commands processed through Buffet
* Backwards compatibility 'm' object for use with legacy projects
* Added use of Beaker middleware for session and caching functionality
* Fixed error traceback and updated template to use proper error images and
stylesheets.
0.8.2 (**dev**)
* Fixed default controller to allow for actions with - in them. The - will be
replaced with an underscore, while the original action name in the mapper
dict is unchanged. Patch by Thomas Sidwick.
0.8.1 (May 10th, 2006)
* Added REST decorators and re-arranged decorator layout to support more styles
of decorators for future expansion.
* Fixed dependency requirement bug that had Pylons locked to simplejson 1.1
even though a newer version was out.
================================================
FILE: LICENSE
================================================
Copyright (c) 2005-2015 Ben Bangert, James Gardner, Philip Jenvey
and contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author or contributors may not be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-------------------------------------------------------------------------------
ALL TEMPLATES GENERATED ARE COVERED UNDER THE FOLLOWING LICENSE:
Copyright (c) 2005-2015 Ben Bangert, James Gardner, Philip Jenvey
and contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following condition is
met:
The name of the author or contributors may not be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
================================================
FILE: MANIFEST.in
================================================
recursive-include pylons/templates *
recursive-include pylons/media *
recursive-include tests *
recursive-include test_files *
include CHANGELOG
include LICENSE
include UPGRADING
recursive-exclude tests/test_units/session *
global-exclude .DS_Store *.hgignore *.hgtags
================================================
FILE: README.rst
================================================
Pylons
++++++
.. image:: https://secure.travis-ci.org/Pylons/pylons.png?branch=master
:alt: Build Status
:target: https://secure.travis-ci.org/Pylons/pylons
Pylons is a rapid web application development framework.
.. note::
Pylons has merged with repoze.bfg, and is now in maintenance-only
mode. It's highly recommended that new projects start with the new
merged web framework, `pyramid <http://www.pylonsproject.org/>`_.
Install
=======
`Read the online Installation instructions
<http://docs.pylonsproject.org/projects/pylons-webframework/en/latest/gettingstarted.html#installing>`_.
If you want to install from source you can run the following command:
.. code-block :: bash
$ python setup.py install
This will display a message and download setuptools if the module is not
already installed. It will then install Pylons and all its dependencies. You
may need root privileges to install setuptools.
Testing
=======
To test the source distribution run the following command:
.. code-block :: bash
$ python setup.py test
This will install additional dependencies needed for the tests. As above, you
may need root privileges.
Documentation
=============
`Read the complete Pylons web framework documentation
<http://docs.pylonsproject.org/projects/pylons-webframework/>`_.
`Definitive Guide to Pylons <https://thejimmyg.github.io/pylonsbook/>`_ is a book about Pylons published by Apress, written by James Gardner, with free HTML rendering.
Generating documentation requires Sphinx:
.. code-block :: bash
$ easy_install Sphinx
Then to build the documentation use the commands:
.. code-block :: bash
$ cd pylons/docs/<lang>
$ make html
================================================
FILE: UPGRADING
================================================
Upgrading your Pylons Project
=============================
Pylons projects should be updated using the paster command create. In addition
to creating new projects, paster create when run over an existing project will
provide several ways to update the project template to the latest version.
Using this tool properly can make upgrading a fairly minor task. For the
purpose of this document, the project being upgraded will be called 'demoapp'
and all commands will use that name.
Running paster create to upgrade
--------------------------------
You'll first need to cd to the directory *above* your projects main directory.
The main directory is the one that contains your setup.py, setup.cfg, and
development.ini files.
.. code:: bash
/home/joe/demoapp $ cd ..
/home/joe $
Then run paster create on the project directory:
.. code:: bash
/home/joe $ paster create demoapp -t pylons
paster will prompt you on how to handle conflicts and updates to the existing
project files. The options let you (hit the key in the parens to perform the
operation):
(d)iff them, and show you the changes between your projects file and the one
that has changed in Pylons
(b)ackup the file, and copy the new version into its place. The old one will
end in .bak
(y)es to overwrite the existing file with the new one. *Not recommended* since
you will then have no way to see your existing one, unless you have seen
the diff first and know there is no changes you're losing.
(n)o to overwrite, and just keep your existing file. Also safe if you know
that nothing has changed.
It's recommended when upgrading your project that you always look at the diff
first to see whats changed. Then either overwrite your existing one if you are
not going to lose changes you want, or backup yours and write the new one in.
You can then manually compare and add your changes back in.
================================================
FILE: ez_setup.py
================================================
#!python
"""Bootstrap setuptools installation
If you want to use setuptools in your package's setup.py, just include this
file in the same directory with it, and add this to the top of your setup.py::
from ez_setup import use_setuptools
use_setuptools()
If you want to require a specific version of setuptools, set a download
mirror, or use an alternate download directory, you can do so by supplying
the appropriate options to ``use_setuptools()``.
This file can also be run as a script to install or upgrade setuptools.
"""
import sys
DEFAULT_VERSION = "0.6c9"
DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
md5_data = {
'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03',
'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a',
'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6',
'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a',
}
import sys, os
try: from hashlib import md5
except ImportError: from md5 import md5
def _validate_md5(egg_name, data):
if egg_name in md5_data:
digest = md5(data).hexdigest()
if digest != md5_data[egg_name]:
print >>sys.stderr, (
"md5 validation of %s failed! (Possible download problem?)"
% egg_name
)
sys.exit(2)
return data
def use_setuptools(
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
download_delay=15
):
"""Automatically find/download setuptools and make it available on sys.path
`version` should be a valid setuptools version number that is available
as an egg for download under the `download_base` URL (which should end with
a '/'). `to_dir` is the directory where setuptools will be downloaded, if
it is not already available. If `download_delay` is specified, it should
be the number of seconds that will be paused before initiating a download,
should one be required. If an older version of setuptools is installed,
this routine will print a message to ``sys.stderr`` and raise SystemExit in
an attempt to abort the calling script.
"""
was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
def do_download():
egg = download_setuptools(version, download_base, to_dir, download_delay)
sys.path.insert(0, egg)
import setuptools; setuptools.bootstrap_install_from = egg
try:
import pkg_resources
except ImportError:
return do_download()
try:
pkg_resources.require("setuptools>="+version); return
except pkg_resources.VersionConflict, e:
if was_imported:
print >>sys.stderr, (
"The required version of setuptools (>=%s) is not available, and\n"
"can't be installed while this script is running. Please install\n"
" a more recent version first, using 'easy_install -U setuptools'."
"\n\n(Currently using %r)"
) % (version, e.args[0])
sys.exit(2)
else:
del pkg_resources, sys.modules['pkg_resources'] # reload ok
return do_download()
except pkg_resources.DistributionNotFound:
return do_download()
def download_setuptools(
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
delay = 15
):
"""Download setuptools from a specified location and return its filename
`version` should be a valid setuptools version number that is available
as an egg for download under the `download_base` URL (which should end
with a '/'). `to_dir` is the directory where the egg will be downloaded.
`delay` is the number of seconds to pause before an actual download attempt.
"""
import urllib2, shutil
egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
url = download_base + egg_name
saveto = os.path.join(to_dir, egg_name)
src = dst = None
if not os.path.exists(saveto): # Avoid repeated downloads
try:
from distutils import log
if delay:
log.warn("""
---------------------------------------------------------------------------
This script requires setuptools version %s to run (even to display
help). I will attempt to download it for you (from
%s), but
you may need to enable firewall access for this script first.
I will start the download in %d seconds.
(Note: if this machine does not have network access, please obtain the file
%s
and place it in this directory before rerunning this script.)
---------------------------------------------------------------------------""",
version, download_base, delay, url
); from time import sleep; sleep(delay)
log.warn("Downloading %s", url)
src = urllib2.urlopen(url)
# Read/write all in one block, so we don't create a corrupt file
# if the download is interrupted.
data = _validate_md5(egg_name, src.read())
dst = open(saveto,"wb"); dst.write(data)
finally:
if src: src.close()
if dst: dst.close()
return os.path.realpath(saveto)
def main(argv, version=DEFAULT_VERSION):
"""Install or upgrade setuptools and EasyInstall"""
try:
import setuptools
except ImportError:
egg = None
try:
egg = download_setuptools(version, delay=0)
sys.path.insert(0,egg)
from setuptools.command.easy_install import main
return main(list(argv)+[egg]) # we're done here
finally:
if egg and os.path.exists(egg):
os.unlink(egg)
else:
if setuptools.__version__ == '0.0.1':
print >>sys.stderr, (
"You have an obsolete version of setuptools installed. Please\n"
"remove it from your system entirely before rerunning this script."
)
sys.exit(2)
req = "setuptools>="+version
import pkg_resources
try:
pkg_resources.require(req)
except pkg_resources.VersionConflict:
try:
from setuptools.command.easy_install import main
except ImportError:
from easy_install import main
main(list(argv)+[download_setuptools(delay=0)])
sys.exit(0) # try to force an exit
else:
if argv:
from setuptools.command.easy_install import main
main(argv)
else:
print "Setuptools version",version,"or greater has been installed."
print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
def update_md5(filenames):
"""Update our built-in md5 registry"""
import re
for name in filenames:
base = os.path.basename(name)
f = open(name,'rb')
md5_data[base] = md5(f.read()).hexdigest()
f.close()
data = [" %r: %r,\n" % it for it in md5_data.items()]
data.sort()
repl = "".join(data)
import inspect
srcfile = inspect.getsourcefile(sys.modules[__name__])
f = open(srcfile, 'rb'); src = f.read(); f.close()
match = re.search("\nmd5_data = {\n([^}]+)}", src)
if not match:
print >>sys.stderr, "Internal error!"
sys.exit(2)
src = src[:match.start(1)] + repl + src[match.end(1):]
f = open(srcfile,'w')
f.write(src)
f.close()
if __name__=='__main__':
if len(sys.argv)>2 and sys.argv[1]=='--md5update':
update_md5(sys.argv[2:])
else:
main(sys.argv[1:])
================================================
FILE: pylons/__init__.py
================================================
"""Base objects to be exported for use in Controllers"""
# Import pkg_resources first so namespace handling is properly done so the
# paste imports work
import pkg_resources
from paste.registry import StackedObjectProxy
from pylons.configuration import config
from pylons.controllers.util import Request
from pylons.controllers.util import Response
__all__ = ['app_globals', 'cache', 'config', 'request', 'response',
'session', 'tmpl_context', 'url', 'Request', 'Response']
def __figure_version():
try:
from pkg_resources import require
import os
# NOTE: this only works when the package is either installed,
# or has an .egg-info directory present (i.e. wont work with raw
# SVN checkout)
info = require('pylons')[0]
if os.path.normcase(os.path.realpath(os.path.dirname(
os.path.dirname(__file__)))) == info.location:
return info.version
else:
return '(not installed)'
except:
return '(not installed)'
__version__ = __figure_version()
app_globals = StackedObjectProxy(name="app_globals")
cache = StackedObjectProxy(name="cache")
request = StackedObjectProxy(name="request")
response = StackedObjectProxy(name="response")
session = StackedObjectProxy(name="session")
tmpl_context = StackedObjectProxy(name="tmpl_context or C")
url = StackedObjectProxy(name="url")
translator = StackedObjectProxy(name="translator")
================================================
FILE: pylons/commands.py
================================================
"""Paster Commands, for use with paster in your project
.. highlight:: bash
The following commands are made available via paster utilizing
setuptools points discovery. These can be used from the command line
when the directory is the Pylons project.
Commands available:
``controller``
Create a Controller and accompanying functional test
``restcontroller``
Create a REST Controller and accompanying functional test
``shell``
Open an interactive shell with the Pylons app loaded
Example usage::
~/sample$ paster controller account
Creating /Users/ben/sample/sample/controllers/account.py
Creating /Users/ben/sample/sample/tests/functional/test_account.py
~/sample$
.. admonition:: How it Works
:command:`paster` is a command line script (from the PasteScript
package) that allows the creation of context sensitive commands.
:command:`paster` looks in the current directory for a
``.egg-info`` directory, then loads the ``paster_plugins.txt``
file.
Using setuptools entry points, :command:`paster` looks for
functions registered with setuptools as
:func:`paste.paster_command`. These are defined in the entry_points
block in each packages :file:`setup.py` module.
This same system is used when running :command:`paster create` to
determine what templates are available when creating new projects.
"""
import os
import sys
import paste.fixture
import paste.registry
from paste.deploy import loadapp
from paste.script.command import Command, BadCommand
from paste.script.filemaker import FileOp
from tempita import paste_script_template_renderer
import pylons
import pylons.util as util
__all__ = ['ControllerCommand', 'RestControllerCommand', 'ShellCommand']
def can_import(name):
"""Attempt to __import__ the specified package/module, returning
True when succeeding, otherwise False"""
try:
__import__(name)
return True
except ImportError:
return False
def is_minimal_template(package, fail_fast=False):
"""Determine if the specified Pylons project (package) uses the
Pylons Minimal Template.
fail_fast causes ImportErrors encountered during detection to be
raised.
"""
minimal_template = False
try:
# Check if PACKAGE.lib.base exists
__import__(package + '.lib.base')
except ImportError, ie:
if 'No module named lib.base' in str(ie):
minimal_template = True
except:
# PACKAGE.lib.base exists but throws an error
if fail_fast:
raise
return minimal_template
def defines_render(package):
"""Determine if the specified Pylons project (package) defines a
render callable in their base module
"""
base_module = (is_minimal_template(package) and package + '.controllers' or
package + '.lib.base')
try:
base = __import__(base_module, globals(), locals(), ['__doc__'])
except:
return False
return callable(getattr(base, 'render', None))
def validate_name(name):
"""Validate that the name for the controller isn't present on the
path already"""
if not name:
# This happens when the name is an existing directory
raise BadCommand('Please give the name of a controller.')
# 'setup' is a valid controller name, but when paster controller is ran
# from the root directory of a project, importing setup will import the
# project's setup.py causing a sys.exit(). Blame relative imports
if name != 'setup' and can_import(name):
raise BadCommand(
"\n\nA module named '%s' is already present in your "
"PYTHON_PATH.\nChoosing a conflicting name will likely cause "
"import problems in\nyour controller at some point. It's "
"suggested that you choose an\nalternate name, and if you'd "
"like that name to be accessible as\n'%s', add a route "
"to your projects config/routing.py file similar\nto:\n"
" map.connect('%s', controller='my_%s')" \
% (name, name, name, name))
return True
def check_controller_existence(base_package, directory, name):
"""Check if given controller already exists in project."""
filename = os.path.join(base_package, 'controllers', directory,
name + '.py')
if os.path.exists(filename):
raise BadCommand('Controller %s already exists.' %
os.path.join(directory, name))
class ControllerCommand(Command):
"""Create a Controller and accompanying functional test
The Controller command will create the standard controller template
file and associated functional test to speed creation of
controllers.
Example usage::
yourproj% paster controller comments
Creating yourproj/yourproj/controllers/comments.py
Creating yourproj/yourproj/tests/functional/test_comments.py
If you'd like to have controllers underneath a directory, just
include the path as the controller name and the necessary
directories will be created for you::
yourproj% paster controller admin/trackback
Creating yourproj/controllers/admin
Creating yourproj/yourproj/controllers/admin/trackback.py
Creating yourproj/yourproj/tests/functional/test_admin_trackback.py
"""
summary = __doc__.splitlines()[0]
usage = '\n' + __doc__
min_args = 1
max_args = 1
group_name = 'pylons'
default_verbosity = 3
parser = Command.standard_parser(simulate=True)
parser.add_option('--no-test',
action='store_true',
dest='no_test',
help="Don't create the test; just the controller")
def command(self):
"""Main command to create controller"""
try:
file_op = FileOp(source_dir=('pylons', 'templates'))
try:
name, directory = file_op.parse_path_name_args(self.args[0])
except:
raise BadCommand('No egg_info directory was found')
# Check the name isn't the same as the package
base_package = file_op.find_dir('controllers', True)[0]
if base_package.lower() == name.lower():
raise BadCommand(
'Your controller name should not be the same as '
'the package name %r.' % base_package)
# Validate the name
name = name.replace('-', '_')
validate_name(name)
# Determine the module's import statement
if is_minimal_template(base_package):
importstatement = ('from %s.controllers import BaseController'
% base_package)
else:
importstatement = ('from %s.lib.base import BaseController' %
base_package)
if defines_render(base_package):
importstatement += ', render'
# Setup the controller
fullname = os.path.join(directory, name)
controller_name = util.class_name_from_module_name(
name.split('/')[-1])
if not fullname.startswith(os.sep):
fullname = os.sep + fullname
testname = fullname.replace(os.sep, '_')[1:]
module_dir = directory.replace('/', os.path.sep)
check_controller_existence(base_package, module_dir, name)
file_op.template_vars.update(
{'name': controller_name,
'fname': os.path.join(directory, name).replace('\\', '/'),
'tmpl_name': name,
'package': base_package,
'importstatement': importstatement})
file_op.copy_file(template='controller.py_tmpl',
dest=os.path.join('controllers', directory),
filename=name,
template_renderer=paste_script_template_renderer)
if not self.options.no_test:
file_op.copy_file(
template='test_controller.py_tmpl',
dest=os.path.join('tests', 'functional'),
filename='test_' + testname,
template_renderer=paste_script_template_renderer)
except BadCommand, e:
raise BadCommand('An error occurred. %s' % e)
except:
msg = str(sys.exc_info()[1])
raise BadCommand('An unknown error occurred. %s' % msg)
class RestControllerCommand(Command):
"""Create a REST Controller and accompanying functional test
The RestController command will create a REST-based Controller file
for use with the :meth:`~routes.mapper.Mapper.resource`
REST-based dispatching. This template includes the methods that
:meth:`~routes.mapper.Mapper.resource` dispatches to in
addition to doc strings for clarification on when the methods will
be called.
The first argument should be the singular form of the REST
resource. The second argument is the plural form of the word. If
its a nested controller, put the directory information in front as
shown in the second example below.
Example usage::
yourproj% paster restcontroller comment comments
Creating yourproj/yourproj/controllers/comments.py
Creating yourproj/yourproj/tests/functional/test_comments.py
If you'd like to have controllers underneath a directory, just
include the path as the controller name and the necessary
directories will be created for you::
yourproj% paster restcontroller admin/tracback admin/trackbacks
Creating yourproj/controllers/admin
Creating yourproj/yourproj/controllers/admin/trackbacks.py
Creating yourproj/yourproj/tests/functional/test_admin_trackbacks.py
"""
summary = __doc__.splitlines()[0]
usage = '\n' + __doc__
min_args = 2
max_args = 2
group_name = 'pylons'
default_verbosity = 3
parser = Command.standard_parser(simulate=True)
parser.add_option('--no-test',
action='store_true',
dest='no_test',
help="Don't create the test; just the controller")
def command(self):
"""Main command to create controller"""
try:
file_op = FileOp(source_dir=('pylons', 'templates'))
try:
singularname, singulardirectory = \
file_op.parse_path_name_args(self.args[0])
pluralname, pluraldirectory = \
file_op.parse_path_name_args(self.args[1])
except:
raise BadCommand('No egg_info directory was found')
# Check the name isn't the same as the package
base_package = file_op.find_dir('controllers', True)[0]
if base_package.lower() == pluralname.lower():
raise BadCommand(
'Your controller name should not be the same as '
'the package name %r.' % base_package)
# Validate the name
for name in [pluralname]:
name = name.replace('-', '_')
validate_name(name)
# Determine the module's import statement
if is_minimal_template(base_package):
importstatement = ('from %s.controllers import BaseController'
% base_package)
else:
importstatement = ('from %s.lib.base import BaseController' %
base_package)
if defines_render(base_package):
importstatement += ', render'
module_dir = pluraldirectory.replace('/', os.path.sep)
check_controller_existence(base_package, module_dir, name)
# Setup the controller
fullname = os.path.join(pluraldirectory, pluralname)
controller_name = util.class_name_from_module_name(
pluralname.split('/')[-1])
if not fullname.startswith(os.sep):
fullname = os.sep + fullname
testname = fullname.replace(os.sep, '_')[1:]
nameprefix = ''
path = ''
if pluraldirectory:
nameprefix = pluraldirectory.replace(os.path.sep, '_') + '_'
path = pluraldirectory + '/'
controller_c = ''
if nameprefix:
controller_c = ", controller='%s', \n\t" % \
'/'.join([pluraldirectory, pluralname])
controller_c += "path_prefix='/%s', name_prefix='%s'" % \
(pluraldirectory, nameprefix)
command = "map.resource('%s', '%s'%s)\n" % \
(singularname, pluralname, controller_c)
file_op.template_vars.update(
{'classname': controller_name,
'pluralname': pluralname,
'singularname': singularname,
'name': controller_name,
'nameprefix': nameprefix,
'package': base_package,
'path': path,
'resource_command': command.replace('\n\t', '\n%s#%s' % \
(' ' * 4, ' ' * 9)),
'fname': os.path.join(pluraldirectory, pluralname),
'importstatement': importstatement})
resource_command = ("\nTo create the appropriate RESTful mapping, "
"add a map statement to your\n")
resource_command += ("config/routing.py file near the top like "
"this:\n\n")
resource_command += command
file_op.copy_file(template='restcontroller.py_tmpl',
dest=os.path.join('controllers', pluraldirectory),
filename=pluralname,
template_renderer=paste_script_template_renderer)
if not self.options.no_test:
file_op.copy_file(
template='test_restcontroller.py_tmpl',
dest=os.path.join('tests', 'functional'),
filename='test_' + testname,
template_renderer=paste_script_template_renderer)
print resource_command
except BadCommand, e:
raise BadCommand('An error occurred. %s' % e)
except:
msg = str(sys.exc_info()[1])
raise BadCommand('An unknown error occurred. %s' % msg)
class RoutesCommand(Command):
"""Print the applications routes
The optional CONFIG_FILE argument specifies the config file to use.
CONFIG_FILE defaults to 'development.ini'.
Example::
$ paster routes my-development.ini
"""
summary = __doc__.splitlines()[0]
usage = '\n' + __doc__
min_args = 0
max_args = 1
group_name = 'pylons'
parser = Command.standard_parser(simulate=True)
parser.add_option('-q',
action='count',
dest='quiet',
default=0,
help=("Do not load logging configuration from the "
"config file"))
def command(self):
"""Main command to create a new shell"""
self.verbose = 3
if len(self.args) == 0:
# Assume the .ini file is ./development.ini
config_file = 'development.ini'
if not os.path.isfile(config_file):
raise BadCommand('%sError: CONFIG_FILE not found at: .%s%s\n'
'Please specify a CONFIG_FILE' % \
(self.parser.get_usage(), os.path.sep,
config_file))
else:
config_file = self.args[0]
config_name = 'config:%s' % config_file
here_dir = os.getcwd()
if not self.options.quiet:
# Configure logging from the config file
self.logging_file_config(config_file)
# Load the wsgi app first so that everything is initialized right
wsgiapp = loadapp(config_name, relative_to=here_dir)
test_app = paste.fixture.TestApp(wsgiapp)
# Query the test app to setup the environment and get the mapper
tresponse = test_app.get('/_test_vars')
mapper = tresponse.config.get('routes.map')
if mapper:
print mapper
class ShellCommand(Command):
"""Open an interactive shell with the Pylons app loaded
The optional CONFIG_FILE argument specifies the config file to use for
the interactive shell. CONFIG_FILE defaults to 'development.ini'.
This allows you to test your mapper, models, and simulate web requests
using ``paste.fixture``.
Example::
$ paster shell my-development.ini
"""
summary = __doc__.splitlines()[0]
usage = '\n' + __doc__
min_args = 0
max_args = 1
group_name = 'pylons'
parser = Command.standard_parser(simulate=True)
parser.add_option('-d', '--disable-ipython',
action='store_true',
dest='disable_ipython',
help="Don't use IPython if it is available")
parser.add_option('-q',
action='count',
dest='quiet',
default=0,
help=("Do not load logging configuration from the "
"config file"))
def command(self):
"""Main command to create a new shell"""
self.verbose = 3
if len(self.args) == 0:
# Assume the .ini file is ./development.ini
config_file = 'development.ini'
if not os.path.isfile(config_file):
raise BadCommand('%sError: CONFIG_FILE not found at: .%s%s\n'
'Please specify a CONFIG_FILE' % \
(self.parser.get_usage(), os.path.sep,
config_file))
else:
config_file = self.args[0]
config_name = 'config:%s' % config_file
here_dir = os.getcwd()
locs = dict(__name__="pylons-admin")
if not self.options.quiet:
# Configure logging from the config file
self.logging_file_config(config_file)
# Load locals and populate with objects for use in shell
sys.path.insert(0, here_dir)
# Load the wsgi app first so that everything is initialized right
wsgiapp = loadapp(config_name, relative_to=here_dir)
test_app = paste.fixture.TestApp(wsgiapp)
# Query the test app to setup the environment
tresponse = test_app.get('/_test_vars')
request_id = int(tresponse.body)
# Disable restoration during test_app requests
test_app.pre_request_hook = lambda self: \
paste.registry.restorer.restoration_end()
test_app.post_request_hook = lambda self: \
paste.registry.restorer.restoration_begin(request_id)
# Restore the state of the Pylons special objects
# (StackedObjectProxies)
paste.registry.restorer.restoration_begin(request_id)
# Determine the package name from the pylons.config object
pkg_name = pylons.config['pylons.package']
# Start the rest of our imports now that the app is loaded
if is_minimal_template(pkg_name, True):
model_module = None
helpers_module = pkg_name + '.helpers'
base_module = pkg_name + '.controllers'
else:
model_module = pkg_name + '.model'
helpers_module = pkg_name + '.lib.helpers'
base_module = pkg_name + '.lib.base'
if model_module and can_import(model_module):
locs['model'] = sys.modules[model_module]
if can_import(helpers_module):
locs['h'] = sys.modules[helpers_module]
exec ('from pylons import app_globals, config, request, response, '
'session, tmpl_context, url') in locs
exec ('from pylons.controllers.util import abort, redirect') in locs
exec 'from pylons.i18n import _, ungettext, N_' in locs
locs.pop('__builtins__', None)
# Import all objects from the base module
__import__(base_module)
base = sys.modules[base_module]
base_public = [__name for __name in dir(base) if not \
__name.startswith('_') or __name == '_']
locs.update((name, getattr(base, name)) for name in base_public)
locs.update(dict(wsgiapp=wsgiapp, app=test_app))
mapper = tresponse.config.get('routes.map')
if mapper:
locs['mapper'] = mapper
banner = " All objects from %s are available\n" % base_module
banner += " Additional Objects:\n"
if mapper:
banner += " %-10s - %s\n" % ('mapper', 'Routes mapper object')
banner += " %-10s - %s\n" % ('wsgiapp',
"This project's WSGI App instance")
banner += " %-10s - %s\n" % ('app',
'paste.fixture wrapped around wsgiapp')
try:
if self.options.disable_ipython:
raise ImportError()
# try to use IPython if possible
try:
try:
# 1.0 <= ipython
from IPython.terminal.embed import InteractiveShellEmbed
except ImportError:
# 0.11 <= ipython < 1.0
from IPython.frontend.terminal.embed import InteractiveShellEmbed
shell = InteractiveShellEmbed(banner2=banner)
except ImportError:
# ipython < 0.11
from IPython.Shell import IPShellEmbed
shell = IPShellEmbed(argv=self.args)
shell.set_banner(shell.IP.BANNER + '\n\n' + banner)
try:
shell(local_ns=locs, global_ns={})
finally:
paste.registry.restorer.restoration_end()
except ImportError:
import code
py_prefix = sys.platform.startswith('java') and 'J' or 'P'
newbanner = "Pylons Interactive Shell\n%sython %s\n\n" % \
(py_prefix, sys.version)
banner = newbanner + banner
shell = code.InteractiveConsole(locals=locs)
try:
import readline
except ImportError:
pass
try:
shell.interact(banner)
finally:
paste.registry.restorer.restoration_end()
================================================
FILE: pylons/configuration.py
================================================
"""Configuration object and defaults setup
The PylonsConfig object is initialized in pylons projects inside the
:file:`config/environment.py` module. Importing the :data:`config`
object from module causes the PylonsConfig object to be created, and
setup in app-safe manner so that multiple apps being setup avoid
conflicts.
After importing :data:`config`, the project should then call
:meth:`~PylonsConfig.init_app` with the appropriate options to setup
the configuration. In the config data passed with
:meth:`~PylonsConfig.init_app`, various defaults are set use with Paste
and Routes.
"""
import copy
import logging
import os
from paste.config import DispatchingConfig
from paste.deploy.converters import asbool
from webhelpers.mimehelper import MIMETypes
request_defaults = dict(charset='utf-8', errors='replace',
decode_param_names=False, language='en-us')
response_defaults = dict(content_type='text/html',
charset='utf-8', errors='strict',
headers={'Cache-Control': 'no-cache',
'Pragma': 'no-cache'})
log = logging.getLogger(__name__)
config = DispatchingConfig()
class PylonsConfig(dict):
"""Pylons configuration object
The Pylons configuration object is a per-application instance
object that retains the information regarding the global and app
conf's as well as per-application instance specific data such as
the mapper, and the paths for this instance.
The config object is available in your application as the Pylons
global :data:`pylons.config`. For example::
from pylons import config
template_paths = config['pylons.paths']['templates']
There's several useful keys of the config object most people will
be interested in:
``pylons.paths``
A dict of absolute paths that were defined in the applications
``config/environment.py`` module.
``pylons.environ_config``
Dict of environ keys for where in the environ to pickup various
objects for registering with Pylons. If these are present then
PylonsApp will use them from environ rather than using default
middleware from Beaker. Valid keys are: ``session, cache``
``pylons.strict_tmpl_context``
Whether or not the ``tmpl_context`` object should throw an
attribute error when access is attempted to an attribute that
doesn't exist. Defaults to True.
``pylons.tmpl_context_attach_args``
Whethor or not Routes variables should automatically be
attached to the tmpl_context object when specified in a
controllers method.
``pylons.request_options``
A dict of Content-Type related default settings for new
instances of :class:`~pylons.controllers.util.Request`. May
contain the values ``charset`` and ``errors`` and
``decode_param_names``. Overrides the Pylons default values
specified by the ``request_defaults`` dict.
``pylons.response_options``
A dict of Content-Type related default settings for new
instances of :class:`~pylons.controllers.util.Response`. May
contain the values ``content_type``, ``charset`` and
``errors``. Overrides the Pylons default values specified by
the ``response_defaults`` dict.
``routes.map``
Mapper object used for Routing. Yes, it is possible to add
routes after your application has started running.
"""
defaults = {
'debug': False,
'pylons.package': None,
'pylons.paths': {'root': None,
'controllers': None,
'templates': [],
'static_files': None},
'pylons.environ_config': dict(session='beaker.session',
cache='beaker.cache'),
'pylons.app_globals': None,
'pylons.h': None,
'pylons.request_options': request_defaults.copy(),
'pylons.response_options': response_defaults.copy(),
'pylons.strict_tmpl_context': True,
'pylons.tmpl_context_attach_args': False,
}
def init_app(self, global_conf, app_conf, package=None, paths=None):
"""Initialize configuration for the application
.. note
This *must* be called at least once, as soon as possible
to setup all the configuration options.
``global_conf``
Several options are expected to be set for a Pylons web
application. They will be loaded from the global_config
which has the main Paste options. If ``debug`` is not
enabled as a global config option, the following option
*must* be set:
* error_to - The email address to send the debug error to
The optional config options in this case are:
* smtp_server - The SMTP server to use, defaults to
'localhost'
* error_log - A logfile to write the error to
* error_subject_prefix - The prefix of the error email
subject
* from_address - Whom the error email should be from
``app_conf``
Defaults supplied via the [app:main] section from the Paste
config file. ``load_config`` only cares about whether a
'prefix' option is set, if so it will update Routes to
ensure URL's take that into account.
``package``
The name of the application package, to be stored in the
app_conf.
.. versionchanged:: 1.0
``template_engine`` option is no longer supported.
"""
log.debug("Initializing configuration, package: '%s'", package)
conf = global_conf.copy()
conf.update(app_conf)
conf.update(dict(app_conf=app_conf, global_conf=global_conf))
conf.update(self.pop('environment_load', {}))
if paths:
conf['pylons.paths'] = paths
conf['pylons.package'] = package
conf['debug'] = asbool(conf.get('debug'))
# Load the MIMETypes with its default types
MIMETypes.init()
# Ensure all the keys from defaults are present, load them if not
for key, val in copy.deepcopy(PylonsConfig.defaults).iteritems():
conf.setdefault(key, val)
# Load the errorware configuration from the Paste configuration file
# These all have defaults, and emails are only sent if configured and
# if this application is running in production mode
errorware = {}
errorware['debug'] = conf['debug']
if not errorware['debug']:
errorware['debug'] = False
errorware['error_email'] = conf.get('email_to')
errorware['error_log'] = conf.get('error_log', None)
errorware['smtp_server'] = conf.get('smtp_server',
'localhost')
errorware['error_subject_prefix'] = conf.get(
'error_subject_prefix', 'WebApp Error: ')
errorware['from_address'] = conf.get(
'from_address', conf.get('error_email_from',
'pylons@yourapp.com'))
errorware['error_message'] = conf.get('error_message',
'An internal server error occurred')
# Copy in some defaults
if 'cache_dir' in conf:
conf.setdefault('beaker.session.data_dir',
os.path.join(conf['cache_dir'], 'sessions'))
conf.setdefault('beaker.cache.data_dir',
os.path.join(conf['cache_dir'], 'cache'))
conf['pylons.cache_dir'] = conf.pop('cache_dir',
conf['app_conf'].get('cache_dir'))
# Save our errorware values
conf['pylons.errorware'] = errorware
# Load conf dict into self
self.update(conf)
pylons_config = PylonsConfig()
# Push an empty config so all accesses to config at import time have something
# to look at and modify. This config will be merged with the app's when it's
# built in the paste.app_factory entry point.
pylons_config.update(copy.deepcopy(PylonsConfig.defaults))
config.push_process_config(pylons_config)
================================================
FILE: pylons/controllers/__init__.py
================================================
"""Standard Controllers intended for subclassing by web developers"""
from pylons.controllers.core import WSGIController
from pylons.controllers.xmlrpc import XMLRPCController
from pylons.controllers.jsonrpc import JSONRPCController, JSONRPCError
================================================
FILE: pylons/controllers/core.py
================================================
"""The core WSGIController"""
import inspect
import logging
import types
from webob.exc import HTTPException, HTTPNotFound
import pylons
__all__ = ['WSGIController']
log = logging.getLogger(__name__)
class WSGIController(object):
"""WSGI Controller that follows WSGI spec for calling and return
values
The Pylons WSGI Controller handles incoming web requests that are
dispatched from the PylonsBaseWSGIApp. These requests result in a
new instance of the WSGIController being created, which is then
called with the dict options from the Routes match. The standard
WSGI response is then returned with start_response called as per
the WSGI spec.
Special WSGIController methods you may define:
``__before__``
This method is called before your action is, and should be used
for setting up variables/objects, restricting access to other
actions, or other tasks which should be executed before the
action is called.
``__after__``
This method is called after the action is, unless an unexpected
exception was raised. Subclasses of
:class:`~webob.exc.HTTPException` (such as those raised by
``redirect_to`` and ``abort``) are expected; e.g. ``__after__``
will be called on redirects.
Each action to be called is inspected with :meth:`_inspect_call` so
that it is only passed the arguments in the Routes match dict that
it asks for. The arguments passed into the action can be customized
by overriding the :meth:`_get_method_args` function which is
expected to return a dict.
In the event that an action is not found to handle the request, the
Controller will raise an "Action Not Found" error if in debug mode,
otherwise a ``404 Not Found`` error will be returned.
"""
_pylons_log_debug = False
def _perform_call(self, func, args):
"""Hide the traceback for everything above this method"""
__traceback_hide__ = 'before_and_this'
return func(**args)
def _inspect_call(self, func):
"""Calls a function with arguments from
:meth:`_get_method_args`
Given a function, inspect_call will inspect the function args
and call it with no further keyword args than it asked for.
If the function has been decorated, it is assumed that the
decorator preserved the function signature.
"""
# Check to see if the class has a cache of argspecs yet
try:
cached_argspecs = self.__class__._cached_argspecs
except AttributeError:
self.__class__._cached_argspecs = cached_argspecs = {}
# function could be callable
func_key = getattr(func, 'im_func', func.__call__)
try:
argspec = cached_argspecs[func_key]
except KeyError:
argspec = cached_argspecs[func_key] = inspect.getargspec(func_key)
kargs = self._get_method_args()
log_debug = self._pylons_log_debug
c = self._py_object.tmpl_context
environ = self._py_object.request.environ
args = None
if argspec[2]:
if self._py_object.config['pylons.tmpl_context_attach_args']:
for k, val in kargs.iteritems():
setattr(c, k, val)
args = kargs
else:
args = {}
argnames = argspec[0][isinstance(func, types.MethodType)
and 1 or 0:]
for name in argnames:
if name in kargs:
if self._py_object.config['pylons.tmpl_context_attach_args']:
setattr(c, name, kargs[name])
args[name] = kargs[name]
if log_debug:
log.debug("Calling %r method with keyword args: **%r",
func.__name__, args)
try:
result = self._perform_call(func, args)
except HTTPException, httpe:
if log_debug:
log.debug("%r method raised HTTPException: %s (code: %s)",
func.__name__, httpe.__class__.__name__,
httpe.wsgi_response.code, exc_info=True)
result = httpe
# Store the exception in the environ
environ['pylons.controller.exception'] = httpe
# 304 Not Modified's shouldn't have a content-type set
if result.wsgi_response.status_int == 304:
result.wsgi_response.headers.pop('Content-Type', None)
result._exception = True
return result
def _get_method_args(self):
"""Retrieve the method arguments to use with inspect call
By default, this uses Routes to retrieve the arguments,
override this method to customize the arguments your controller
actions are called with.
This method should return a dict.
"""
req = self._py_object.request
kargs = req.environ['pylons.routes_dict'].copy()
kargs['environ'] = req.environ
kargs['start_response'] = self.start_response
kargs['pylons'] = self._py_object
return kargs
def _dispatch_call(self):
"""Handles dispatching the request to the function using
Routes"""
log_debug = self._pylons_log_debug
req = self._py_object.request
try:
action = req.environ['pylons.routes_dict']['action']
except KeyError:
raise Exception("No action matched from Routes, unable to"
"determine action dispatch.")
action_method = action.replace('-', '_')
if log_debug:
log.debug("Looking for %r method to handle the request",
action_method)
try:
func = getattr(self, action_method, None)
except UnicodeEncodeError:
func = None
if action_method != 'start_response' and callable(func):
# Store function used to handle request
req.environ['pylons.action_method'] = func
response = self._inspect_call(func)
else:
if log_debug:
log.debug("Couldn't find %r method to handle response", action)
if pylons.config['debug']:
raise NotImplementedError('Action %r is not implemented' %
action)
else:
response = HTTPNotFound()
return response
def __call__(self, environ, start_response):
"""The main call handler that is called to return a response"""
log_debug = self._pylons_log_debug
# Keep a local reference to the req/response objects
self._py_object = environ['pylons.pylons']
# Keep private methods private
try:
if environ['pylons.routes_dict']['action'][:1] in ('_', '-'):
if log_debug:
log.debug("Action starts with _, private action not "
"allowed. Returning a 404 response")
return HTTPNotFound()(environ, start_response)
except KeyError:
# The check later will notice that there's no action
pass
start_response_called = []
def repl_start_response(status, headers, exc_info=None):
response = self._py_object.response
start_response_called.append(None)
# Copy the headers from the global response
if log_debug:
log.debug("Merging pylons.response headers into "
"start_response call, status: %s", status)
headers.extend(header for header in response.headerlist
if header[0] == 'Set-Cookie' or
header[0].startswith('X-'))
return start_response(status, headers, exc_info)
self.start_response = repl_start_response
if hasattr(self, '__before__'):
response = self._inspect_call(self.__before__)
if hasattr(response, '_exception'):
return response(environ, self.start_response)
response = self._dispatch_call()
if not start_response_called:
self.start_response = start_response
py_response = self._py_object.response
# If its not a WSGI response, and we have content, it needs to
# be wrapped in the response object
if isinstance(response, str):
if log_debug:
log.debug("Controller returned a string "
", writing it to pylons.response")
py_response.body = py_response.body + response
elif isinstance(response, unicode):
if log_debug:
log.debug("Controller returned a unicode string "
", writing it to pylons.response")
py_response.unicode_body = py_response.unicode_body + \
response
elif hasattr(response, 'wsgi_response'):
# It's an exception that got tossed.
if log_debug:
log.debug("Controller returned a Response object, merging "
"it with pylons.response")
for name, value in py_response.headers.items():
if name.lower() == 'set-cookie':
response.headers.add(name, value)
else:
response.headers.setdefault(name, value)
try:
registry = environ['paste.registry']
registry.replace(pylons.response, response)
except KeyError:
# Ignore the case when someone removes the registry
pass
py_response = response
elif response is None:
if log_debug:
log.debug("Controller returned None")
else:
if log_debug:
log.debug("Assuming controller returned an iterable, "
"setting it as pylons.response.app_iter")
py_response.app_iter = response
response = py_response
if hasattr(self, '__after__'):
after = self._inspect_call(self.__after__)
if hasattr(after, '_exception'):
after.wsgi_response = True
response = after
if hasattr(response, 'wsgi_response'):
# Copy the response object into the testing vars if we're testing
if 'paste.testing_variables' in environ:
environ['paste.testing_variables']['response'] = response
if log_debug:
log.debug("Calling Response object to return WSGI data")
return response(environ, self.start_response)
if log_debug:
log.debug("Response assumed to be WSGI content, returning "
"un-touched")
return response
================================================
FILE: pylons/controllers/jsonrpc.py
================================================
"""The base WSGI JSONRPCController"""
import inspect
import json
import logging
import types
import urllib
from paste.response import replace_header
from pylons.controllers import WSGIController
from pylons.controllers.util import abort, Response
__all__ = ['JSONRPCController', 'JSONRPCError',
'JSONRPC_PARSE_ERROR',
'JSONRPC_INVALID_REQUEST',
'JSONRPC_METHOD_NOT_FOUND',
'JSONRPC_INVALID_PARAMS',
'JSONRPC_INTERNAL_ERROR']
log = logging.getLogger(__name__)
JSONRPC_VERSION = '2.0'
class JSONRPCError(BaseException):
def __init__(self, code, message):
self.code = code
self.message = message
self.data = None
def __str__(self):
return str(self.code) + ': ' + self.message
def as_dict(self):
"""Return a dictionary representation of this object for
serialization in a JSON-RPC response."""
error = dict(code=self.code,
message=self.message)
if self.data:
error['data'] = self.data
return error
JSONRPC_PARSE_ERROR = JSONRPCError(-32700, "Parse error")
JSONRPC_INVALID_REQUEST = JSONRPCError(-32600, "Invalid Request")
JSONRPC_METHOD_NOT_FOUND = JSONRPCError(-32601, "Method not found")
JSONRPC_INVALID_PARAMS = JSONRPCError(-32602, "Invalid params")
JSONRPC_INTERNAL_ERROR = JSONRPCError(-32603, "Internal error")
_reserved_errors = dict(parse_error=JSONRPC_PARSE_ERROR,
invalid_request=JSONRPC_INVALID_REQUEST,
method_not_found=JSONRPC_METHOD_NOT_FOUND,
invalid_params=JSONRPC_INVALID_PARAMS,
internal_error=JSONRPC_INTERNAL_ERROR)
def jsonrpc_error(req_id, error):
"""Generate a Response object with a JSON-RPC error body. Used to
raise top-level pre-defined errors that happen outside the
controller."""
if error in _reserved_errors:
err = _reserved_errors[error]
return Response(body=json.dumps(dict(jsonrpc=JSONRPC_VERSION,
id=req_id,
error=err.as_dict())))
class JSONRPCController(WSGIController):
"""
A WSGI-speaking JSON-RPC 2.0 controller class
See the specification:
`<http://groups.google.com/group/json-rpc/web/json-rpc-2-0>`.
Many parts of this controller are modelled after XMLRPCController
from Pylons 0.9.7
Valid controller return values should be json-serializable objects.
Sub-classes should catch their exceptions and raise JSONRPCError
if they want to pass meaningful errors to the client. Unhandled
errors should be caught and return JSONRPC_INTERNAL_ERROR to the
client.
Parts of the specification not supported (yet):
- Notifications
- Batch
"""
def _get_method_args(self):
"""Return `self._rpc_args` to dispatched controller method
chosen by __call__"""
return self._rpc_args
def __call__(self, environ, start_response):
"""Parse the request body as JSON, look up the method on the
controller and if it exists, dispatch to it.
"""
length = 0
if 'CONTENT_LENGTH' not in environ:
log.debug("No Content-Length")
abort(411)
else:
if environ['CONTENT_LENGTH'] == '':
abort(411)
length = int(environ['CONTENT_LENGTH'])
log.debug('Content-Length: %s', length)
if length == 0:
log.debug("Content-Length is 0")
abort(411)
raw_body = environ['wsgi.input'].read(length)
json_body = json.loads(urllib.unquote_plus(raw_body))
self._req_id = json_body['id']
self._req_method = json_body['method']
self._req_params = json_body['params']
log.debug('id: %s, method: %s, params: %s',
self._req_id,
self._req_method,
self._req_params)
self._error = None
try:
self._func = self._find_method()
except AttributeError:
err = jsonrpc_error(self._req_id, 'method_not_found')
return err(environ, start_response)
# now that we have a method, make sure we have enough
# parameters and pass off control to the controller.
if not isinstance(self._req_params, dict):
# JSON-RPC version 1 request.
arglist = inspect.getargspec(self._func)[0][1:]
if len(self._req_params) < len(arglist):
err = jsonrpc_error(self._req_id, 'invalid_params')
return err(environ, start_response)
else:
kargs = dict(zip(arglist, self._req_params))
else:
# JSON-RPC version 2 request. Params may be default, and
# are already a dict, so skip the parameter length check here.
kargs = self._req_params
# XX Fix this namespace clash. One cannot use names below as
# method argument names as this stands!
kargs['action'], kargs['environ'] = self._req_method, environ
kargs['start_response'] = start_response
self._rpc_args = kargs
status = []
headers = []
exc_info = []
def change_content(new_status, new_headers, new_exc_info=None):
status.append(new_status)
headers.extend(new_headers)
exc_info.append(new_exc_info)
output = WSGIController.__call__(self, environ, change_content)
output = list(output)
headers.append(('Content-Length', str(len(output[0]))))
replace_header(headers, 'Content-Type', 'application/json')
start_response(status[0], headers, exc_info[0])
return output
def _dispatch_call(self):
"""Implement dispatch interface specified by WSGIController"""
try:
raw_response = self._inspect_call(self._func)
except JSONRPCError, e:
self._error = e.as_dict()
except TypeError, e:
# Insufficient args in an arguments dict v2 call.
if 'takes at least' in str(e):
err = _reserved_errors['invalid_params']
self._error = err.as_dict()
else:
raise
except Exception, e:
log.debug('Encountered unhandled exception: %s', repr(e))
err = _reserved_errors['internal_error']
self._error = err.as_dict()
response = dict(jsonrpc=JSONRPC_VERSION,
id=self._req_id)
if self._error is not None:
response['error'] = self._error
else:
response['result'] = raw_response
try:
return json.dumps(response)
except TypeError, e:
log.debug('Error encoding response: %s', e)
err = _reserved_errors['internal_error']
return json.dumps(dict(
jsonrpc=JSONRPC_VERSION,
id=self._req_id,
error=err.as_dict()))
def _find_method(self):
"""Return method named by `self._req_method` in controller if able"""
log.debug('Trying to find JSON-RPC method: %s', self._req_method)
if self._req_method.startswith('_'):
raise AttributeError("Method not allowed")
try:
func = getattr(self, self._req_method, None)
except UnicodeEncodeError:
# XMLRPCController catches this, not sure why.
raise AttributeError("Problem decoding unicode in requested "
"method name.")
if isinstance(func, types.MethodType):
return func
else:
raise AttributeError("No such method: %s" % self._req_method)
================================================
FILE: pylons/controllers/util.py
================================================
"""Utility functions and classes available for use by Controllers
Pylons subclasses the `WebOb <http://pythonpaste.org/webob/>`_
:class:`webob.Request` and :class:`webob.Response` classes to provide
backwards compatible functions for earlier versions of Pylons as well
as add a few helper functions to assist with signed cookies.
For reference use, refer to the :class:`Request` and :class:`Response`
below.
Functions available:
:func:`abort`, :func:`forward`, :func:`etag_cache`,
:func:`mimetype` and :func:`redirect`
"""
import base64
import binascii
import hmac
import logging
import re
try:
import cPickle as pickle
except ImportError:
import pickle
try:
from hashlib import sha1
except ImportError:
import sha as sha1
from webob import BaseRequest as WebObRequest
from webob import Response as WebObResponse
from webob.exc import status_map
import pylons
__all__ = ['abort', 'etag_cache', 'redirect', 'Request', 'Response']
log = logging.getLogger(__name__)
IF_NONE_MATCH = re.compile('(?:W/)?(?:"([^"]*)",?\s*)')
class Request(WebObRequest):
"""WebOb Request subclass
The WebOb :class:`webob.Request` has no charset, or other defaults. This subclass
adds defaults, along with several methods for backwards
compatibility with paste.wsgiwrappers.WSGIRequest.
"""
def determine_browser_charset(self):
"""Legacy method to return the
:attr:`webob.Request.accept_charset`"""
return self.accept_charset
def languages(self):
# And we now have the old best_matches code that webob ditched!
al = self.accept_language
try:
items = [i for i, q in sorted(al._parsed, key=lambda iq: -iq[1])]
for index, item in enumerate(items):
if al._match(item, self.language):
items[index:] = [self.language]
break
else:
items.append(self.language)
return items
except AttributeError:
# If its a NilAccept, there won't be a _parsed attribute
# Return the best match instead
return [self.accept_language.best_match(self.language)]
languages = property(languages)
def match_accept(self, mimetypes):
return self.accept.first_match(mimetypes)
def signed_cookie(self, name, secret):
"""Extract a signed cookie of ``name`` from the request
The cookie is expected to have been created with
``Response.signed_cookie``, and the ``secret`` should be the
same as the one used to sign it.
Any failure in the signature of the data will result in None
being returned.
"""
cookie = self.str_cookies.get(name)
if not cookie:
return None
try:
input_sig, pickled = cookie[:40], base64.standard_b64decode(cookie[40:])
except binascii.Error:
# Badly formed data can make base64 die
return None
sig = hmac.new(secret, pickled, sha1).hexdigest()
# Avoid timing attacks
invalid_bits = 0
if len(sig) != len(input_sig):
return None
for a, b in zip(sig, input_sig):
invalid_bits += a != b
if invalid_bits:
return None
else:
return pickle.loads(pickled)
class Response(WebObResponse):
"""WebOb Response subclass
The WebOb Response has no default content type, or error defaults.
This subclass adds defaults, along with several methods for
backwards compatibility with paste.wsgiwrappers.WSGIResponse.
"""
content = WebObResponse.body
def determine_charset(self):
return self.charset
def has_header(self, header):
return header in self.headers
def get_content(self):
return self.body
def wsgi_response(self):
return self.status, self.headers, self.body
def signed_cookie(self, name, data, secret=None, **kwargs):
"""Save a signed cookie with ``secret`` signature
Saves a signed cookie of the pickled data. All other keyword
arguments that ``WebOb.set_cookie`` accepts are usable and
passed to the WebOb set_cookie method after creating the signed
cookie value.
"""
pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL)
sig = hmac.new(secret, pickled, sha1).hexdigest()
self.set_cookie(name, sig + base64.standard_b64encode(pickled), **kwargs)
def etag_cache(key=None):
"""Use the HTTP Entity Tag cache for Browser side caching
If a "If-None-Match" header is found, and equivilant to ``key``,
then a ``304`` HTTP message will be returned with the ETag to tell
the browser that it should use its current cache of the page.
Otherwise, the ETag header will be added to the response headers.
Suggested use is within a Controller Action like so:
.. code-block:: python
import pylons
class YourController(BaseController):
def index(self):
etag_cache(key=1)
return render('/splash.mako')
.. note::
This works because etag_cache will raise an HTTPNotModified
exception if the ETag received matches the key provided.
"""
if_none_matches = IF_NONE_MATCH.findall(
pylons.request.environ.get('HTTP_IF_NONE_MATCH', ''))
response = pylons.response._current_obj()
response.headers['ETag'] = '"%s"' % key
if str(key) in if_none_matches:
log.debug("ETag match, returning 304 HTTP Not Modified Response")
response.headers.pop('Content-Type', None)
response.headers.pop('Cache-Control', None)
response.headers.pop('Pragma', None)
raise status_map[304]()
else:
log.debug("ETag didn't match, returning response object")
def forward(wsgi_app):
"""Forward the request to a WSGI application. Returns its response.
.. code-block:: python
return forward(FileApp('filename'))
"""
environ = pylons.request.environ
controller = environ.get('pylons.controller')
if not controller or not hasattr(controller, 'start_response'):
raise RuntimeError("Unable to forward: environ['pylons.controller'] "
"is not a valid Pylons controller")
return wsgi_app(environ, controller.start_response)
def abort(status_code=None, detail="", headers=None, comment=None):
"""Aborts the request immediately by returning an HTTP exception
In the event that the status_code is a 300 series error, the detail
attribute will be used as the Location header should one not be
specified in the headers attribute.
"""
exc = status_map[status_code](detail=detail, headers=headers,
comment=comment)
log.debug("Aborting request, status: %s, detail: %r, headers: %r, "
"comment: %r", status_code, detail, headers, comment)
raise exc
def redirect(url, code=302):
"""Raises a redirect exception to the specified URL
Optionally, a code variable may be passed with the status code of
the redirect, ie::
redirect(url(controller='home', action='index'), code=303)
"""
log.debug("Generating %s redirect" % code)
exc = status_map[code]
raise exc(location=url.encode('utf-8'))
================================================
FILE: pylons/controllers/xmlrpc.py
================================================
"""The base WSGI XMLRPCController"""
import inspect
import logging
import types
import xmlrpclib
from paste.response import replace_header
from pylons.controllers import WSGIController
from pylons.controllers.util import abort, Response
__all__ = ['XMLRPCController']
log = logging.getLogger(__name__)
XMLRPC_MAPPING = ((basestring, 'string'), (list, 'array'), (bool, 'boolean'),
(int, 'int'), (float, 'double'), (dict, 'struct'),
(xmlrpclib.DateTime, 'dateTime.iso8601'),
(xmlrpclib.Binary, 'base64'))
def xmlrpc_sig(args):
"""Returns a list of the function signature in string format based on a
tuple provided by xmlrpclib."""
signature = []
for param in args:
for type, xml_name in XMLRPC_MAPPING:
if isinstance(param, type):
signature.append(xml_name)
break
return signature
def xmlrpc_fault(code, message):
"""Convienence method to return a Pylons response XMLRPC Fault"""
fault = xmlrpclib.Fault(code, message)
return Response(body=xmlrpclib.dumps(fault, methodresponse=True))
class XMLRPCController(WSGIController):
"""XML-RPC Controller that speaks WSGI
This controller handles XML-RPC responses and complies with the
`XML-RPC Specification <http://www.xmlrpc.com/spec>`_ as well as
the `XML-RPC Introspection
<http://scripts.incutio.com/xmlrpc/introspection.html>`_
specification.
By default, methods with names containing a dot are translated to
use an underscore. For example, the `system.methodHelp` is handled
by the method :meth:`system_methodHelp`.
Methods in the XML-RPC controller will be called with the method
given in the XMLRPC body. Methods may be annotated with a signature
attribute to declare the valid arguments and return types.
For example::
class MyXML(XMLRPCController):
def userstatus(self):
return 'basic string'
userstatus.signature = [ ['string'] ]
def userinfo(self, username, age=None):
user = LookUpUser(username)
response = {'username':user.name}
if age and age > 10:
response['age'] = age
return response
userinfo.signature = [['struct', 'string'],
['struct', 'string', 'int']]
Since XML-RPC methods can take different sets of data, each set of
valid arguments is its own list. The first value in the list is the
type of the return argument. The rest of the arguments are the
types of the data that must be passed in.
In the last method in the example above, since the method can
optionally take an integer value both sets of valid parameter lists
should be provided.
Valid types that can be checked in the signature and their
corresponding Python types::
'string' - str
'array' - list
'boolean' - bool
'int' - int
'double' - float
'struct' - dict
'dateTime.iso8601' - xmlrpclib.DateTime
'base64' - xmlrpclib.Binary
The class variable ``allow_none`` is passed to xmlrpclib.dumps;
enabling it allows translating ``None`` to XML (an extension to the
XML-RPC specification)
.. note::
Requiring a signature is optional.
"""
allow_none = False
max_body_length = 4194304
def _get_method_args(self):
return self.rpc_kargs
def __call__(self, environ, start_response):
"""Parse an XMLRPC body for the method, and call it with the
appropriate arguments"""
# Pull out the length, return an error if there is no valid
# length or if the length is larger than the max_body_length.
log_debug = self._pylons_log_debug
length = environ.get('CONTENT_LENGTH')
if length:
length = int(length)
else:
# No valid Content-Length header found
if log_debug:
log.debug("No Content-Length found, returning 411 error")
abort(411)
if length > self.max_body_length or length == 0:
if log_debug:
log.debug("Content-Length larger than max body length. Max: "
"%s, Sent: %s. Returning 413 error",
self.max_body_length, length)
abort(413, "XML body too large")
body = environ['wsgi.input'].read(int(environ['CONTENT_LENGTH']))
rpc_args, orig_method = xmlrpclib.loads(body)
method = self._find_method_name(orig_method)
func = self._find_method(method)
if not func:
if log_debug:
log.debug("Method: %r not found, returning xmlrpc fault",
method)
return xmlrpc_fault(0, "No such method name %r" %
method)(environ, start_response)
# Signature checking for params
if hasattr(func, 'signature'):
if log_debug:
log.debug("Checking XMLRPC argument signature")
valid_args = False
params = xmlrpc_sig(rpc_args)
for sig in func.signature:
# Next sig if we don't have the same amount of args
if len(sig) - 1 != len(rpc_args):
continue
# If the params match, we're valid
if params == sig[1:]:
valid_args = True
break
if not valid_args:
if log_debug:
log.debug("Bad argument signature recieved, returning "
"xmlrpc fault")
msg = ("Incorrect argument signature. %r recieved does not "
"match %r signature for method %r" % \
(params, func.signature, orig_method))
return xmlrpc_fault(0, msg)(environ, start_response)
# Change the arg list into a keyword dict based off the arg
# names in the functions definition
arglist = inspect.getargspec(func)[0][1:]
kargs = dict(zip(arglist, rpc_args))
kargs['action'], kargs['environ'] = method, environ
kargs['start_response'] = start_response
self.rpc_kargs = kargs
self._func = func
# Now that we know the method is valid, and the args are valid,
# we can dispatch control to the default WSGIController
status = []
headers = []
exc_info = []
def change_content(new_status, new_headers, new_exc_info=None):
status.append(new_status)
headers.extend(new_headers)
exc_info.append(new_exc_info)
output = WSGIController.__call__(self, environ, change_content)
output = list(output)
headers.append(('Content-Length', str(len(output[0]))))
replace_header(headers, 'Content-Type', 'text/xml')
start_response(status[0], headers, exc_info[0])
return output
def _dispatch_call(self):
"""Dispatch the call to the function chosen by __call__"""
raw_response = self._inspect_call(self._func)
if not isinstance(raw_response, xmlrpclib.Fault):
raw_response = (raw_response,)
response = xmlrpclib.dumps(raw_response, methodresponse=True,
allow_none=self.allow_none)
return response
def _find_method(self, name):
"""Locate a method in the controller by the specified name and
return it"""
# Keep private methods private
if name.startswith('_'):
if self._pylons_log_debug:
log.debug("Action starts with _, private action not allowed")
return
if self._pylons_log_debug:
log.debug("Looking for XMLRPC method: %r", name)
try:
func = getattr(self, name, None)
except UnicodeEncodeError:
return
if isinstance(func, types.MethodType):
return func
def _find_method_name(self, name):
"""Locate a method in the controller by the appropriate name
By default, this translates method names like
'system.methodHelp' into 'system_methodHelp'.
"""
return name.replace('.', '_')
def _publish_method_name(self, name):
"""Translate an internal method name to a publicly viewable one
By default, this translates internal method names like
'blog_view' into 'blog.view'.
"""
return name.replace('_', '.')
def system_listMethods(self):
"""Returns a list of XML-RPC methods for this XML-RPC resource"""
methods = []
for method in dir(self):
meth = getattr(self, method)
if not method.startswith('_') and isinstance(meth,
types.MethodType):
methods.append(self._publish_method_name(method))
return methods
system_listMethods.signature = [['array']]
def system_methodSignature(self, name):
"""Returns an array of array's for the valid signatures for a
method.
The first value of each array is the return value of the
method. The result is an array to indicate multiple signatures
a method may be capable of.
"""
method = self._find_method(self._find_method_name(name))
if method:
return getattr(method, 'signature', '')
else:
return xmlrpclib.Fault(0, 'No such method name')
system_methodSignature.signature = [['array', 'string'],
['string', 'string']]
def system_methodHelp(self, name):
"""Returns the documentation for a method"""
method = self._find_method(self._find_method_name(name))
if method:
help = MethodHelp.getdoc(method)
sig = getattr(method, 'signature', None)
if sig:
help += "\n\nMethod signature: %s" % sig
return help
return xmlrpclib.Fault(0, "No such method name")
system_methodHelp.signature = [['string', 'string']]
class MethodHelp(object):
"""Wrapper for formatting doc strings from XMLRPCController
methods"""
def __init__(self, doc):
self.__doc__ = doc
def getdoc(method):
"""Return a formatted doc string, via inspect.getdoc, from the
specified XMLRPCController method
The method's help attribute is used if it exists, otherwise the
method's doc string is used.
"""
help = getattr(method, 'help', None)
if help is None:
help = method.__doc__
doc = inspect.getdoc(MethodHelp(help))
if doc is None:
return ''
return doc
getdoc = staticmethod(getdoc)
================================================
FILE: pylons/decorators/__init__.py
================================================
"""Pylons Decorators
Common decorators intended for use in controllers. Additional
decorators for use with controllers are in the
:mod:`~pylons.decorators.cache`, :mod:`~pylons.decorators.rest` and
:mod:`~pylons.decorators.secure` modules.
"""
import logging
import warnings
import formencode
import simplejson
from decorator import decorator
from formencode import api, htmlfill, variabledecode
from pylons.decorators.util import get_pylons
from pylons.i18n import _ as pylons_gettext
__all__ = ['jsonify', 'validate']
log = logging.getLogger(__name__)
class JSONEncoder(simplejson.JSONEncoder):
def default(self, obj):
encoder = getattr(obj, '__json__', None)
if encoder is not None:
return encoder()
return super(JSONEncoder, self).default(obj)
@decorator
def jsonify(func, *args, **kwargs):
"""Action decorator that formats output for JSON
Given a function that will return content, this decorator will turn
the result into JSON, with a content-type of 'application/json' and
output it.
"""
pylons = get_pylons(args)
pylons.response.headers['Content-Type'] = 'application/json; charset=utf-8'
data = func(*args, **kwargs)
if isinstance(data, (list, tuple)):
msg = "JSON responses with Array envelopes are susceptible to " \
"cross-site data leak attacks, see " \
"http://wiki.pylonshq.com/display/pylonsfaq/Warnings"
warnings.warn(msg, Warning, 2)
log.warning(msg)
log.debug("Returning JSON wrapped action output")
return simplejson.dumps(data, cls=JSONEncoder, encoding='utf-8')
def validate(schema=None, validators=None, form=None, variable_decode=False,
dict_char='.', list_char='-', post_only=True, state=None,
on_get=False, **htmlfill_kwargs):
"""Validate input either for a FormEncode schema, or individual
validators
Given a form schema or dict of validators, validate will attempt to
validate the schema or validator list.
If validation was successful, the valid result dict will be saved
as ``self.form_result``. Otherwise, the action will be re-run as if
it was a GET, and the output will be filled by FormEncode's
htmlfill to fill in the form field errors.
``schema``
Refers to a FormEncode Schema object to use during validation.
``form``
Method used to display the form, which will be used to get the
HTML representation of the form for error filling.
``variable_decode``
Boolean to indicate whether FormEncode's variable decode
function should be run on the form input before validation.
``dict_char``
Passed through to FormEncode. Toggles the form field naming
scheme used to determine what is used to represent a dict. This
option is only applicable when used with variable_decode=True.
``list_char``
Passed through to FormEncode. Toggles the form field naming
scheme used to determine what is used to represent a list. This
option is only applicable when used with variable_decode=True.
``post_only``
Boolean that indicates whether or not GET (query) variables
should be included during validation.
.. warning::
``post_only`` applies to *where* the arguments to be
validated come from. It does *not* restrict the form to
only working with post, merely only checking POST vars.
``state``
Passed through to FormEncode for use in validators that utilize
a state object.
``on_get``
Whether to validate on GET requests. By default only POST
requests are validated.
Example::
class SomeController(BaseController):
def create(self, id):
return render('/myform.mako')
@validate(schema=model.forms.myshema(), form='create')
def update(self, id):
# Do something with self.form_result
pass
"""
if state is None:
state = PylonsFormEncodeState
def wrapper(func, self, *args, **kwargs):
"""Decorator Wrapper function"""
request = self._py_object.request
errors = {}
# Skip the validation if on_get is False and its a GET
if not on_get and request.environ['REQUEST_METHOD'] == 'GET':
return func(self, *args, **kwargs)
# If they want post args only, use just the post args
if post_only:
params = request.POST
else:
params = request.params
params = params.mixed()
if variable_decode:
log.debug("Running variable_decode on params")
decoded = variabledecode.variable_decode(params, dict_char,
list_char)
else:
decoded = params
if schema:
log.debug("Validating against a schema")
try:
self.form_result = schema.to_python(decoded, state)
except formencode.Invalid, e:
errors = e.unpack_errors(variable_decode, dict_char, list_char)
if validators:
log.debug("Validating against provided validators")
if isinstance(validators, dict):
if not hasattr(self, 'form_result'):
self.form_result = {}
for field, validator in validators.iteritems():
try:
self.form_result[field] = \
validator.to_python(decoded.get(field), state)
except formencode.Invalid, error:
errors[field] = error
if errors:
log.debug("Errors found in validation, parsing form with htmlfill "
"for errors")
request.environ['REQUEST_METHOD'] = 'GET'
self._py_object.tmpl_context.form_errors = errors
# If there's no form supplied, just continue with the current
# function call.
if not form:
return func(self, *args, **kwargs)
request.environ['pylons.routes_dict']['action'] = form
response = self._dispatch_call()
# If the form_content is an exception response, return it
if hasattr(response, '_exception'):
return response
htmlfill_kwargs2 = htmlfill_kwargs.copy()
htmlfill_kwargs2.setdefault('encoding', request.charset)
return htmlfill.render(response, defaults=params, errors=errors,
**htmlfill_kwargs2)
return func(self, *args, **kwargs)
return decorator(wrapper)
def pylons_formencode_gettext(value):
"""Translates a string ``value`` using pylons gettext first and if
that fails, formencode gettext.
This allows to "merge" localized error messages from built-in
FormEncode's validators with application-specific validators.
"""
trans = pylons_gettext(value)
if trans == value:
# translation failed, try formencode
trans = api._stdtrans(value)
return trans
class PylonsFormEncodeState(object):
"""A ``state`` for FormEncode validate API that includes smart
``_`` hook.
The FormEncode library used by validate() decorator has some
provision for localizing error messages. In particular, it looks
for attribute ``_`` in the application-specific state object that
gets passed to every ``.to_python()`` call. If it is found, the
``_`` is assumed to be a gettext-like function and is called to
localize error messages.
One complication is that FormEncode ships with localized error
messages for standard validators so the user may want to re-use
them instead of gathering and translating everything from scratch.
To allow this, we pass as ``_`` a function which looks up
translation both in application and formencode message catalogs.
"""
_ = staticmethod(pylons_formencode_gettext)
================================================
FILE: pylons/decorators/cache.py
================================================
"""Caching decorator"""
import inspect
import logging
import time
from decorator import decorator
from paste.deploy.converters import asbool
from pylons.decorators.util import get_pylons
log = logging.getLogger(__name__)
def beaker_cache(key="cache_default", expire="never", type=None,
query_args=False,
cache_headers=('content-type', 'content-length'),
invalidate_on_startup=False,
cache_response=True, **b_kwargs):
"""Cache decorator utilizing Beaker. Caches action or other
function that returns a pickle-able object as a result.
Optional arguments:
``key``
None - No variable key, uses function name as key
"cache_default" - Uses all function arguments as the key
string - Use kwargs[key] as key
list - Use [kwargs[k] for k in list] as key
``expire``
Time in seconds before cache expires, or the string "never".
Defaults to "never"
``type``
Type of cache to use: dbm, memory, file, memcached, or None for
Beaker's default
``query_args``
Uses the query arguments as the key, defaults to False
``cache_headers``
A tuple of header names indicating response headers that
will also be cached.
``invalidate_on_startup``
If True, the cache will be invalidated each time the application
starts or is restarted.
``cache_response``
Determines whether the response at the time beaker_cache is used
should be cached or not, defaults to True.
.. note::
When cache_response is set to False, the cache_headers
argument is ignored as none of the response is cached.
If cache_enabled is set to False in the .ini file, then cache is
disabled globally.
"""
if invalidate_on_startup:
starttime = time.time()
else:
starttime = None
cache_headers = set(cache_headers)
def wrapper(func, *args, **kwargs):
"""Decorator wrapper"""
pylons = get_pylons(args)
log.debug("Wrapped with key: %s, expire: %s, type: %s, query_args: %s",
key, expire, type, query_args)
enabled = pylons.config.get("cache_enabled", "True")
if not asbool(enabled):
log.debug("Caching disabled, skipping cache lookup")
return func(*args, **kwargs)
if key:
key_dict = kwargs.copy()
key_dict.update(_make_dict_from_args(func, args))
if query_args:
key_dict.update(pylons.request.GET.mixed())
if key != "cache_default":
if isinstance(key, list):
key_dict = dict((k, key_dict[k]) for k in key)
else:
key_dict = {key: key_dict[key]}
else:
key_dict = None
self = None
if args:
self = args[0]
namespace, cache_key = create_cache_key(func, key_dict, self)
if type:
b_kwargs['type'] = type
cache_obj = getattr(pylons.app_globals, 'cache', None)
if not cache_obj:
cache_obj = getattr(pylons, 'cache', None)
if not cache_obj:
raise Exception('No CacheMiddleware or cache object on '
' app_globals was found')
my_cache = cache_obj.get_cache(namespace, **b_kwargs)
if expire == "never":
cache_expire = None
else:
cache_expire = expire
def create_func():
log.debug("Creating new cache copy with key: %s, type: %s",
cache_key, type)
result = func(*args, **kwargs)
glob_response = pylons.response
headers = glob_response.headerlist
status = glob_response.status
full_response = dict(headers=headers, status=status,
cookies=None, content=result)
return full_response
response = my_cache.get_value(cache_key, createfunc=create_func,
expiretime=cache_expire,
starttime=starttime)
if cache_response:
glob_response = pylons.response
glob_response.headerlist = [header for header in response['headers']
if header[0].lower() in cache_headers]
glob_response.status = response['status']
return response['content']
return decorator(wrapper)
def create_cache_key(func, key_dict=None, self=None):
"""Get a cache namespace and key used by the beaker_cache decorator.
Example::
from pylons import cache
from pylons.decorators.cache import create_cache_key
namespace, key = create_cache_key(MyController.some_method)
cache.get_cache(namespace).remove(key)
"""
kls = None
if hasattr(func, 'im_func'):
kls = func.im_class
func = func.im_func
cache_key = func.__name__
else:
cache_key = func.__name__
if key_dict:
cache_key += " " + " ".join("%s=%s" % (k, v)
for k, v in key_dict.iteritems())
if not kls and self:
kls = getattr(self, '__class__', None)
if kls:
return '%s.%s' % (kls.__module__, kls.__name__), cache_key
else:
return func.__module__, cache_key
def _make_dict_from_args(func, args):
"""Inspects function for name of args"""
args_keys = {}
for i, arg in enumerate(inspect.getargspec(func)[0]):
if arg != "self":
args_keys[arg] = args[i]
return args_keys
================================================
FILE: pylons/decorators/rest.py
================================================
"""REST decorators"""
import logging
from decorator import decorator
from pylons.controllers.util import abort
from pylons.decorators.util import get_pylons
__all__ = ['dispatch_on', 'restrict']
log = logging.getLogger(__name__)
def restrict(*methods):
"""Restricts access to the function depending on HTTP method
Example:
.. code-block:: python
from pylons.decorators import rest
class SomeController(BaseController):
@rest.restrict('GET')
def comment(self, id):
"""
def check_methods(func, *args, **kwargs):
"""Wrapper for restrict"""
if get_pylons(args).request.method not in methods:
log.debug("Method not allowed by restrict")
abort(405, headers=[('Allow', ','.join(methods))])
return func(*args, **kwargs)
return decorator(check_methods)
def dispatch_on(**method_map):
"""Dispatches to alternate controller methods based on HTTP method
Multiple keyword arguments should be passed, with the keyword
corresponding to the HTTP method to dispatch on (DELETE, POST, GET,
etc.) and the value being the function to call. The value should be
a string indicating the name of the function to dispatch to.
Example:
.. code-block:: python
from pylons.decorators import rest
class SomeController(BaseController):
@rest.dispatch_on(POST='create_comment')
def comment(self):
# Do something with the comment
def create_comment(self, id):
# Do something if its a post to comment
"""
def dispatcher(func, self, *args, **kwargs):
"""Wrapper for dispatch_on"""
alt_method = method_map.get(get_pylons(args).request.method)
if alt_method:
alt_method = getattr(self, alt_method)
log.debug("Dispatching to %s instead", alt_method)
return self._inspect_call(alt_method, **kwargs)
return func(self, *args, **kwargs)
return decorator(dispatcher)
================================================
FILE: pylons/decorators/secure.py
================================================
"""Security related decorators"""
import logging
import urlparse
from decorator import decorator
try:
import webhelpers.html.secure_form as secure_form
except ImportError:
import webhelpers.pylonslib.secure_form as secure_form
from pylons.controllers.util import abort, redirect
from pylons.decorators.util import get_pylons
__all__ = ['authenticate_form', 'https']
log = logging.getLogger(__name__)
csrf_detected_message = (
"Cross-site request forgery detected, request denied. See "
"http://en.wikipedia.org/wiki/Cross-site_request_forgery for more "
"information.")
def authenticated_form(params):
submitted_token = params.get(secure_form.token_key)
return submitted_token is not None and \
submitted_token == secure_form.authentication_token()
@decorator
def authenticate_form(func, *args, **kwargs):
"""Decorator for authenticating a form
This decorator uses an authorization token stored in the client's
session for prevention of certain Cross-site request forgery (CSRF)
attacks (See
http://en.wikipedia.org/wiki/Cross-site_request_forgery for more
information).
For use with the ``webhelpers.html.secure_form`` helper functions.
"""
request = get_pylons(args).request
if authenticated_form(request.params):
try:
del request.POST[secure_form.token_key]
except KeyError:
del request.GET[secure_form.token_key]
return func(*args, **kwargs)
else:
log.warn('Cross-site request forgery detected, request denied: %r '
'REMOTE_ADDR: %s' % (request, request.remote_addr))
abort(403, detail=csrf_detected_message)
def https(url_or_callable=None):
"""Decorator to redirect to the SSL version of a page if not
currently using HTTPS. Apply this decorator to controller methods
(actions).
Takes a url argument: either a string url, or a callable returning a
string url. The callable will be called with no arguments when the
decorated method is called. The url's scheme will be rewritten to
https if necessary.
Non-HTTPS POST requests are aborted (405 response code) by this
decorator.
Example:
.. code-block:: python
# redirect to HTTPS /pylons
@https('/pylons')
def index(self):
do_secure()
# redirect to HTTPS /auth/login, delaying the url() call until
# later (as the url object may not be functional when the
# decorator/method are defined)
@https(lambda: url(controller='auth', action='login'))
def login(self):
do_secure()
# redirect to HTTPS version of myself
@https()
def get(self):
do_secure()
"""
def wrapper(func, *args, **kwargs):
"""Decorator Wrapper function"""
request = get_pylons(args).request
if request.scheme.lower() == 'https':
return func(*args, **kwargs)
if request.method.upper() == 'POST':
# don't allow POSTs (raises an exception)
abort(405, headers=[('Allow', 'GET')])
if url_or_callable is None:
url = request.url
elif callable(url_or_callable):
url = url_or_callable()
else:
url = url_or_callable
# Ensure an https scheme, which also needs a host
parts = urlparse.urlparse(url)
url = urlparse.urlunparse(('https', parts[1] or request.host) +
parts[2:])
log.debug('Redirecting non-https request: %s to: %s',
request.path_info, url)
redirect(url)
return decorator(wrapper)
================================================
FILE: pylons/decorators/util.py
================================================
"""Decorator internal utilities"""
import pylons
from pylons.controllers import WSGIController
def get_pylons(decorator_args):
"""Return the `pylons` object: either the :mod`~pylons` module or
the :attr:`~WSGIController._py_object` equivalent, searching a
decorator's *args for the latter
:attr:`~WSGIController._py_object` is more efficient as it provides
direct access to the Pylons global variables.
"""
if decorator_args:
controller = decorator_args[0]
if isinstance(controller, WSGIController):
return controller._py_object
return pylons
================================================
FILE: pylons/docs/en/.gitignore
================================================
_build
_themes
================================================
FILE: pylons/docs/en/Makefile
================================================
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html web htmlhelp latex changes linkcheck
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " web to make files usable by Sphinx.web"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " changes to make an overview over all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
clean:
-rm -rf _build/*
html:
mkdir -p _build/html _build/doctrees
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html
@echo
@echo "Build finished. The HTML pages are in _build/html."
web:
mkdir -p _build/web _build/doctrees
$(SPHINXBUILD) -b web $(ALLSPHINXOPTS) _build/web
@echo
@echo "Build finished; now you can run"
@echo " python -m sphinx.web _build/web"
@echo "to start the server."
htmlhelp:
mkdir -p _build/htmlhelp _build/doctrees
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in _build/htmlhelp."
latex:
mkdir -p _build/latex _build/doctrees
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
@echo
@echo "Build finished; the LaTeX files are in _build/latex."
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
"run these through (pdf)latex."
changes:
mkdir -p _build/changes _build/doctrees
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes
@echo
@echo "The overview file is in _build/changes."
linkcheck:
mkdir -p _build/linkcheck _build/doctrees
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in _build/linkcheck/output.txt."
================================================
FILE: pylons/docs/en/_oldstatic/akhet.css
================================================
div.body h2 { font-size: 160%; background: url(akhettransaqua.png) 10px 3px no-repeat; padding-left: 2.66em;}
pre { background: #efc url(background.png) 0 0 repeat; }
================================================
FILE: pylons/docs/en/_oldstatic/default.css
================================================
/**
* Sphinx Doc Design
*/
body {
font-family: sans-serif;
font-size: 100%;
background-color: #11303d;
color: #000;
margin: 0;
padding: 0;
}
/* :::: LAYOUT :::: */
div.document {
background-color: #1c4e63;
}
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 0 0 230px;
}
div.body {
background-color: white;
padding: 0 20px 30px 20px;
}
div.sphinxsidebarwrapper {
padding: 10px 5px 0 10px;
}
div.sphinxsidebar {
float: left;
width: 230px;
margin-left: -100%;
font-size: 90%;
}
div.clearer {
clear: both;
}
div.footer {
color: #fff;
width: 100%;
padding: 9px 0 9px 0;
text-align: center;
font-size: 75%;
}
div.footer a {
color: #fff;
text-decoration: underline;
}
div.related {
background-color: #133f52;
color: #fff;
width: 100%;
height: 30px;
line-height: 30px;
font-size: 90%;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
}
div.related li.right {
float: right;
margin-right: 5px;
}
div.related a {
color: white;
}
/* ::: TOC :::: */
div.sphinxsidebar h3 {
font-family: 'Trebuchet MS', sans-serif;
color: white;
font-size: 1.4em;
font-weight: normal;
margin: 0;
padding: 0;
}
div.sphinxsidebar h4 {
font-family: 'Trebuchet MS', sans-serif;
color: white;
font-size: 1.3em;
font-weight: normal;
margin: 5px 0 0 0;
padding: 0;
}
div.sphinxsidebar p {
color: white;
}
div.sphinxsidebar p.topless {
margin: 5px 10px 10px 10px;
}
div.sphinxsidebar ul {
margin: 10px;
padding: 0;
list-style: none;
color: white;
}
div.sphinxsidebar ul ul,
div.sphinxsidebar ul.want-points {
margin-left: 20px;
list-style: square;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar a {
color: #98dbcc;
}
div.sphinxsidebar form {
margin-top: 10px;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
/* :::: MODULE CLOUD :::: */
div.modulecloud {
margin: -5px 10px 5px 10px;
padding: 10px;
line-height: 160%;
border: 1px solid #cbe7e5;
background-color: #f2fbfd;
}
div.modulecloud a {
padding: 0 5px 0 5px;
}
/* :::: SEARCH :::: */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li div.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* :::: COMMON FORM STYLES :::: */
div.actions {
padding: 5px 10px 5px 10px;
border-top: 1px solid #cbe7e5;
border-bottom: 1px solid #cbe7e5;
background-color: #e0f6f4;
}
form dl {
color: #333;
}
form dt {
clear: both;
float: left;
min-width: 110px;
margin-right: 10px;
padding-top: 2px;
}
input#homepage {
display: none;
}
div.error {
margin: 5px 20px 0 0;
padding: 5px;
border: 1px solid #d00;
font-weight: bold;
}
/* :::: INLINE COMMENTS :::: */
div.inlinecomments {
position: absolute;
right: 20px;
}
div.inlinecomments a.bubble {
display: block;
float: right;
background-image: url(style/comment.png);
background-repeat: no-repeat;
width: 25px;
height: 25px;
text-align: center;
padding-top: 3px;
font-size: 0.9em;
line-height: 14px;
font-weight: bold;
color: black;
}
div.inlinecomments a.bubble span {
display: none;
}
div.inlinecomments a.emptybubble {
background-image: url(style/nocomment.png);
}
div.inlinecomments a.bubble:hover {
background-image: url(style/hovercomment.png);
text-decoration: none;
color: #3ca0a4;
}
div.inlinecomments div.comments {
float: right;
margin: 25px 5px 0 0;
max-width: 50em;
min-width: 30em;
border: 1px solid #2eabb0;
background-color: #f2fbfd;
z-index: 150;
}
div#comments {
border: 1px solid #2eabb0;
margin-top: 20px;
}
div#comments div.nocomments {
padding: 10px;
font-weight: bold;
}
div.inlinecomments div.comments h3,
div#comments h3 {
margin: 0;
padding: 0;
background-color: #2eabb0;
color: white;
border: none;
padding: 3px;
}
div.inlinecomments div.comments div.actions {
padding: 4px;
margin: 0;
border-top: none;
}
div#comments div.comment {
margin: 10px;
border: 1px solid #2eabb0;
}
div.inlinecomments div.comment h4,
div.commentwindow div.comment h4,
div#comments div.comment h4 {
margin: 10px 0 0 0;
background-color: #2eabb0;
color: white;
border: none;
padding: 1px 4px 1px 4px;
}
div#comments div.comment h4 {
margin: 0;
}
div#comments div.comment h4 a {
color: #d5f4f4;
}
div.inlinecomments div.comment div.text,
div.commentwindow div.comment div.text,
div#comments div.comment div.text {
margin: -5px 0 -5px 0;
padding: 0 10px 0 10px;
}
div.inlinecomments div.comment div.meta,
div.commentwindow div.comment div.meta,
div#comments div.comment div.meta {
text-align: right;
padding: 2px 10px 2px 0;
font-size: 95%;
color: #538893;
border-top: 1px solid #cbe7e5;
background-color: #e0f6f4;
}
div.commentwindow {
position: absolute;
width: 500px;
border: 1px solid #cbe7e5;
background-color: #f2fbfd;
display: none;
z-index: 130;
}
div.commentwindow h3 {
margin: 0;
background-color: #2eabb0;
color: white;
border: none;
padding: 5px;
font-size: 1.5em;
cursor: pointer;
}
div.commentwindow div.actions {
margin: 10px -10px 0 -10px;
padding: 4px 10px 4px 10px;
color: #538893;
}
div.commentwindow div.actions input {
border: 1px solid #2eabb0;
background-color: white;
color: #135355;
cursor: pointer;
}
div.commentwindow div.form {
padding: 0 10px 0 10px;
}
div.commentwindow div.form input,
div.commentwindow div.form textarea {
border: 1px solid #3c9ea2;
background-color: white;
color: black;
}
div.commentwindow div.error {
margin: 10px 5px 10px 5px;
background-color: #fbe5dc;
display: none;
}
div.commentwindow div.form textarea {
width: 99%;
}
div.commentwindow div.preview {
margin: 10px 0 10px 0;
background-color: #70d0d4;
padding: 0 1px 1px 25px;
}
div.commentwindow div.preview h4 {
margin: 0 0 -5px -20px;
padding: 4px 0 0 4px;
color: white;
font-size: 1.3em;
}
div.commentwindow div.preview div.comment {
background-color: #f2fbfd;
}
div.commentwindow div.preview div.comment h4 {
margin: 10px 0 0 0!important;
padding: 1px 4px 1px 4px!important;
font-size: 1.2em;
}
/* :::: SUGGEST CHANGES :::: */
div#suggest-changes-box input, div#suggest-changes-box textarea {
border: 1px solid #ccc;
background-color: white;
color: black;
}
div#suggest-changes-box textarea {
width: 99%;
height: 400px;
}
/* :::: PREVIEW :::: */
div.preview {
background-image: url(style/preview.png);
padding: 0 20px 20px 20px;
margin-bottom: 30px;
}
/* :::: INDEX PAGE :::: */
table.contentstable {
width: 90%;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* :::: INDEX STYLES :::: */
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable dl, table.indextable dd {
margin-top: 0;
margin-bottom: 0;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
form.pfform {
margin: 10px 0 20px 0;
}
/* :::: GLOBAL STYLES :::: */
.docwarning {
background-color: #ffe4e4;
padding: 10px;
margin: 0 -20px 0 -20px;
border-bottom: 1px solid #f66;
}
p.subhead {
font-weight: bold;
margin-top: 20px;
}
a {
color: #355f7c;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: 'Trebuchet MS', sans-serif;
background-color: #f2f2f2;
font-weight: normal;
color: #20435c;
border-bottom: 1px solid #ccc;
margin: 20px -20px 10px -20px;
padding: 3px 0 3px 10px;
}
div.body h1 { margin-top: 0; font-size: 200%; }
div.body h2 { font-size: 160%; }
div.body h3 { font-size: 140%; }
div.body h4 { font-size: 120%; }
div.body h5 { font-size: 110%; }
div.body h6 { font-size: 100%; }
a.headerlink {
color: #c60f0f;
font-size: 0.8em;
padding: 0 4px 0 4px;
text-decoration: none;
visibility: hidden;
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink {
visibility: visible;
}
a.headerlink:hover {
background-color: #c60f0f;
color: white;
}
div.body p, div.body dd, div.body li {
text-align: justify;
line-height: 130%;
}
div.body p.caption {
text-align: inherit;
}
div.body td {
text-align: left;
}
ul.fakelist {
list-style: none;
margin: 10px 0 10px 20px;
padding: 0;
}
.field-list ul {
padding-left: 1em;
}
.first {
margin-top: 0 !important;
}
/* "Footnotes" heading */
p.rubric {
margin-top: 30px;
font-weight: bold;
}
/* "Topics" */
div.topic {
background-color: #eee;
border: 1px solid #ccc;
padding: 0 7px 0 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* Admonitions */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
div.admonition dl {
margin-bottom: 0;
}
div.admonition p {
display: inline;
}
div.seealso {
background-color: #ffc;
border: 1px solid #ff6;
}
div.warning {
background-color: #ffe4e4;
border: 1px solid #f66;
}
div.note {
background-color: #eee;
border: 1px solid #ccc;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
display: inline;
}
p.admonition-title:after {
content: ":";
}
div.body p.centered {
text-align: center;
margin-top: 25px;
}
table.docutils {
border: 0;
}
table.docutils td, table.docutils th {
padding: 1px 8px 1px 0;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #aaa;
}
table.field-list td, table.field-list th {
border: 0 !important;
}
table.footnote td, table.footnote th {
border: 0 !important;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
dl {
margin-bottom: 15px;
clear: both;
}
dd p {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
.refcount {
color: #060;
}
dt:target,
.highlight {
background-color: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
th {
text-align: left;
padding-right: 5px;
}
pre {
padding: 5px;
background-color: #efc;
color: #333;
border: 1px solid #ac9;
border-left: none;
border-right: none;
overflow: auto;
}
td.linenos pre {
padding: 5px 0px;
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
margin-left: 0.5em;
}
table.highlighttable td {
padding: 0 0.5em 0 0.5em;
}
tt {
background-color: #ecf0f3;
padding: 0 1px 0 1px;
font-size: 0.95em;
}
tt.descname {
background-color: transparent;
font-weight: bold;
font-size: 1.2em;
}
tt.descclassname {
background-color: transparent;
}
tt.xref, a tt {
background-color: transparent;
font-weight: bold;
}
.footnote:target { background-color: #ffa }
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
background-color: transparent;
}
.optional {
font-size: 1.3em;
}
.versionmodified {
font-style: italic;
}
form.comment {
margin: 0;
padding: 10px 30px 10px 30px;
background-color: #eee;
}
form.comment h3 {
background-color: #326591;
color: white;
margin: -10px -30px 10px -30px;
padding: 5px;
font-size: 1.4em;
}
form.comment input,
form.comment textarea {
border: 1px solid #ccc;
padding: 2px;
font-family: sans-serif;
font-size: 100%;
}
form.comment input[type="text"] {
width: 240px;
}
form.comment textarea {
width: 100%;
height: 200px;
margin-bottom: 10px;
}
.system-message {
background-color: #fda;
padding: 5px;
border: 3px solid red;
}
/* :::: PRINT :::: */
@media print {
div.document,
div.documentwrapper,
div.bodywrapper {
margin: 0;
width : 100%;
}
div.sphinxsidebar,
div.related,
div.footer,
div#comments div.new-comment-box,
#top-link {
display: none;
}
}
================================================
FILE: pylons/docs/en/_oldstatic/pygments.css
================================================
.c { color: #60a0b0; font-style: italic } /* Comment */
.err { border: 1px solid #FF0000 } /* Error */
.k { color: #007020; font-weight: bold } /* Keyword */
.o { color: #666666 } /* Operator */
.cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
.cp { color: #007020 } /* Comment.Preproc */
.c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
.cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
.gd { color: #A00000 } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.gr { color: #FF0000 } /* Generic.Error */
.gh { color: #000080; font-weight: bold } /* Generic.Heading */
.gi { color: #00A000 } /* Generic.Inserted */
.go { color: #808080 } /* Generic.Output */
.gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.gt { color: #0040D0 } /* Generic.Traceback */
.kc { color: #007020; font-weight: bold } /* Keyword.Constant */
.kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
.kp { color: #007020 } /* Keyword.Pseudo */
.kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
.kt { color: #902000 } /* Keyword.Type */
.m { color: #40a070 } /* Literal.Number */
.s { color: #4070a0 } /* Literal.String */
.na { color: #4070a0 } /* Name.Attribute */
.nb { color: #007020 } /* Name.Builtin */
.nc { color: #0e84b5; font-weight: bold } /* Name.Class */
.no { color: #60add5 } /* Name.Constant */
.nd { color: #555555; font-weight: bold } /* Name.Decorator */
.ni { color: #d55537; font-weight: bold } /* Name.Entity */
.ne { color: #007020 } /* Name.Exception */
.nf { color: #06287e } /* Name.Function */
.nl { color: #002070; font-weight: bold } /* Name.Label */
.nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
.nt { color: #062873; font-weight: bold } /* Name.Tag */
.nv { color: #bb60d5 } /* Name.Variable */
.ow { color: #007020; font-weight: bold } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #40a070 } /* Literal.Number.Float */
.mh { color: #40a070 } /* Literal.Number.Hex */
.mi { color: #40a070 } /* Literal.Number.Integer */
.mo { color: #40a070 } /* Literal.Number.Oct */
.sb { color: #4070a0 } /* Literal.String.Backtick */
.sc { color: #4070a0 } /* Literal.String.Char */
.sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
.s2 { color: #4070a0 } /* Literal.String.Double */
.se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
.sh { color: #4070a0 } /* Literal.String.Heredoc */
.si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
.sx { color: #c65d09 } /* Literal.String.Other */
.sr { color: #235388 } /* Literal.String.Regex */
.s1 { color: #4070a0 } /* Literal.String.Single */
.ss { color: #517918 } /* Literal.String.Symbol */
.bp { color: #007020 } /* Name.Builtin.Pseudo */
.vc { color: #bb60d5 } /* Name.Variable.Class */
.vg { color: #bb60d5 } /* Name.Variable.Global */
.vi { color: #bb60d5 } /* Name.Variable.Instance */
.il { color: #40a070 } /* Literal.Number.Integer.Long */
================================================
FILE: pylons/docs/en/_oldstatic/pylons_as_onion.ai
================================================
%PDF-1.5
%
1 0 obj
<</Metadata 788 0 R/Pages 2 0 R/OCProperties<</D<</RBGroups[]/ON[24 0 R 28 0 R 32 0 R 36 0 R 40 0 R 44 0 R 48 0 R 52 0 R 56 0 R 60 0 R 68 0 R 126 0 R 161 0 R 165 0 R 169 0 R 173 0 R 177 0 R 181 0 R 185 0 R 189 0 R 193 0 R 197 0 R 205 0 R 263 0 R 298 0 R 302 0 R 306 0 R 310 0 R 314 0 R 318 0 R 322 0 R 326 0 R 330 0 R 334 0 R 342 0 R 400 0 R 425 0 R 429 0 R 433 0 R 437 0 R 441 0 R 445 0 R 449 0 R 453 0 R 457 0 R 461 0 R 469 0 R 580 0 R 611 0 R 615 0 R 619 0 R 623 0 R 627 0 R 631 0 R 635 0 R 639 0 R 643 0 R 647 0 R 655 0 R 766 0 R]/OFF[15 0 R 64 0 R 152 0 R 201 0 R 289 0 R 338 0 R 465 0 R 651 0 R]/Order 610 0 R>>/OCGs[15 0 R 24 0 R 28 0 R 32 0 R 36 0 R 40 0 R 44 0 R 48 0 R 52 0 R 56 0 R 60 0 R 64 0 R 68 0 R 126 0 R 152 0 R 161 0 R 165 0 R 169 0 R 173 0 R 177 0 R 181 0 R 185 0 R 189 0 R 193 0 R 197 0 R 201 0 R 205 0 R 263 0 R 289 0 R 298 0 R 302 0 R 306 0 R 310 0 R 314 0 R 318 0 R 322 0 R 326 0 R 330 0 R 334 0 R 338 0 R 342 0 R 400 0 R 425 0 R 429 0 R 433 0 R 437 0 R 441 0 R 445 0 R 449 0 R 453 0 R 457 0 R 461 0 R 465 0 R 469 0 R 580 0 R 611 0 R 615 0 R 619 0 R 623 0 R 627 0 R 631 0 R 635 0 R 639 0 R 643 0 R 647 0 R 651 0 R 655 0 R 766 0 R]>>/Type/Catalog>>
endobj
788 0 obj
<</Subtype/XML/Length 45242/Type/Metadata>>stream
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.1-c036 46.277092, Fri Feb 23 2007 14:16:18 ">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:format>application/pdf</dc:format>
<dc:title>
<rdf:Alt>
<rdf:li xml:lang="x-default">Web</rdf:li>
</rdf:Alt>
</dc:title>
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:xap="http://ns.adobe.com/xap/1.0/"
xmlns:xapGImg="http://ns.adobe.com/xap/1.0/g/img/">
<xap:CreatorTool>Adobe Illustrator CS3</xap:CreatorTool>
<xap:CreateDate>2008-06-01T12:30:09-07:00</xap:CreateDate>
<xap:ModifyDate>2008-07-18T18:27:25-07:00</xap:ModifyDate>
<xap:MetadataDate>2008-07-18T18:27:25-07:00</xap:MetadataDate>
<xap:Thumbnails>
<rdf:Alt>
<rdf:li rdf:parseType="Resource">
<xapGImg:width>256</xapGImg:width>
<xapGImg:height>180</xapGImg:height>
<xapGImg:format>JPEG</xapGImg:format>
<xapGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAtAEAAwER
AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7
FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7F
XYq7FXYq7FXYq7FWK+avzR8jeU7+Kw8wag9jdToJIFNtdSK6kkfC8UToTtuAajFUnf8A5yA/KVBV
9bZR4tZXw/XBiqKsfzv/ACmvZRFB5nslc0NJmaACtOpmVAOvfFUt1f8AMbzqlxNeeWNF0zzdoMZP
GbStTElyqjassYjfevaLmcVQnl7/AJyH8pXl0bHX7a48u30bCO4+tDlbxOTQLLJRJYfnPFGPfFXq
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</xapGImg:image>
</rdf:li>
</rdf:Alt>
</xap:Thumbnails>
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/"
xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#">
<xapMM:DocumentID>uuid:D1901A446631DD11B693883DCB3DE232</xapMM:DocumentID>
<xapMM:InstanceID>uuid:8b042820-52bd-2b40-8c3d-932332e9814c</xapMM:InstanceID>
<xapMM:DerivedFrom rdf:parseType="Resource">
<stRef:instanceID>uuid:CE901A446631DD11B693883DCB3DE232</stRef:instanceID>
<stRef:documentID>uuid:CD901A446631DD11B693883DCB3DE232</stRef:documentID>
</xapMM:DerivedFrom>
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/">
<illustrator:Type>Document</illustrator:Type>
<illustrator:StartupProfile>Web</illustrator:StartupProfile>
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:xapTPg="http://ns.adobe.com/xap/1.0/t/pg/"
xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
xmlns:stFnt="http://ns.adobe.com/xap/1.0/sType/Font#"
xmlns:xapG="http://ns.adobe.com/xap/1.0/g/">
<xapTPg:NPages>1</xapTPg:NPages>
<xapTPg:HasVisibleTransparency>False</xapTPg:HasVisibleTransparency>
<xapTPg:HasVisibleOverprint>False</xapTPg:HasVisibleOverprint>
<xapTPg:MaxPageSize rdf:parseType="Resource">
<stDim:w>14400.000000</stDim:w>
<stDim:h>14400.000000</stDim:h>
<stDim:unit>Pixels</stDim:unit>
</xapTPg:MaxPageSize>
<xapTPg:Fonts>
<rdf:Bag>
<rdf:li rdf:parseType="Resource">
<stFnt:fontName>MyriadPro-Regular</stFnt:fontName>
<stFnt:fontFamily>Myriad Pro</stFnt:fontFamily>
<stFnt:fontFace>Regular</stFnt:fontFace>
<stFnt:fontType>Open Type</stFnt:fontType>
<stFnt:versionString>Version 2.007;PS 002.000;Core 1.0.38;makeotf.lib1.7.9032</stFnt:versionString>
<stFnt:composite>False</stFnt:composite>
<stFnt:fontFileName>MyriadPro-Regular.otf</stFnt:fontFileName>
</rdf:li>
</rdf:Bag>
</xapTPg:Fonts>
<xapTPg:PlateNames>
<rdf:Seq>
<rdf:li>Cyan</rdf:li>
<rdf:li>Magenta</rdf:li>
<rdf:li>Yellow</rdf:li>
<rdf:li>Black</rdf:li>
</rdf:Seq>
</xapTPg:PlateNames>
<xapTPg:SwatchGroups>
<rdf:Seq>
<rdf:li rdf:parseType="Resource">
<xapG:groupName>Default Swatch Group</xapG:groupName>
<xapG:groupType>0</xapG:groupType>
<xapG:Colorants>
<rdf:Seq>
<rdf:li rdf:parseType="Resource">
<xapG:swatchName>White</xapG:swatchName>
<xapG:mode>RGB</xapG:mode>
<xapG:type>PROCESS</xapG:type>
<xapG:red>255</xapG:red>
<xapG:green>255</xapG:green>
<xapG:blue>255</xapG:blue>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<xapG:swatchName>Black</xapG:swatchName>
<xapG:mode>RGB</xapG:mode>
<xapG:type>PROCESS</xapG:type>
<xapG:red>0</xapG:red>
<xapG:green>0</xapG:green>
<xapG:blue>0</xapG:blue>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<xapG:swatchName>RGB Red</xapG:swatchName>
<xapG:mode>RGB</xapG:mode>
<xapG:type>PROCESS</xapG:type>
<xapG:red>255</xapG:red>
<xapG:green>0</xapG:green>
<xapG:blue>0</xapG:blue>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<xapG:swatchName>RGB Yellow</xapG:swatchName>
<xapG:mode>RGB</xapG:mode>
<xapG:type>PROCESS</xapG:type>
<xapG:red>255</xapG:red>
<xapG:green>255</xapG:green>
<xapG:blue>0</xapG:blue>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<xapG:swatchName>RGB Green</xapG:swatchName>
<xapG:mode>RGB</xapG:mode>
<xapG:type>PROCESS</xapG:type>
<xapG:red>0</xapG:red>
<xapG:green>255</xapG:green>
<xapG:blue>0</xapG:blue>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<xapG:swatchName>RGB Cyan</xapG:swatchName>
<xapG:mode>RGB</xapG:mode>
<xapG:type>PROCESS</xapG:type>
<xapG:red>0</xapG:red>
<xapG:green>255</xapG:green>
<xapG:blue>255</xapG:blue>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<xapG:swatchName>RGB Blue</xapG:swatchName>
<xapG:mode>RGB</xapG:mode>
<xapG:type>PROCESS</xapG:type>
<xapG:red>0</xapG:red>
<xapG:green>0</xapG:green>
<xapG:blue>255</xapG:blue>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<xapG:swatchName>RGB Magenta</xapG:swatchName>
<xapG:mode>RGB</xapG:mode>
<xapG:type>PROCESS</xapG:type>
<xapG:red>255</xapG:red>
<xapG:green>0</xapG:green>
<xapG:blue>255</xapG:blue>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<xapG:swatchName>R=193 G=39 B=45</xapG:swatchName>
<xapG:mode>RGB</xapG:mode>
<xapG:type>PROCESS</xapG:type>
<xapG:red>193</xapG:red>
<xapG:green>39</xapG:green>
<xapG:blue>45</xapG:blue>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<xapG:swatchName>R=237 G=28 B=36</xapG:swatchName>
<xapG:mode>RGB</xapG:mode>
<xapG:type>PROCESS</xapG:type>
<xapG:red>237</xapG:red>
<xapG:green>28</xapG:green>
<xapG:blue>36</xapG:blue>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<xapG:swatchName>R=241 G=90 B=36</xapG:swatchName>
<xapG:mode>RGB</xapG:mode>
<xapG:type>PROCESS</xapG:type>
<xapG:red>241</xapG:red>
<xapG:green>90</xapG:green>
<xapG:blue>36</xapG:blue>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<xapG:swatchName>R=247 G=147 B=30</xapG:swatchName>
<xapG:mode>RGB</xapG:mode>
<xapG:type>PROCESS</xapG:type>
<xapG:red>247</xapG:red>
<xapG:green>147</xapG:green>
<xapG:blue>30</xapG:blue>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<xapG:swatchName>R=251 G=176 B=59</xapG:swatchName>
<xapG:mode>RGB</xapG:mode>
<xapG:type>PROCESS</xapG:type>
<xapG:red>251</xapG:red>
<xapG:green>176</xapG:green>
<xapG:blue>59</xapG:blue>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<xapG:swatchName>R=252 G=238 B=33</xapG:swatchName>
<xapG:mode>RGB</xapG:mode>
<xapG:type>PROCESS</xapG:type>
<xapG:red>252</xapG:red>
<xapG:green>238</xapG:green>
<xapG:blue>33</xapG:blue>
</rdf:li>
<rdf:li rdf:parseType="Resource">
gitextract_jwapr307/
├── .gitignore
├── .hgignore
├── .hgtags
├── .travis.yml
├── CHANGELOG
├── LICENSE
├── MANIFEST.in
├── README.rst
├── UPGRADING
├── ez_setup.py
├── pylons/
│ ├── __init__.py
│ ├── commands.py
│ ├── configuration.py
│ ├── controllers/
│ │ ├── __init__.py
│ │ ├── core.py
│ │ ├── jsonrpc.py
│ │ ├── util.py
│ │ └── xmlrpc.py
│ ├── decorators/
│ │ ├── __init__.py
│ │ ├── cache.py
│ │ ├── rest.py
│ │ ├── secure.py
│ │ └── util.py
│ ├── docs/
│ │ ├── en/
│ │ │ ├── .gitignore
│ │ │ ├── Makefile
│ │ │ ├── _oldstatic/
│ │ │ │ ├── akhet.css
│ │ │ │ ├── default.css
│ │ │ │ ├── pygments.css
│ │ │ │ └── pylons_as_onion.ai
│ │ │ ├── _oldtemplates/
│ │ │ │ ├── genindex.html
│ │ │ │ ├── layout.html
│ │ │ │ ├── modindex.html
│ │ │ │ └── page.html
│ │ │ ├── advanced_models.rst
│ │ │ ├── advanced_pylons/
│ │ │ │ ├── creating_paste_templates.rst
│ │ │ │ ├── entry_points_and_plugins.rst
│ │ │ │ ├── index.rst
│ │ │ │ ├── paster.rst
│ │ │ │ └── paster_commands.rst
│ │ │ ├── caching.rst
│ │ │ ├── concepts.rst
│ │ │ ├── conf.py
│ │ │ ├── configuration.rst
│ │ │ ├── controllers.rst
│ │ │ ├── debugging.rst
│ │ │ ├── deployment.rst
│ │ │ ├── events.rst
│ │ │ ├── execution.rst
│ │ │ ├── forms.rst
│ │ │ ├── gettingstarted.rst
│ │ │ ├── glossary.rst
│ │ │ ├── helpers.rst
│ │ │ ├── i18n.rst
│ │ │ ├── index.rst
│ │ │ ├── jython.rst
│ │ │ ├── logging.rst
│ │ │ ├── models.rst
│ │ │ ├── modules/
│ │ │ │ ├── commands.rst
│ │ │ │ ├── configuration.rst
│ │ │ │ ├── controllers.rst
│ │ │ │ ├── controllers_core.rst
│ │ │ │ ├── controllers_util.rst
│ │ │ │ ├── controllers_xmlrpc.rst
│ │ │ │ ├── decorators.rst
│ │ │ │ ├── decorators_cache.rst
│ │ │ │ ├── decorators_rest.rst
│ │ │ │ ├── decorators_secure.rst
│ │ │ │ ├── error.rst
│ │ │ │ ├── i18n_translation.rst
│ │ │ │ ├── index.rst
│ │ │ │ ├── log.rst
│ │ │ │ ├── middleware.rst
│ │ │ │ ├── templating.rst
│ │ │ │ ├── test.rst
│ │ │ │ ├── util.rst
│ │ │ │ └── wsgiapp.rst
│ │ │ ├── objects.inv
│ │ │ ├── python23_install.rst
│ │ │ ├── security_policy_for_bugs.rst
│ │ │ ├── sessions.rst
│ │ │ ├── testing.rst
│ │ │ ├── thirdparty/
│ │ │ │ ├── formencode_api.rst
│ │ │ │ ├── index.rst
│ │ │ │ ├── weberror.rst
│ │ │ │ ├── webob.rst
│ │ │ │ └── webtest.rst
│ │ │ ├── tutorials/
│ │ │ │ ├── index.rst
│ │ │ │ ├── quickwiki_tutorial.rst
│ │ │ │ └── understanding_unicode.rst
│ │ │ ├── upgrading.rst
│ │ │ ├── views.rst
│ │ │ ├── windowsnotes.rst
│ │ │ └── wsgi_support.rst
│ │ └── uploader.py
│ ├── error.py
│ ├── i18n/
│ │ ├── __init__.py
│ │ └── translation.py
│ ├── log.py
│ ├── media/
│ │ ├── javascripts/
│ │ │ └── traceback.js
│ │ └── style/
│ │ ├── black.css
│ │ ├── itraceback.css
│ │ └── orange.css
│ ├── middleware.py
│ ├── templates/
│ │ ├── __init__.py
│ │ ├── controller.py_tmpl
│ │ ├── default_project/
│ │ │ ├── +package+/
│ │ │ │ ├── __init__.py_tmpl
│ │ │ │ ├── config/
│ │ │ │ │ ├── __init__.py_tmpl
│ │ │ │ │ ├── deployment.ini_tmpl_tmpl
│ │ │ │ │ ├── environment.py_tmpl
│ │ │ │ │ ├── middleware.py_tmpl
│ │ │ │ │ └── routing.py_tmpl
│ │ │ │ ├── controllers/
│ │ │ │ │ ├── __init__.py_tmpl
│ │ │ │ │ └── error.py_tmpl
│ │ │ │ ├── lib/
│ │ │ │ │ ├── __init__.py_tmpl
│ │ │ │ │ ├── app_globals.py_tmpl
│ │ │ │ │ ├── base.py_tmpl
│ │ │ │ │ └── helpers.py_tmpl
│ │ │ │ ├── model/
│ │ │ │ │ ├── __init__.py_tmpl
│ │ │ │ │ └── meta.py_tmpl
│ │ │ │ ├── public/
│ │ │ │ │ └── index.html_tmpl
│ │ │ │ ├── templates/
│ │ │ │ │ ├── .distutils_placeholder
│ │ │ │ │ └── __init__.py_tmpl
│ │ │ │ ├── tests/
│ │ │ │ │ ├── __init__.py_tmpl
│ │ │ │ │ ├── functional/
│ │ │ │ │ │ └── __init__.py_tmpl
│ │ │ │ │ └── test_models.py_tmpl
│ │ │ │ └── websetup.py_tmpl
│ │ │ ├── MANIFEST.in_tmpl
│ │ │ ├── README.txt_tmpl
│ │ │ ├── development.ini_tmpl
│ │ │ ├── ez_setup.py
│ │ │ ├── setup.cfg_tmpl
│ │ │ ├── setup.py_tmpl
│ │ │ └── test.ini_tmpl
│ │ ├── minimal_project/
│ │ │ ├── +package+/
│ │ │ │ ├── __init__.py_tmpl
│ │ │ │ ├── config/
│ │ │ │ │ └── deployment.ini_tmpl_tmpl
│ │ │ │ ├── controllers/
│ │ │ │ │ └── __init__.py_tmpl
│ │ │ │ ├── helpers.py_tmpl
│ │ │ │ ├── public/
│ │ │ │ │ └── index.html_tmpl
│ │ │ │ ├── routing.py_tmpl
│ │ │ │ ├── templates/
│ │ │ │ │ ├── .distutils_placeholder
│ │ │ │ │ └── __init__.py_tmpl
│ │ │ │ ├── tests/
│ │ │ │ │ └── __init__.py_tmpl
│ │ │ │ └── wsgiapp.py_tmpl
│ │ │ ├── MANIFEST.in_tmpl
│ │ │ ├── README.txt_tmpl
│ │ │ ├── development.ini_tmpl
│ │ │ ├── ez_setup.py
│ │ │ ├── setup.cfg_tmpl
│ │ │ ├── setup.py_tmpl
│ │ │ └── test.ini_tmpl
│ │ ├── restcontroller.py_tmpl
│ │ ├── test_controller.py_tmpl
│ │ └── test_restcontroller.py_tmpl
│ ├── templating.py
│ ├── test.py
│ ├── testutil.py
│ ├── url.py
│ ├── util.py
│ └── wsgiapp.py
├── rtd.txt
├── scripts/
│ ├── gen-go-pylons.py
│ ├── go-pylons.py
│ └── pylintrc
├── setup.cfg
├── setup.py
├── test_files/
│ ├── __init__.py
│ ├── event_file.py
│ └── sample_controllers/
│ ├── __init__.py
│ ├── controllers/
│ │ ├── __init__.py
│ │ ├── goodbye.py
│ │ ├── hello.py
│ │ └── i18nc.py
│ ├── i18n/
│ │ ├── es/
│ │ │ └── LC_MESSAGES/
│ │ │ ├── sample_controllers.mo
│ │ │ └── sample_controllers.po
│ │ ├── fr/
│ │ │ └── LC_MESSAGES/
│ │ │ ├── sample_controllers.mo
│ │ │ └── sample_controllers.po
│ │ └── ja/
│ │ └── LC_MESSAGES/
│ │ ├── sample_controllers.mo
│ │ └── sample_controllers.po
│ └── templates/
│ ├── hello.html
│ └── time.html
└── tests/
├── __init__.py
├── conftest.py
├── test_units/
│ ├── __init__.py
│ ├── test_basic_app.py
│ ├── test_controller.py
│ ├── test_decorator_authenticate_form.py
│ ├── test_decorator_cache.py
│ ├── test_decorator_https.py
│ ├── test_decorator_jsonify.py
│ ├── test_decorator_validate.py
│ ├── test_helpers.py
│ ├── test_i18n.py
│ ├── test_jsonrpc.py
│ ├── test_middleware.py
│ ├── test_templating.py
│ └── test_xmlrpc.py
└── test_webapps/
├── __init__.py
├── filestotest/
│ ├── app_globals.py
│ ├── base_with_xmlrpc.py
│ ├── cache_controller.py
│ ├── controller_sample.py
│ ├── controller_sqlatest.py
│ ├── controller_xmlrpc.py
│ ├── development.ini
│ ├── development_sqlatesting.ini
│ ├── environment_def_engine.py
│ ├── environment_def_sqlamodel.py
│ ├── functional_controller_cache_decorator.py
│ ├── functional_controller_xmlrpc.py
│ ├── functional_sample_controller_i18n.py
│ ├── functional_sample_controller_jinja2.py
│ ├── functional_sample_controller_mako.py
│ ├── functional_sample_controller_sample1.py
│ ├── functional_sample_controller_sample2.py
│ ├── functional_sample_controller_sample3.py
│ ├── functional_sample_controller_sample4.py
│ ├── functional_sample_controller_sqlatesting.py
│ ├── helpers_sample.py
│ ├── messages.ja.mo
│ ├── messages.ja.po
│ ├── messages.pot
│ ├── middleware_mako.py
│ ├── model__init__.py
│ ├── rest_routing.py
│ ├── test_mako.html
│ ├── test_sqlalchemy.html
│ ├── testgenshi.html
│ ├── testjinja2.html
│ ├── tests__init__.py
│ └── websetup.py
└── test_make_project.py
SYMBOL INDEX (590 symbols across 70 files)
FILE: ez_setup.py
function _validate_md5 (line 61) | def _validate_md5(egg_name, data):
function use_setuptools (line 72) | def use_setuptools(
function download_setuptools (line 113) | def download_setuptools(
function main (line 195) | def main(argv, version=DEFAULT_VERSION):
function update_md5 (line 236) | def update_md5(filenames):
FILE: pylons/__init__.py
function __figure_version (line 15) | def __figure_version():
FILE: pylons/commands.py
function can_import (line 58) | def can_import(name):
function is_minimal_template (line 68) | def is_minimal_template(package, fail_fast=False):
function defines_render (line 89) | def defines_render(package):
function validate_name (line 102) | def validate_name(name):
function check_controller_existence (line 124) | def check_controller_existence(base_package, directory, name):
class ControllerCommand (line 133) | class ControllerCommand(Command):
method command (line 171) | def command(self):
class RestControllerCommand (line 234) | class RestControllerCommand(Command):
method command (line 280) | def command(self):
class RoutesCommand (line 376) | class RoutesCommand(Command):
method command (line 402) | def command(self):
class ShellCommand (line 434) | class ShellCommand(Command):
method command (line 468) | def command(self):
FILE: pylons/configuration.py
class PylonsConfig (line 38) | class PylonsConfig(dict):
method init_app (line 106) | def init_app(self, global_conf, app_conf, package=None, paths=None):
FILE: pylons/controllers/core.py
class WSGIController (line 15) | class WSGIController(object):
method _perform_call (line 54) | def _perform_call(self, func, args):
method _inspect_call (line 59) | def _inspect_call(self, func):
method _get_method_args (line 125) | def _get_method_args(self):
method _dispatch_call (line 142) | def _dispatch_call(self):
method __call__ (line 175) | def __call__(self, environ, start_response):
FILE: pylons/controllers/jsonrpc.py
class JSONRPCError (line 24) | class JSONRPCError(BaseException):
method __init__ (line 26) | def __init__(self, code, message):
method __str__ (line 31) | def __str__(self):
method as_dict (line 34) | def as_dict(self):
function jsonrpc_error (line 57) | def jsonrpc_error(req_id, error):
class JSONRPCController (line 68) | class JSONRPCController(WSGIController):
method _get_method_args (line 90) | def _get_method_args(self):
method __call__ (line 95) | def __call__(self, environ, start_response):
method _dispatch_call (line 168) | def _dispatch_call(self):
method _find_method (line 203) | def _find_method(self):
FILE: pylons/controllers/util.py
class Request (line 43) | class Request(WebObRequest):
method determine_browser_charset (line 51) | def determine_browser_charset(self):
method languages (line 56) | def languages(self):
method match_accept (line 74) | def match_accept(self, mimetypes):
method signed_cookie (line 77) | def signed_cookie(self, name, secret):
class Response (line 112) | class Response(WebObResponse):
method determine_charset (line 122) | def determine_charset(self):
method has_header (line 125) | def has_header(self, header):
method get_content (line 128) | def get_content(self):
method wsgi_response (line 131) | def wsgi_response(self):
method signed_cookie (line 134) | def signed_cookie(self, name, data, secret=None, **kwargs):
function etag_cache (line 148) | def etag_cache(key=None):
function forward (line 187) | def forward(wsgi_app):
function abort (line 203) | def abort(status_code=None, detail="", headers=None, comment=None):
function redirect (line 218) | def redirect(url, code=302):
FILE: pylons/controllers/xmlrpc.py
function xmlrpc_sig (line 22) | def xmlrpc_sig(args):
function xmlrpc_fault (line 34) | def xmlrpc_fault(code, message):
class XMLRPCController (line 40) | class XMLRPCController(WSGIController):
method _get_method_args (line 106) | def _get_method_args(self):
method __call__ (line 109) | def __call__(self, environ, start_response):
method _dispatch_call (line 193) | def _dispatch_call(self):
method _find_method (line 203) | def _find_method(self, name):
method _find_method_name (line 221) | def _find_method_name(self, name):
method _publish_method_name (line 230) | def _publish_method_name(self, name):
method system_listMethods (line 239) | def system_listMethods(self):
method system_methodSignature (line 251) | def system_methodSignature(self, name):
method system_methodHelp (line 268) | def system_methodHelp(self, name):
class MethodHelp (line 281) | class MethodHelp(object):
method __init__ (line 284) | def __init__(self, doc):
method getdoc (line 287) | def getdoc(method):
FILE: pylons/decorators/__init__.py
class JSONEncoder (line 25) | class JSONEncoder(simplejson.JSONEncoder):
method default (line 26) | def default(self, obj):
function jsonify (line 34) | def jsonify(func, *args, **kwargs):
function validate (line 55) | def validate(schema=None, validators=None, form=None, variable_decode=Fa...
function pylons_formencode_gettext (line 182) | def pylons_formencode_gettext(value):
class PylonsFormEncodeState (line 197) | class PylonsFormEncodeState(object):
FILE: pylons/decorators/cache.py
function beaker_cache (line 14) | def beaker_cache(key="cache_default", expire="never", type=None,
function create_cache_key (line 131) | def create_cache_key(func, key_dict=None, self=None):
function _make_dict_from_args (line 161) | def _make_dict_from_args(func, args):
FILE: pylons/decorators/rest.py
function restrict (line 14) | def restrict(*methods):
function dispatch_on (line 38) | def dispatch_on(**method_map):
FILE: pylons/decorators/secure.py
function authenticated_form (line 24) | def authenticated_form(params):
function authenticate_form (line 31) | def authenticate_form(func, *args, **kwargs):
function https (line 56) | def https(url_or_callable=None):
FILE: pylons/decorators/util.py
function get_pylons (line 6) | def get_pylons(decorator_args):
FILE: pylons/docs/uploader.py
function scan_dir (line 24) | def scan_dir(parent, directory):
function scan_images (line 52) | def scan_images(directory):
FILE: pylons/error.py
function handle_mako_error (line 17) | def handle_mako_error(context, exc):
function myghty_html_data (line 25) | def myghty_html_data(exc_value):
function mako_html_data (line 36) | def mako_html_data(exc_value):
FILE: pylons/i18n/translation.py
class LanguageError (line 19) | class LanguageError(Exception):
class LazyString (line 24) | class LazyString(object):
method __init__ (line 31) | def __init__(self, func, *args, **kwargs):
method eval (line 36) | def eval(self):
method __unicode__ (line 39) | def __unicode__(self):
method __str__ (line 42) | def __str__(self):
method __mod__ (line 45) | def __mod__(self, other):
method format (line 48) | def format(self, *args):
function lazify (line 52) | def lazify(func):
function gettext_noop (line 62) | def gettext_noop(value):
function gettext (line 85) | def gettext(value):
function ugettext (line 98) | def ugettext(value):
function ngettext (line 112) | def ngettext(singular, plural, n):
function ungettext (line 131) | def ungettext(singular, plural, n):
function _get_translator (line 150) | def _get_translator(lang, **kwargs):
function set_lang (line 171) | def set_lang(lang, set_environ=True, **kwargs):
function get_lang (line 187) | def get_lang():
function add_fallback (line 192) | def add_fallback(lang, **kwargs):
FILE: pylons/log.py
class WSGIErrorsHandler (line 15) | class WSGIErrorsHandler(logging.Handler):
method __init__ (line 34) | def __init__(self, cache=False, *args, **kwargs):
method get_wsgierrors (line 39) | def get_wsgierrors(self):
method flush (line 53) | def flush(self):
method emit (line 63) | def emit(self, record):
FILE: pylons/middleware.py
function DebugHandler (line 79) | def DebugHandler(app, global_conf, **kwargs):
function ErrorHandler (line 92) | def ErrorHandler(app, global_conf, **errorware):
class StatusCodeRedirect (line 120) | class StatusCodeRedirect(object):
method __init__ (line 135) | def __init__(self, app, errors=(400, 401, 403, 404),
method __call__ (line 153) | def __call__(self, environ, start_response):
function debugger_filter_factory (line 203) | def debugger_filter_factory(global_conf, **kwargs):
function debugger_filter_app_factory (line 209) | def debugger_filter_app_factory(app, global_conf, **kwargs):
FILE: pylons/templates/default_project/ez_setup.py
function _validate_md5 (line 61) | def _validate_md5(egg_name, data):
function use_setuptools (line 72) | def use_setuptools(
function download_setuptools (line 113) | def download_setuptools(
function main (line 195) | def main(argv, version=DEFAULT_VERSION):
function update_md5 (line 236) | def update_md5(filenames):
FILE: pylons/templates/minimal_project/ez_setup.py
function _validate_md5 (line 61) | def _validate_md5(egg_name, data):
function use_setuptools (line 72) | def use_setuptools(
function download_setuptools (line 113) | def download_setuptools(
function main (line 195) | def main(argv, version=DEFAULT_VERSION):
function update_md5 (line 236) | def update_md5(filenames):
FILE: pylons/templating.py
function pylons_globals (line 118) | def pylons_globals():
function cached_template (line 161) | def cached_template(template_name, render_func, ns_options=(),
function render_mako (line 222) | def render_mako(template_name, extra_vars=None, cache_key=None,
function render_mako_def (line 247) | def render_mako_def(template_name, def_name, cache_key=None,
function render_genshi (line 283) | def render_genshi(template_name, extra_vars=None, cache_key=None,
function render_jinja2 (line 311) | def render_jinja2(template_name, extra_vars=None, cache_key=None,
FILE: pylons/test.py
class PylonsPlugin (line 32) | class PylonsPlugin(nose.plugins.Plugin):
method options (line 45) | def options(self, parser, env=os.environ):
method configure (line 56) | def configure(self, options, conf):
method begin (line 64) | def begin(self):
FILE: pylons/testutil.py
class ControllerWrap (line 16) | class ControllerWrap(object):
method __init__ (line 17) | def __init__(self, controller):
method __call__ (line 20) | def __call__(self, environ, start_response):
class SetupCacheGlobal (line 26) | class SetupCacheGlobal(object):
method __init__ (line 27) | def __init__(self, app, environ, setup_g=True, setup_cache=False,
method __call__ (line 42) | def __call__(self, environ, start_response):
FILE: pylons/url.py
function route_url (line 8) | def route_url(route_name, request, *elements, **kw):
FILE: pylons/util.py
function call_wsgi_application (line 28) | def call_wsgi_application(application, environ, catch_exc_info=False):
function class_name_from_module_name (line 64) | def class_name_from_module_name(module_name):
class PylonsContext (line 85) | class PylonsContext(object):
class ContextObj (line 105) | class ContextObj(object):
method __repr__ (line 108) | def __repr__(self):
class AttribSafeContextObj (line 125) | class AttribSafeContextObj(ContextObj):
method __getattr__ (line 128) | def __getattr__(self, name):
class PylonsTemplate (line 137) | class PylonsTemplate(Template):
method pre (line 150) | def pre(self, command, output_dir, vars):
class MinimalPylonsTemplate (line 178) | class MinimalPylonsTemplate(PylonsTemplate):
class LegacyPylonsTemplate (line 187) | class LegacyPylonsTemplate(PylonsTemplate):
class NewPylonsTemplate (line 196) | class NewPylonsTemplate(PylonsTemplate):
class NewMinimalPylonsTemplate (line 202) | class NewMinimalPylonsTemplate(PylonsTemplate):
class NewSQLAlchemyTemplate (line 208) | class NewSQLAlchemyTemplate(PylonsTemplate):
class PylonsInstaller (line 214) | class PylonsInstaller(Installer):
method config_content (line 218) | def config_content(self, command, vars):
function resolve_dotted (line 239) | def resolve_dotted(name):
FILE: pylons/wsgiapp.py
class PylonsApp (line 28) | class PylonsApp(object):
method __init__ (line 47) | def __init__(self, config=None, **kwargs):
method __call__ (line 71) | def __call__(self, environ, start_response):
method register_globals (line 124) | def register_globals(self, environ):
method setup_app_env (line 154) | def setup_app_env(self, environ, start_response):
method resolve (line 213) | def resolve(self, environ, start_response):
method find_controller (line 233) | def find_controller(self, controller):
method dispatch (line 283) | def dispatch(self, controller, environ, start_response):
method load_test_env (line 315) | def load_test_env(self, environ):
FILE: scripts/gen-go-pylons.py
function generate (line 32) | def generate(filename, version):
function main (line 43) | def main():
FILE: scripts/go-pylons.py
function get_installed_pythons (line 70) | def get_installed_pythons():
function get_installed_pythons (line 78) | def get_installed_pythons():
class Logger (line 303) | class Logger(object):
method __init__ (line 319) | def __init__(self, consumers):
method debug (line 325) | def debug(self, msg, *args, **kw):
method info (line 327) | def info(self, msg, *args, **kw):
method notify (line 329) | def notify(self, msg, *args, **kw):
method warn (line 331) | def warn(self, msg, *args, **kw):
method error (line 333) | def error(self, msg, *args, **kw):
method fatal (line 335) | def fatal(self, msg, *args, **kw):
method log (line 337) | def log(self, level, msg, *args, **kw):
method start_progress (line 362) | def start_progress(self, msg):
method end_progress (line 374) | def end_progress(self, msg='done.'):
method show_progress (line 388) | def show_progress(self):
method stdout_level_matches (line 395) | def stdout_level_matches(self, level):
method _stdout_level (line 399) | def _stdout_level(self):
method level_matches (line 406) | def level_matches(self, level, consumer_level):
method level_for_integer (line 433) | def level_for_integer(cls, level):
function mkdir (line 447) | def mkdir(path):
function copyfileordir (line 454) | def copyfileordir(src, dest, symlink=True):
function copyfile (line 460) | def copyfile(src, dest, symlink=True):
function writefile (line 486) | def writefile(dest, content, overwrite=True):
function rmtree (line 508) | def rmtree(dir):
function make_exe (line 515) | def make_exe(fn):
function _find_file (line 522) | def _find_file(filename, dirs):
function file_search_dirs (line 529) | def file_search_dirs():
class UpdatingDefaultsHelpFormatter (line 544) | class UpdatingDefaultsHelpFormatter(optparse.IndentedHelpFormatter):
method expand_default (line 550) | def expand_default(self, option):
class ConfigOptionParser (line 556) | class ConfigOptionParser(optparse.OptionParser):
method __init__ (line 561) | def __init__(self, *args, **kwargs):
method get_config_files (line 567) | def get_config_files(self):
method update_defaults (line 573) | def update_defaults(self, defaults):
method get_config_section (line 613) | def get_config_section(self, name):
method get_environ_vars (line 621) | def get_environ_vars(self, prefix='VIRTUALENV_'):
method get_default_values (line 629) | def get_default_values(self):
function main (line 647) | def main():
function call_subprocess (line 831) | def call_subprocess(cmd, show_stdout=True,
function filter_install_output (line 911) | def filter_install_output(line):
function find_wheels (line 916) | def find_wheels(projects, search_dirs):
function install_wheel (line 942) | def install_wheel(project_names, py_executable, search_dirs=None):
function create_environment (line 970) | def create_environment(home_dir, site_packages=False, clear=False,
function is_executable_file (line 999) | def is_executable_file(fpath):
function path_locations (line 1002) | def path_locations(home_dir):
function change_prefix (line 1056) | def change_prefix(filename, dst_prefix):
function copy_required_modules (line 1088) | def copy_required_modules(dst_prefix, symlink):
function subst_path (line 1131) | def subst_path(prefix_path, prefix, home_dir):
function install_python (line 1141) | def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, c...
function install_activate (line 1483) | def install_activate(home_dir, bin_dir, prompt=None):
function install_distutils (line 1523) | def install_distutils(home_dir):
function fix_local_scheme (line 1534) | def fix_local_scheme(home_dir, symlink=True):
function fix_lib64 (line 1554) | def fix_lib64(lib_dir, symlink=True):
function resolve_interpreter (line 1585) | def resolve_interpreter(exe):
function is_executable (line 1609) | def is_executable(exe):
function make_environment_relocatable (line 1616) | def make_environment_relocatable(home_dir):
function fixup_scripts (line 1635) | def fixup_scripts(home_dir, bin_dir):
function relative_script (line 1686) | def relative_script(lines):
function fixup_pth_and_egg_link (line 1701) | def fixup_pth_and_egg_link(home_dir, sys_path=None):
function fixup_pth_file (line 1728) | def fixup_pth_file(filename):
function fixup_egg_link (line 1752) | def fixup_egg_link(filename):
function make_relative_path (line 1765) | def make_relative_path(source, dest, dest_is_directory=True):
function create_bootstrap_script (line 1803) | def create_bootstrap_script(extra_text, python_version=''):
function after_install (line 1856) | def after_install(options, home_dir):
function convert (line 1876) | def convert(s):
class fileview (line 2244) | class fileview(object):
method __init__ (line 2250) | def __init__(self, fileobj, start=0, size=maxint):
method __repr__ (line 2259) | def __repr__(self):
method tell (line 2263) | def tell(self):
method _checkwindow (line 2266) | def _checkwindow(self, seekto, op):
method seek (line 2271) | def seek(self, offset, whence=0):
method write (line 2285) | def write(self, bytes):
method read (line 2293) | def read(self, size=maxint):
function read_data (line 2304) | def read_data(file, endian, num=1):
function mach_o_change (line 2315) | def mach_o_change(path, what, value):
FILE: test_files/event_file.py
function add_reggy (line 5) | def add_reggy(event):
function add_respy (line 9) | def add_respy(event):
FILE: test_files/sample_controllers/controllers/goodbye.py
class Smithy (line 11) | class Smithy(WSGIController):
method __init__ (line 12) | def __init__(self):
method index (line 15) | def index(self):
FILE: test_files/sample_controllers/controllers/hello.py
class HelloController (line 12) | class HelloController(WSGIController):
method __init__ (line 13) | def __init__(self):
method index (line 16) | def index(self):
method oops (line 19) | def oops(self):
method abort (line 22) | def abort(self):
method intro_template (line 25) | def intro_template(self):
method time_template (line 28) | def time_template(self):
function special_controller (line 32) | def special_controller(environ, start_response):
function empty_wsgi (line 35) | def empty_wsgi(environ, start_response):
function a_view (line 38) | def a_view(request):
FILE: test_files/sample_controllers/controllers/i18nc.py
class I18NcController (line 10) | class I18NcController(WSGIController):
method set_lang (line 11) | def set_lang(self):
method set_lang_pylonscontext (line 14) | def set_lang_pylonscontext(self, pylons):
method _set_lang (line 17) | def _set_lang(self, gettext):
method i18n_index (line 29) | def i18n_index(self):
method no_lang (line 35) | def no_lang(self):
method langs (line 42) | def langs(self):
FILE: tests/test_units/__init__.py
class TestMiddleware (line 21) | class TestMiddleware(object):
method __init__ (line 22) | def __init__(self, app):
method __call__ (line 25) | def __call__(self, environ, start_response):
class TestWSGIController (line 33) | class TestWSGIController(TestCase):
method setUp (line 34) | def setUp(self):
method tearDown (line 47) | def tearDown(self):
method get_response (line 51) | def get_response(self, **kargs):
method post_response (line 57) | def post_response(self, **kargs):
method xmlreq (line 62) | def xmlreq(self, method, args=None):
method jsonreq (line 71) | def jsonreq(self, method, args=()):
FILE: tests/test_units/test_basic_app.py
function make_app (line 11) | def make_app(global_conf, full_stack=True, static_files=True, include_ca...
class TestWsgiApp (line 61) | class TestWsgiApp(object):
method setUp (line 62) | def setUp(self):
method test_testvars (line 70) | def test_testvars(self):
method test_exception_resp_attach (line 74) | def test_exception_resp_attach(self):
method test_no_content (line 79) | def test_no_content(self):
method test_middleware_cache_obj_instance (line 83) | def test_middleware_cache_obj_instance(self):
method test_attribsafe_tmpl_context (line 89) | def test_attribsafe_tmpl_context(self):
method test_cache_obj_appglobals (line 95) | def test_cache_obj_appglobals(self):
method test_controller_name_override (line 99) | def test_controller_name_override(self):
class TestJsonifyDecorator (line 104) | class TestJsonifyDecorator(object):
method setUp (line 105) | def setUp(self):
method test_basic_response (line 113) | def test_basic_response(self):
method test_config (line 117) | def test_config(self):
method test_eval (line 123) | def test_eval(self):
method test_set_lang (line 128) | def test_set_lang(self):
method test_set_lang_pylonscontext (line 131) | def test_set_lang_pylonscontext(self):
method _test_set_lang (line 134) | def _test_set_lang(self, action):
method test_detect_lang (line 140) | def test_detect_lang(self):
method test_no_lang (line 146) | def test_no_lang(self):
method test_langs (line 151) | def test_langs(self):
FILE: tests/test_units/test_controller.py
class BasicWSGIController (line 12) | class BasicWSGIController(WSGIController):
method __init__ (line 13) | def __init__(self):
method __before__ (line 16) | def __before__(self):
method __after__ (line 19) | def __after__(self):
method index (line 22) | def index(self):
method yield_fun (line 25) | def yield_fun(self):
method strme (line 33) | def strme(self):
method use_redirect (line 36) | def use_redirect(self):
method use_customnotfound (line 41) | def use_customnotfound(self):
method header_check (line 45) | def header_check(self):
method nothing (line 49) | def nothing(self):
method params (line 52) | def params(self):
method list (line 57) | def list(self):
class FilteredWSGIController (line 60) | class FilteredWSGIController(WSGIController):
method __init__ (line 61) | def __init__(self):
method __before__ (line 65) | def __before__(self):
method __after__ (line 68) | def __after__(self):
method index (line 74) | def index(self):
method after_response (line 77) | def after_response(self):
method after_string_response (line 80) | def after_string_response(self):
class TestBasicWSGI (line 83) | class TestBasicWSGI(TestWSGIController):
method __init__ (line 84) | def __init__(self, *args, **kargs):
method setUp (line 93) | def setUp(self):
method test_wsgi_call (line 97) | def test_wsgi_call(self):
method test_yield_wrapper (line 101) | def test_yield_wrapper(self):
method test_404 (line 105) | def test_404(self):
method test_404exception (line 111) | def test_404exception(self):
method test_private_func (line 120) | def test_private_func(self):
method test_strme_func (line 125) | def test_strme_func(self):
method test_header_check (line 130) | def test_header_check(self):
method test_head (line 138) | def test_head(self):
method test_redirect (line 144) | def test_redirect(self):
method test_nothing (line 148) | def test_nothing(self):
method test_unicode_action (line 154) | def test_unicode_action(self):
method test_params (line 158) | def test_params(self):
method test_list (line 169) | def test_list(self):
class TestFilteredWSGI (line 173) | class TestFilteredWSGI(TestWSGIController):
method __init__ (line 174) | def __init__(self, *args, **kargs):
method setUp (line 182) | def setUp(self):
method test_before (line 186) | def test_before(self):
method test_after_response (line 191) | def test_after_response(self):
method test_after_string_response (line 195) | def test_after_string_response(self):
method test_start_response (line 199) | def test_start_response(self):
FILE: tests/test_units/test_decorator_authenticate_form.py
class NullHandler (line 26) | class NullHandler(logging.Handler):
method emit (line 27) | def emit(self, record):
function make_protected (line 32) | def make_protected():
class TestAuthenticateFormDecorator (line 50) | class TestAuthenticateFormDecorator(TestWSGIController):
method setUp (line 51) | def setUp(self):
method test_unauthenticated (line 61) | def test_unauthenticated(self):
method test_authenticated (line 70) | def test_authenticated(self):
FILE: tests/test_units/test_decorator_cache.py
function make_cache_controller (line 15) | def make_cache_controller():
class TestBadCacheDecorator (line 130) | class TestBadCacheDecorator(TestWSGIController):
method setUp (line 131) | def setUp(self):
method test_no_cache (line 137) | def test_no_cache(self):
class TestCacheDecorator (line 140) | class TestCacheDecorator(TestWSGIController):
method setUp (line 141) | def setUp(self):
method test_default_cache_decorator (line 147) | def test_default_cache_decorator(self):
method test_default_cache_decorator (line 158) | def test_default_cache_decorator(self):
method test_dbm_cache_decorator (line 216) | def test_dbm_cache_decorator(self):
method test_cache_key (line 239) | def test_cache_key(self):
method test_cache_key_dupe (line 254) | def test_cache_key_dupe(self):
method test_header_cache (line 262) | def test_header_cache(self):
method test_nocache (line 276) | def test_nocache(self):
FILE: tests/test_units/test_decorator_https.py
function make_httpscontroller (line 8) | def make_httpscontroller():
class TestHttpsDecorator (line 32) | class TestHttpsDecorator(TestWSGIController):
method setUp (line 33) | def setUp(self):
method test_https_explicit_path (line 49) | def test_https_explicit_path(self):
method test_https_disallows_post (line 61) | def test_https_disallows_post(self):
method test_https_callable (line 65) | def test_https_callable(self):
method test_https_callable_current (line 77) | def test_https_callable_current(self):
method test_https_redirect_to_self (line 89) | def test_https_redirect_to_self(self):
FILE: tests/test_units/test_decorator_jsonify.py
function make_cache_controller_app (line 8) | def make_cache_controller_app():
class TestJsonifyDecorator (line 35) | class TestJsonifyDecorator(TestWSGIController):
method setUp (line 36) | def setUp(self):
method tearDown (line 42) | def tearDown(self):
method test_bad_json (line 45) | def test_bad_json(self):
method test_good_json (line 52) | def test_good_json(self):
FILE: tests/test_units/test_decorator_validate.py
function custom_error_formatter (line 10) | def custom_error_formatter(error):
class NetworkForm (line 13) | class NetworkForm(formencode.Schema):
class HelloForm (line 18) | class HelloForm(formencode.Schema):
function make_validating_controller (line 21) | def make_validating_controller():
class TestValidateDecorator (line 85) | class TestValidateDecorator(TestWSGIController):
method setUp (line 86) | def setUp(self):
method test_network_validated (line 96) | def test_network_validated(self):
method test_network_failed_validation_non_ascii (line 101) | def test_network_failed_validation_non_ascii(self):
method test_recurse_validated (line 106) | def test_recurse_validated(self):
method test_hello (line 111) | def test_hello(self):
method test_hello_failed (line 117) | def test_hello_failed(self):
method test_hello_custom_failed (line 124) | def test_hello_custom_failed(self):
FILE: tests/test_units/test_helpers.py
function make_helperscontroller (line 11) | def make_helperscontroller():
class TestHelpers (line 23) | class TestHelpers(TestWSGIController):
method __init__ (line 24) | def __init__(self, *args, **kargs):
method setUp (line 34) | def setUp(self):
method tearDown (line 39) | def tearDown(self):
method test_return_etag_cache (line 42) | def test_return_etag_cache(self):
FILE: tests/test_units/test_i18n.py
function setup_py_trans (line 12) | def setup_py_trans():
class TestI18N (line 24) | class TestI18N(object):
method setUp (line 25) | def setUp(self):
method test_lazify (line 28) | def test_lazify(self):
method test_noop (line 40) | def test_noop(self):
FILE: tests/test_units/test_jsonrpc.py
function make_basejsonrpc (line 10) | def make_basejsonrpc():
class TestJSONRPCController (line 58) | class TestJSONRPCController(TestWSGIController):
method __init__ (line 60) | def __init__(self, *args, **kwargs):
method test_echo (line 72) | def test_echo(self):
method test_int_arg_check (line 78) | def test_int_arg_check(self):
method test_return_garbage (line 85) | def test_return_garbage(self):
method test_private_method (line 92) | def test_private_method(self):
method test_content_type (line 99) | def test_content_type(self):
method test_missing_method (line 103) | def test_missing_method(self):
method test_no_content_length (line 110) | def test_no_content_length(self):
method test_zero_content_length (line 119) | def test_zero_content_length(self):
method test_positional_params (line 128) | def test_positional_params(self):
method test_missing_positional_param (line 134) | def test_missing_positional_param(self):
method test_wrong_param_type (line 141) | def test_wrong_param_type(self):
method test_v2_echo (line 148) | def test_v2_echo(self):
method test_v2_echo_default (line 154) | def test_v2_echo_default(self):
method test_v2_int_arg_check_valid (line 160) | def test_v2_int_arg_check_valid(self):
method test_v2_int_arg_check_default_keyword_argument (line 166) | def test_v2_int_arg_check_default_keyword_argument(self):
method test_v2_int_arg_check (line 172) | def test_v2_int_arg_check(self):
method test_v2_decrement (line 179) | def test_v2_decrement(self):
method test_v2_decrement_default_keywoard_argument (line 185) | def test_v2_decrement_default_keywoard_argument(self):
method test_v2_decrement_missing_keyword_argument (line 191) | def test_v2_decrement_missing_keyword_argument(self):
FILE: tests/test_units/test_middleware.py
function simple_app (line 4) | def simple_app(environ, start_response):
function simple_exception_app (line 8) | def simple_exception_app(environ, start_response):
function test_plain_wrap (line 16) | def test_plain_wrap():
function test_status_intercept (line 22) | def test_status_intercept():
function test_original_path (line 28) | def test_original_path():
function test_retains_response (line 35) | def test_retains_response():
function test_retains_request (line 43) | def test_retains_request():
FILE: tests/test_units/test_templating.py
function make_app (line 20) | def make_app(global_conf, full_stack=True, static_files=True, include_ca...
class TestTemplatingApp (line 68) | class TestTemplatingApp(object):
method setUp (line 69) | def setUp(self):
method test_testvars (line 72) | def test_testvars(self):
method test_template_cache (line 76) | def test_template_cache(self):
FILE: tests/test_units/test_xmlrpc.py
function make_basexmlrpc (line 10) | def make_basexmlrpc():
class TestXMLRPCController (line 57) | class TestXMLRPCController(TestWSGIController):
method __init__ (line 58) | def __init__(self, *args, **kargs):
method test_index (line 70) | def test_index(self):
method test_structure (line 74) | def test_structure(self):
method test_methodhelp (line 78) | def test_methodhelp(self):
method test_methodhelp_with_structured_methodname (line 82) | def test_methodhelp_with_structured_methodname(self):
method test_methodsignature (line 86) | def test_methodsignature(self):
method test_methodsignature_with_structured_methodname (line 90) | def test_methodsignature_with_structured_methodname(self):
method test_listmethods (line 94) | def test_listmethods(self):
method test_unicode (line 98) | def test_unicode(self):
method test_unicode_method (line 102) | def test_unicode_method(self):
method test_no_length (line 106) | def test_no_length(self):
method test_too_big (line 110) | def test_too_big(self):
method test_badargs (line 114) | def test_badargs(self):
method test_badarity (line 117) | def test_badarity(self):
method test_bad_paramval (line 121) | def test_bad_paramval(self):
method test_missingmethod (line 124) | def test_missingmethod(self):
method test_nosignature (line 127) | def test_nosignature(self):
method test_nosignature_unicode (line 131) | def test_nosignature_unicode(self):
method test_nodocs (line 135) | def test_nodocs(self):
method test_nodocs_unicode (line 139) | def test_nodocs_unicode(self):
method test_multilinedoc (line 143) | def test_multilinedoc(self):
method test_contenttype (line 147) | def test_contenttype(self):
method test_start_response (line 151) | def test_start_response(self):
method test_private_func (line 154) | def test_private_func(self):
method test_var (line 157) | def test_var(self):
FILE: tests/test_webapps/filestotest/app_globals.py
class Globals (line 7) | class Globals(object):
method __init__ (line 12) | def __init__(self, config):
FILE: tests/test_webapps/filestotest/base_with_xmlrpc.py
class BaseController (line 10) | class BaseController(WSGIController):
method __call__ (line 11) | def __call__(self, environ, start_response):
FILE: tests/test_webapps/filestotest/cache_controller.py
class CacheController (line 5) | class CacheController(BaseController):
method test_default_cache_decorator (line 8) | def test_default_cache_decorator(self):
method test_get_cache_decorator (line 13) | def test_get_cache_decorator(self):
method test_expire_cache_decorator (line 18) | def test_expire_cache_decorator(self):
method test_key_cache_decorator (line 23) | def test_key_cache_decorator(self, id):
method test_keyslist_cache_decorator (line 28) | def test_keyslist_cache_decorator(self, id, id2="123"):
FILE: tests/test_webapps/filestotest/controller_sample.py
class SampleController (line 13) | class SampleController(BaseController):
method index (line 14) | def index(self):
method session_increment (line 17) | def session_increment(self):
method globalup (line 23) | def globalup(self):
method global_store (line 26) | def global_store(self, id=None):
method myself (line 31) | def myself(self):
method myparams (line 34) | def myparams(self):
method testdefault (line 37) | def testdefault(self):
method test_template_caching (line 41) | def test_template_caching(self):
method test_only_post (line 46) | def test_only_post(self):
method test_only_get (line 50) | def test_only_get(self):
method impossible (line 55) | def impossible(self):
method testjinja2 (line 58) | def testjinja2(self):
method set_lang (line 63) | def set_lang(self):
method set_lang_pylonscontext (line 66) | def set_lang_pylonscontext(self, pylons):
method _set_lang (line 69) | def _set_lang(self, gettext):
method i18n_index (line 81) | def i18n_index(self):
method no_lang (line 86) | def no_lang(self):
FILE: tests/test_webapps/filestotest/controller_sqlatest.py
class SampleController (line 20) | class SampleController(BaseController):
method index (line 21) | def index(self):
method testsqlalchemy (line 24) | def testsqlalchemy(self):
method set_lang (line 30) | def set_lang(self):
method set_lang_pylonscontext (line 33) | def set_lang_pylonscontext(self, pylons):
method _set_lang (line 36) | def _set_lang(self, gettext):
method i18n_index (line 48) | def i18n_index(self):
method no_lang (line 53) | def no_lang(self):
FILE: tests/test_webapps/filestotest/controller_xmlrpc.py
class XmlrpcController (line 4) | class XmlrpcController(XMLRPCController):
method userstatus (line 5) | def userstatus(self):
method docs (line 9) | def docs(self):
method uni (line 14) | def uni(self):
FILE: tests/test_webapps/filestotest/environment_def_engine.py
function load_environment (line 15) | def load_environment(global_conf, app_conf):
FILE: tests/test_webapps/filestotest/environment_def_sqlamodel.py
function load_environment (line 17) | def load_environment(global_conf, app_conf):
FILE: tests/test_webapps/filestotest/functional_controller_cache_decorator.py
class TestCacheController (line 5) | class TestCacheController(TestController):
method test_default_cache_decorator (line 7) | def test_default_cache_decorator(self):
FILE: tests/test_webapps/filestotest/functional_controller_xmlrpc.py
class TestXmlrpcController (line 4) | class TestXmlrpcController(TestController):
method xmlreq (line 7) | def xmlreq(self, method, args=None):
method setUp (line 15) | def setUp(self):
method test_index (line 18) | def test_index(self):
method test_structure (line 22) | def test_structure(self):
method test_methodhelp (line 26) | def test_methodhelp(self):
method test_methodsignature (line 30) | def test_methodsignature(self):
method test_listmethods (line 34) | def test_listmethods(self):
method test_unicode (line 38) | def test_unicode(self):
FILE: tests/test_webapps/filestotest/functional_sample_controller_i18n.py
class TestSampleController (line 3) | class TestSampleController(TestController):
method test_set_lang (line 4) | def test_set_lang(self):
method test_set_lang_pylonscontext (line 7) | def test_set_lang_pylonscontext(self):
method _test_set_lang (line 10) | def _test_set_lang(self, action):
method test_detect_lang (line 16) | def test_detect_lang(self):
method test_no_lang (line 22) | def test_no_lang(self):
FILE: tests/test_webapps/filestotest/functional_sample_controller_jinja2.py
class TestJinja2Controller (line 3) | class TestJinja2Controller(TestController):
method test_jinja2 (line 4) | def test_jinja2(self):
FILE: tests/test_webapps/filestotest/functional_sample_controller_mako.py
class TestMakoController (line 3) | class TestMakoController(TestController):
method test_mako (line 4) | def test_mako(self):
FILE: tests/test_webapps/filestotest/functional_sample_controller_sample1.py
class TestSampleController (line 4) | class TestSampleController(TestController):
method test_conf_with_app_globals (line 5) | def test_conf_with_app_globals(self):
method test_root_index (line 9) | def test_root_index(self):
method test_index (line 14) | def test_index(self):
method test_session (line 18) | def test_session(self):
method test_global (line 27) | def test_global(self):
method test_global_persistence (line 31) | def test_global_persistence(self):
method test_helper_urlfor (line 47) | def test_helper_urlfor(self):
method test_params (line 51) | def test_params(self):
FILE: tests/test_webapps/filestotest/functional_sample_controller_sample2.py
class TestSample2Controller (line 3) | class TestSample2Controller(TestController):
method test_session (line 4) | def test_session(self):
method test_genshi_default (line 13) | def test_genshi_default(self):
method _test_genshi_default (line 16) | def _test_genshi_default(self, action):
FILE: tests/test_webapps/filestotest/functional_sample_controller_sample3.py
class TestSample2Controller (line 3) | class TestSample2Controller(TestController):
method test_session (line 4) | def test_session(self):
method test_default (line 13) | def test_default(self):
FILE: tests/test_webapps/filestotest/functional_sample_controller_sample4.py
class TestSample2Controller (line 3) | class TestSample2Controller(TestController):
method test_get (line 4) | def test_get(self):
method test_redir_get (line 8) | def test_redir_get(self):
method test_post (line 12) | def test_post(self):
method test_head (line 17) | def test_head(self):
FILE: tests/test_webapps/filestotest/functional_sample_controller_sqlatesting.py
class TestSQLAlchemyController (line 10) | class TestSQLAlchemyController(TestController):
method setUp (line 11) | def setUp(self):
method tearDown (line 18) | def tearDown(self):
method test_sqlalchemy (line 21) | def test_sqlalchemy(self):
FILE: tests/test_webapps/filestotest/middleware_mako.py
function make_app (line 13) | def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
FILE: tests/test_webapps/filestotest/model__init__.py
function init_model (line 6) | def init_model(engine):
class Foo (line 11) | class Foo(Base):
method __repr__ (line 16) | def __repr__(self):
FILE: tests/test_webapps/filestotest/rest_routing.py
function make_map (line 9) | def make_map(config):
FILE: tests/test_webapps/filestotest/tests__init__.py
class TestController (line 53) | class TestController(TestCase):
method __init__ (line 54) | def __init__(self, *args, **kwargs):
FILE: tests/test_webapps/filestotest/websetup.py
function setup_app (line 13) | def setup_app(command, conf, vars):
FILE: tests/test_webapps/test_make_project.py
function _get_script_name (line 44) | def _get_script_name(script):
function svn_repos_setup (line 49) | def svn_repos_setup():
function paster_create (line 60) | def paster_create(template_engine='mako', overwrite=False, sqlatesting=F...
function make_controller (line 102) | def make_controller():
function make_controller_subdirectory (line 110) | def make_controller_subdirectory():
function make_restcontroller (line 118) | def make_restcontroller():
function make_restcontroller_subdirectory (line 126) | def make_restcontroller_subdirectory():
function _do_proj_test (line 135) | def _do_proj_test(copydict, emptyfiles=None, match_routes_output=None):
function do_nosetests (line 169) | def do_nosetests():
function do_knowntest (line 172) | def do_knowntest():
function do_i18ntest (line 181) | def do_i18ntest():
function do_genshi (line 189) | def do_genshi():
function do_two_engines (line 206) | def do_two_engines():
function do_crazy_decorators (line 214) | def do_crazy_decorators():
function do_jinja2 (line 217) | def do_jinja2():
function do_cache_decorator (line 241) | def do_cache_decorator():
function do_xmlrpc (line 257) | def do_xmlrpc():
function make_tag (line 271) | def make_tag():
function do_sqlaproject (line 289) | def do_sqlaproject():
function test_project_paster_create (line 321) | def test_project_paster_create():
function test_project_make_controller (line 324) | def test_project_make_controller():
function test_project_make_controller_subdirectory (line 327) | def test_project_make_controller_subdirectory():
function test_project_do_nosetests (line 330) | def test_project_do_nosetests():
function test_project_do_knowntest (line 333) | def test_project_do_knowntest():
function test_project_do_i18ntest (line 336) | def test_project_do_i18ntest():
function test_project_make_restcontroller (line 339) | def test_project_make_restcontroller():
function test_project_make_restcontroller_subdirectory (line 342) | def test_project_make_restcontroller_subdirectory():
function test_project_do_rest_nosetests (line 345) | def test_project_do_rest_nosetests():
function test_project_do_crazy_decorators (line 357) | def test_project_do_crazy_decorators():
function test_project_do_cache_decorator (line 360) | def test_project_do_cache_decorator():
function test_project_do_genshi_default (line 363) | def test_project_do_genshi_default():
function test_project_do_jinja2 (line 368) | def test_project_do_jinja2():
function test_project_do_xmlrpc (line 371) | def test_project_do_xmlrpc():
function test_project_do_sqlaproject (line 376) | def test_project_do_sqlaproject():
function teardown (line 382) | def teardown():
Condensed preview — 231 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,282K chars).
[
{
"path": ".gitignore",
"chars": 73,
"preview": "*.pyc\n*.egg-info\n*.egg\ntests/test_units/cache/\ntests/test_units/session/\n"
},
{
"path": ".hgignore",
"chars": 248,
"preview": "\n# Automatically generated by `hgimportsvn`\nsyntax:glob\n*.DS_Store\n.svn\n.coverage\n*.pyc\n*.egg-info\n*.egg\nez_setup\npylons"
},
{
"path": ".hgtags",
"chars": 1445,
"preview": "b7002f68d541940f32fa5d5fecb83483008fd489 v0.9.6\n88112f696d4aba81405753713ca06070a92ebcf9 v0.9.5\n1bc21f0b2820a39801278b32"
},
{
"path": ".travis.yml",
"chars": 115,
"preview": "language: python\npython:\n - \"2.6\"\n - \"2.7\"\ninstall:\n - python setup.py develop\nscript:\n - python setup.py test\n"
},
{
"path": "CHANGELOG",
"chars": 41774,
"preview": "Pylons Changelog\n================\n\n1.0.2 (July 21, 2015)\n* In the event of a NilAccept for the language, request.languag"
},
{
"path": "LICENSE",
"chars": 2843,
"preview": "Copyright (c) 2005-2015 Ben Bangert, James Gardner, Philip Jenvey\n and contributors.\nAll rights r"
},
{
"path": "MANIFEST.in",
"chars": 269,
"preview": "recursive-include pylons/templates *\nrecursive-include pylons/media *\nrecursive-include tests *\nrecursive-include test_f"
},
{
"path": "README.rst",
"chars": 1698,
"preview": "Pylons\n++++++\n\n.. image:: https://secure.travis-ci.org/Pylons/pylons.png?branch=master\n :alt: Build Status\n :target:"
},
{
"path": "UPGRADING",
"chars": 1892,
"preview": "Upgrading your Pylons Project\n=============================\n\nPylons projects should be updated using the paster command "
},
{
"path": "ez_setup.py",
"chars": 9716,
"preview": "#!python\n\"\"\"Bootstrap setuptools installation\n\nIf you want to use setuptools in your package's setup.py, just include th"
},
{
"path": "pylons/__init__.py",
"chars": 1449,
"preview": "\"\"\"Base objects to be exported for use in Controllers\"\"\"\n# Import pkg_resources first so namespace handling is properly "
},
{
"path": "pylons/commands.py",
"chars": 22751,
"preview": "\"\"\"Paster Commands, for use with paster in your project\n\n.. highlight:: bash\n\nThe following commands are made available "
},
{
"path": "pylons/configuration.py",
"chars": 8271,
"preview": "\"\"\"Configuration object and defaults setup\n\nThe PylonsConfig object is initialized in pylons projects inside the\n:file:`"
},
{
"path": "pylons/controllers/__init__.py",
"chars": 247,
"preview": "\"\"\"Standard Controllers intended for subclassing by web developers\"\"\"\nfrom pylons.controllers.core import WSGIController"
},
{
"path": "pylons/controllers/core.py",
"chars": 11067,
"preview": "\"\"\"The core WSGIController\"\"\"\nimport inspect\nimport logging\nimport types\n\nfrom webob.exc import HTTPException, HTTPNotFo"
},
{
"path": "pylons/controllers/jsonrpc.py",
"chars": 7824,
"preview": "\"\"\"The base WSGI JSONRPCController\"\"\"\nimport inspect\nimport json\nimport logging\nimport types\nimport urllib\n\nfrom paste.r"
},
{
"path": "pylons/controllers/util.py",
"chars": 7351,
"preview": "\"\"\"Utility functions and classes available for use by Controllers\n\nPylons subclasses the `WebOb <http://pythonpaste.org/"
},
{
"path": "pylons/controllers/xmlrpc.py",
"chars": 10928,
"preview": "\"\"\"The base WSGI XMLRPCController\"\"\"\nimport inspect\nimport logging\nimport types\nimport xmlrpclib\n\nfrom paste.response im"
},
{
"path": "pylons/decorators/__init__.py",
"chars": 8071,
"preview": "\"\"\"Pylons Decorators\n\nCommon decorators intended for use in controllers. Additional\ndecorators for use with controllers "
},
{
"path": "pylons/decorators/cache.py",
"chars": 5678,
"preview": "\"\"\"Caching decorator\"\"\"\nimport inspect\nimport logging\nimport time\n\nfrom decorator import decorator\nfrom paste.deploy.con"
},
{
"path": "pylons/decorators/rest.py",
"chars": 2051,
"preview": "\"\"\"REST decorators\"\"\"\nimport logging\n\nfrom decorator import decorator\n\nfrom pylons.controllers.util import abort\nfrom py"
},
{
"path": "pylons/decorators/secure.py",
"chars": 3681,
"preview": "\"\"\"Security related decorators\"\"\"\nimport logging\nimport urlparse\n\nfrom decorator import decorator\ntry:\n import webhel"
},
{
"path": "pylons/decorators/util.py",
"chars": 606,
"preview": "\"\"\"Decorator internal utilities\"\"\"\nimport pylons\nfrom pylons.controllers import WSGIController\n\n\ndef get_pylons(decorato"
},
{
"path": "pylons/docs/en/.gitignore",
"chars": 15,
"preview": "_build\n_themes\n"
},
{
"path": "pylons/docs/en/Makefile",
"chars": 2195,
"preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS =\nSPHINXBUILD "
},
{
"path": "pylons/docs/en/_oldstatic/akhet.css",
"chars": 168,
"preview": "div.body h2 { font-size: 160%; background: url(akhettransaqua.png) 10px 3px no-repeat; padding-left: 2.66em;}\npre { bac"
},
{
"path": "pylons/docs/en/_oldstatic/default.css",
"chars": 13294,
"preview": "/**\n * Sphinx Doc Design\n */\n\nbody {\n font-family: sans-serif;\n font-size: 100%;\n background-color: #11303d;\n "
},
{
"path": "pylons/docs/en/_oldstatic/pygments.css",
"chars": 3123,
"preview": ".c { color: #60a0b0; font-style: italic } /* Comment */\n.err { border: 1px solid #FF0000 } /* Error */\n.k { color: #0070"
},
{
"path": "pylons/docs/en/_oldstatic/pylons_as_onion.ai",
"chars": 154435,
"preview": "%PDF-1.5\r%\r\n1 0 obj\r<</Metadata 788 0 R/Pages 2 0 R/OCProperties<</D<</RBGroups[]/ON[24 0 R 28 0 R 32 0 R 36 0 R 40 0 R "
},
{
"path": "pylons/docs/en/_oldtemplates/genindex.html",
"chars": 1774,
"preview": "{% extends \"layout.html\" %}\n{% set title = _('Index') %}\n{% block body %}\n\n <h1 id=\"index\">{{ _('Index') }}</h1>\n\n {"
},
{
"path": "pylons/docs/en/_oldtemplates/layout.html",
"chars": 7947,
"preview": "{%- block doctype -%}\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n \"http://www.w3.org/TR/xhtml1/DTD/"
},
{
"path": "pylons/docs/en/_oldtemplates/modindex.html",
"chars": 2404,
"preview": "{% extends \"layout.html\" %}\n{% set title = _('Global Module Index') %}\n{% block extrahead %}\n{{ super() }}\n{% if builder"
},
{
"path": "pylons/docs/en/_oldtemplates/page.html",
"chars": 440,
"preview": "{% extends \"layout.html\" %}\n{% set page_links = [\n (pathto('@rss/' + sourcename), 'application/rss+xml', 'Page Comments"
},
{
"path": "pylons/docs/en/advanced_models.rst",
"chars": 12246,
"preview": ".. _advanced_models:\n\n===============\nAdvanced Models\n===============\n\nPylons works well with many different types of da"
},
{
"path": "pylons/docs/en/advanced_pylons/creating_paste_templates.rst",
"chars": 9140,
"preview": ".. _creating_paste_templates:\n\n========================\nCreating Paste templates\n========================\n\nIntroduction\n"
},
{
"path": "pylons/docs/en/advanced_pylons/entry_points_and_plugins.rst",
"chars": 8351,
"preview": ".. _entry_points_and_plugins:\n\n===================================\nUsing Entry Points to Write Plugins\n================="
},
{
"path": "pylons/docs/en/advanced_pylons/index.rst",
"chars": 190,
"preview": ".. _advanced_pylons:\n\n===============\nAdvanced Pylons\n===============\n\n.. toctree::\n :maxdepth: 1\n\n paster\n paster"
},
{
"path": "pylons/docs/en/advanced_pylons/paster.rst",
"chars": 4759,
"preview": ".. _paster:\n\nWSGI, CLI scripts\n=================\n\nWorking with :class:`wsgiwrappers.WSGIRequest`\n-----------------------"
},
{
"path": "pylons/docs/en/advanced_pylons/paster_commands.rst",
"chars": 6712,
"preview": ".. _paster_commands: - Adding commands to paster\n\n=========================\nAdding commands to Paster\n=================="
},
{
"path": "pylons/docs/en/caching.rst",
"chars": 13805,
"preview": ".. _caching:\n\n=======\nCaching\n=======\n\nInevitably, there will be occasions during applications development or deployment"
},
{
"path": "pylons/docs/en/concepts.rst",
"chars": 10628,
"preview": ".. _concepts:\n\n==================\nConcepts of Pylons\n==================\n\nUnderstanding the basic concepts of Pylons, the"
},
{
"path": "pylons/docs/en/conf.py",
"chars": 5413,
"preview": "# -*- coding: utf-8 -*-\n#\n# Pylons documentation build configuration file, created by\n# sphinx-quickstart on Mon Apr 21 "
},
{
"path": "pylons/docs/en/configuration.rst",
"chars": 18311,
"preview": ".. _configuration:\n\n=============\nConfiguration\n=============\n\nPylons comes with two main ways to configure an applicati"
},
{
"path": "pylons/docs/en/controllers.rst",
"chars": 24324,
"preview": ".. _controllers:\n\n===========\nControllers\n===========\n\n.. image:: _static/pylon2.jpg\n :alt: \n :align: left\n :heigh"
},
{
"path": "pylons/docs/en/debugging.rst",
"chars": 8587,
"preview": ".. _debugging:\n\n======================================\nErrors, Troubleshooting, and Debugging\n=========================="
},
{
"path": "pylons/docs/en/deployment.rst",
"chars": 23462,
"preview": ".. _deployment:\n\nPackaging and Deployment Overview\n=================================\n\nTODO: some of this is redundant to"
},
{
"path": "pylons/docs/en/events.rst",
"chars": 35,
"preview": ".. _events:\n\n======\nEvents\n======\n\n"
},
{
"path": "pylons/docs/en/execution.rst",
"chars": 31164,
"preview": "Pylons Execution Analysis\n%%%%%%%%%%%%%%%%%%%%%%%%%\n\n*By Mike Orr and Alfredo Deza*\n\nThis chapter shows how Pylons calls"
},
{
"path": "pylons/docs/en/forms.rst",
"chars": 18035,
"preview": ".. _forms:\n\n===========\nForms\n===========\n\nThe basics\n==========\n\nWhen a user submits a form on a website the data is su"
},
{
"path": "pylons/docs/en/gettingstarted.rst",
"chars": 8409,
"preview": ".. _getting_started:\n\n===============\nGetting Started\n===============\n\nThis section is intended to get Pylons up and run"
},
{
"path": "pylons/docs/en/glossary.rst",
"chars": 10063,
"preview": ".. _glossary:\n\nGlossary\n========\n\n.. glossary::\n\n action\n The class method in a Pylons applications' controlle"
},
{
"path": "pylons/docs/en/helpers.rst",
"chars": 12838,
"preview": ".. _helpers:\n\n=======\nHelpers\n=======\n\nHelpers are functions intended for usage in templates, to assist with common\nHTML"
},
{
"path": "pylons/docs/en/i18n.rst",
"chars": 24913,
"preview": ".. _i18n:\n\n=====================================\nInternationalization and Localization\n================================="
},
{
"path": "pylons/docs/en/index.rst",
"chars": 1730,
"preview": "Pylons Reference Documentation\n==============================\n\n.. image:: _static/pylon1.jpg\n :alt: The First Pylon of"
},
{
"path": "pylons/docs/en/jython.rst",
"chars": 2617,
"preview": ".. _jython:\n\n================\nPylons on Jython\n================\n\nPylons supports `Jython <http://www.jython.org>`_ as of"
},
{
"path": "pylons/docs/en/logging.rst",
"chars": 17562,
"preview": ".. _logging:\n\n=======\nLogging\n=======\n\nLogging messages \n----------------\n \nAs of Pylons 0.9.6, Pylons controllers (crea"
},
{
"path": "pylons/docs/en/models.rst",
"chars": 27185,
"preview": ".. _models:\n\n======\nModels\n======\n\nAbout the model\n===============\n\n.. image:: _static/pylon3.jpg\n :alt: \n :align: l"
},
{
"path": "pylons/docs/en/modules/commands.rst",
"chars": 263,
"preview": ":mod:`pylons.commands` -- Command line functions\n================================================\n\n.. automodule:: pylon"
},
{
"path": "pylons/docs/en/modules/configuration.rst",
"chars": 265,
"preview": ":mod:`pylons.configuration` -- Configuration object and defaults setup\n================================================="
},
{
"path": "pylons/docs/en/modules/controllers.rst",
"chars": 275,
"preview": ":mod:`pylons.controllers` -- Controllers\n========================================\n\n.. module:: pylons.controllers\n\nThis "
},
{
"path": "pylons/docs/en/modules/controllers_core.rst",
"chars": 302,
"preview": ":mod:`pylons.controllers.core` -- WSGIController Class\n======================================================\n\n.. automo"
},
{
"path": "pylons/docs/en/modules/controllers_util.rst",
"chars": 476,
"preview": ":mod:`pylons.controllers.util` -- Controller Utility functions\n========================================================="
},
{
"path": "pylons/docs/en/modules/controllers_xmlrpc.rst",
"chars": 313,
"preview": ":mod:`pylons.controllers.xmlrpc` -- XMLRPCController Class\n==========================================================\n\n."
},
{
"path": "pylons/docs/en/modules/decorators.rst",
"chars": 200,
"preview": ":mod:`pylons.decorators` -- Decorators\n======================================\n\n.. automodule:: pylons.decorators\n\nModule"
},
{
"path": "pylons/docs/en/modules/decorators_cache.rst",
"chars": 228,
"preview": ":mod:`pylons.decorators.cache` -- Cache Decorators\n====================================================================="
},
{
"path": "pylons/docs/en/modules/decorators_rest.rst",
"chars": 237,
"preview": ":mod:`pylons.decorators.rest` -- REST-ful Decorators\n====================================================\n\n.. automodule"
},
{
"path": "pylons/docs/en/modules/decorators_secure.rst",
"chars": 242,
"preview": ":mod:`pylons.decorators.secure` -- Secure Decorators\n====================================================\n\n.. automodule"
},
{
"path": "pylons/docs/en/modules/error.rst",
"chars": 122,
"preview": ":mod:`pylons.error` -- Error handling support\n=============================================\n\n.. automodule:: pylons.erro"
},
{
"path": "pylons/docs/en/modules/i18n_translation.rst",
"chars": 521,
"preview": ":mod:`pylons.i18n.translation` -- Translation/Localization functions\n==================================================="
},
{
"path": "pylons/docs/en/modules/index.rst",
"chars": 362,
"preview": ".. _modules:\n\n==============\nPylons Modules\n==============\n\n.. toctree::\n :maxdepth: 2\n\n commands\n configuration\n "
},
{
"path": "pylons/docs/en/modules/log.rst",
"chars": 199,
"preview": ":mod:`pylons.log` -- Logging for WSGI errors\n============================================\n\n.. automodule:: pylons.log\n\nM"
},
{
"path": "pylons/docs/en/modules/middleware.rst",
"chars": 1286,
"preview": ":mod:`pylons.middleware` -- WSGI Middleware\n===========================================\n\n.. automodule:: pylons.middlewa"
},
{
"path": "pylons/docs/en/modules/templating.rst",
"chars": 346,
"preview": ":mod:`pylons.templating` -- Render functions and helpers\n========================================================\n\n.. au"
},
{
"path": "pylons/docs/en/modules/test.rst",
"chars": 189,
"preview": ":mod:`pylons.test` -- Test related functionality\n================================================\n\n.. automodule:: pylon"
},
{
"path": "pylons/docs/en/modules/util.rst",
"chars": 286,
"preview": ":mod:`pylons.util` -- Paste Template and Pylons utility functions\n======================================================"
},
{
"path": "pylons/docs/en/modules/wsgiapp.rst",
"chars": 245,
"preview": ":mod:`pylons.wsgiapp` -- PylonsWSGI App Creator\n===============================================\n\n.. automodule:: pylons."
},
{
"path": "pylons/docs/en/objects.inv",
"chars": 0,
"preview": ""
},
{
"path": "pylons/docs/en/python23_install.rst",
"chars": 1943,
"preview": ".. _python23_installation:\n\n====================================\nPython 2.3 Installation Instructions\n=================="
},
{
"path": "pylons/docs/en/security_policy_for_bugs.rst",
"chars": 2934,
"preview": ".. _security_policy_for_bugs:\n\n========================\nSecurity policy for bugs\n========================\n\nReceiving Sec"
},
{
"path": "pylons/docs/en/sessions.rst",
"chars": 10397,
"preview": ".. _sessions:\n\n========\nSessions\n========\n\nSessions\n========\n\nPylons includes a session object: a session is a server-si"
},
{
"path": "pylons/docs/en/testing.rst",
"chars": 10551,
"preview": ".. _testing:\n\n===========================\nUnit and functional testing\n===========================\n\nUnit Testing with :mo"
},
{
"path": "pylons/docs/en/thirdparty/formencode_api.rst",
"chars": 3071,
"preview": ".. _formencode:\n\n==========\nFormEncode\n==========\n\nFormEncode is a validation and form generation package. The validatio"
},
{
"path": "pylons/docs/en/thirdparty/index.rst",
"chars": 179,
"preview": ".. _third_party_components:\n\n======================\nThird-party components\n======================\n\n.. toctree::\n :maxd"
},
{
"path": "pylons/docs/en/thirdparty/weberror.rst",
"chars": 1881,
"preview": ":mod:`weberror` -- Weberror\n===========================\n\n.. automodule:: weberror\n\n:mod:`weberror.errormiddleware`\n-----"
},
{
"path": "pylons/docs/en/thirdparty/webob.rst",
"chars": 1523,
"preview": ":mod:`webob` -- Request/Response objects\n========================================\n\n.. automodule:: webob\n\nRequest\n------"
},
{
"path": "pylons/docs/en/thirdparty/webtest.rst",
"chars": 220,
"preview": ":mod:`webtest` -- WebTest\n=========================\n\n.. currentmodule:: webtest\n.. automodule:: webtest\n\n.. autoclass:: "
},
{
"path": "pylons/docs/en/tutorials/index.rst",
"chars": 174,
"preview": ".. _tutorials:\n\nPylons Tutorials\n================\n\nA small collection of relevant tutorials.\n\n.. toctree::\n :maxdepth"
},
{
"path": "pylons/docs/en/tutorials/quickwiki_tutorial.rst",
"chars": 45340,
"preview": ".. _quickwiki_tutorial:\n\n==================\nQuickwiki tutorial\n==================\n\nIntroduction \n============ \n\nIf you h"
},
{
"path": "pylons/docs/en/tutorials/understanding_unicode.rst",
"chars": 27038,
"preview": ".. _unicode:\n\n=====================\nUnderstanding Unicode \n===================== \n\nIf you've ever come across text in a "
},
{
"path": "pylons/docs/en/upgrading.rst",
"chars": 7578,
"preview": ".. _upgrading:\n\n=========\nUpgrading\n=========\n\n1.0 -> 1.0.1\n============\n\nNo changes are necessary, however to take adva"
},
{
"path": "pylons/docs/en/views.rst",
"chars": 15267,
"preview": ".. _views:\n\n=====\nViews\n=====\n\n\n.. image:: _static/pylon4.jpg\n :alt: \n :align: left\n :height: 434px\n :width: 36"
},
{
"path": "pylons/docs/en/windowsnotes.rst",
"chars": 2840,
"preview": ".. _windows_notes:\n\n=============\nWindows Notes\n=============\n\nPython scripts installed as part of the Pylons install pr"
},
{
"path": "pylons/docs/en/wsgi_support.rst",
"chars": 9156,
"preview": ".. _wsgi_support:\n\n============\nWSGI support\n============\n\nThe Web Server Gateway Interface `defined in PEP 333 <http://"
},
{
"path": "pylons/docs/uploader.py",
"chars": 3700,
"preview": "import cPickle\nimport mimetypes\nimport os\nimport sys\nimport socket\nfrom os import path\n\nimport httplib2\nimport simplejso"
},
{
"path": "pylons/error.py",
"chars": 1191,
"preview": "\"\"\"Custom EvalException support\n\nProvides template engine HTML error formatters for the Template tab of\nEvalException.\n\n"
},
{
"path": "pylons/i18n/__init__.py",
"chars": 96,
"preview": "\"\"\"Internationalization and Localization functionality\"\"\"\nfrom pylons.i18n.translation import *\n"
},
{
"path": "pylons/i18n/translation.py",
"chars": 5880,
"preview": "\"\"\"Translation/Localization functions.\n\nProvides :mod:`gettext` translation functions via an app's\n``pylons.translator``"
},
{
"path": "pylons/log.py",
"chars": 2580,
"preview": "\"\"\"Logging related functionality\n\nThis logging Handler logs to ``environ['wsgi.errors']`` as designated\nin :pep:`333`.\n\n"
},
{
"path": "pylons/media/javascripts/traceback.js",
"chars": 4066,
"preview": "$(document).ready(function() {\n var getProxyJSON = function(host, path, data, callback) {\n data['host'] = host"
},
{
"path": "pylons/media/style/black.css",
"chars": 1518,
"preview": "body {\n font-family: arial, helvetica, sans-serif;\n background-color: #ffc900;\n background-image: url(../img/bg"
},
{
"path": "pylons/media/style/itraceback.css",
"chars": 2855,
"preview": "/* @override http://localhost:5000/_debug/media/pylons/style/itraceback.css */\n\ndiv.credits {\n padding: 5px 0 0 0;\n "
},
{
"path": "pylons/media/style/orange.css",
"chars": 9032,
"preview": "body{\n margin: 0px;\n padding: 0px;/* 4% 0 0;*/\n background: #494943 url(../img/bg.jpg) top repeat-x; \n font-"
},
{
"path": "pylons/middleware.py",
"chars": 6996,
"preview": "\"\"\"Pylons' WSGI middlewares\"\"\"\nimport logging\nimport os.path\n\nfrom paste.deploy.converters import asbool\nfrom paste.urlp"
},
{
"path": "pylons/templates/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "pylons/templates/controller.py_tmpl",
"chars": 401,
"preview": "import logging\n\nfrom pylons import request, response, session, tmpl_context as c, url\nfrom pylons.controllers.util impor"
},
{
"path": "pylons/templates/default_project/+package+/__init__.py_tmpl",
"chars": 0,
"preview": ""
},
{
"path": "pylons/templates/default_project/+package+/config/__init__.py_tmpl",
"chars": 0,
"preview": ""
},
{
"path": "pylons/templates/default_project/+package+/config/deployment.ini_tmpl_tmpl",
"chars": 1447,
"preview": "#\n# {{project}} - Pylons configuration\n#\n# The %(here)s variable will be replaced with the parent directory of this file"
},
{
"path": "pylons/templates/default_project/+package+/config/environment.py_tmpl",
"chars": 2722,
"preview": "\"\"\"Pylons environment configuration\"\"\"\nimport os\n\n\n{{if template_engine == 'mako'}}\nfrom mako.lookup import TemplateLook"
},
{
"path": "pylons/templates/default_project/+package+/config/middleware.py_tmpl",
"chars": 2411,
"preview": "\"\"\"Pylons middleware initialization\"\"\"\nfrom beaker.middleware import SessionMiddleware\nfrom paste.cascade import Cascade"
},
{
"path": "pylons/templates/default_project/+package+/config/routing.py_tmpl",
"chars": 889,
"preview": "\"\"\"Routes configuration\n\nThe more specific and detailed routes should be defined first so they\nmay take precedent over t"
},
{
"path": "pylons/templates/default_project/+package+/controllers/__init__.py_tmpl",
"chars": 0,
"preview": ""
},
{
"path": "pylons/templates/default_project/+package+/controllers/error.py_tmpl",
"chars": 1675,
"preview": "import cgi\n\nfrom paste.urlparser import PkgResourcesParser\nfrom pylons.middleware import error_document_template\nfrom we"
},
{
"path": "pylons/templates/default_project/+package+/lib/__init__.py_tmpl",
"chars": 0,
"preview": ""
},
{
"path": "pylons/templates/default_project/+package+/lib/app_globals.py_tmpl",
"chars": 540,
"preview": "\"\"\"The application's Globals object\"\"\"\n\nfrom beaker.cache import CacheManager\nfrom beaker.util import parse_cache_config"
},
{
"path": "pylons/templates/default_project/+package+/lib/base.py_tmpl",
"chars": 890,
"preview": "\"\"\"The base Controller API\n\nProvides the BaseController class for subclassing.\n\"\"\"\nfrom pylons.controllers import WSGICo"
},
{
"path": "pylons/templates/default_project/+package+/lib/helpers.py_tmpl",
"chars": 273,
"preview": "\"\"\"Helper functions\n\nConsists of functions to typically be used within templates, but also\navailable to Controllers. Thi"
},
{
"path": "pylons/templates/default_project/+package+/model/__init__.py_tmpl",
"chars": 250,
"preview": "{{if sqlalchemy}}\n\"\"\"The application's model objects\"\"\"\nfrom {{package}}.model.meta import Session, Base\n\n\ndef init_mode"
},
{
"path": "pylons/templates/default_project/+package+/model/meta.py_tmpl",
"chars": 397,
"preview": "{{if sqlalchemy}}\n\"\"\"SQLAlchemy Metadata and Session object\"\"\"\nfrom sqlalchemy.ext.declarative import declarative_base\nf"
},
{
"path": "pylons/templates/default_project/+package+/public/index.html_tmpl",
"chars": 4660,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html \n PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n \"http://www.w3"
},
{
"path": "pylons/templates/default_project/+package+/templates/.distutils_placeholder",
"chars": 0,
"preview": ""
},
{
"path": "pylons/templates/default_project/+package+/templates/__init__.py_tmpl",
"chars": 78,
"preview": "{{if template_engine not in ['genshi', 'kid']}}\n{{skip_template()}}\n{{endif}}\n"
},
{
"path": "pylons/templates/default_project/+package+/tests/__init__.py_tmpl",
"chars": 1497,
"preview": "\"\"\"Pylons application test package\n\nThis package assumes the Pylons environment is already loaded, such as\nwhen this scr"
},
{
"path": "pylons/templates/default_project/+package+/tests/functional/__init__.py_tmpl",
"chars": 0,
"preview": ""
},
{
"path": "pylons/templates/default_project/+package+/tests/test_models.py_tmpl",
"chars": 0,
"preview": ""
},
{
"path": "pylons/templates/default_project/+package+/websetup.py_tmpl",
"chars": 587,
"preview": "\"\"\"Setup the {{project}} application\"\"\"\nimport logging\n\nfrom {{package}}.config.environment import load_environment\n{{if"
},
{
"path": "pylons/templates/default_project/MANIFEST.in_tmpl",
"chars": 128,
"preview": "include {{package}}/config/deployment.ini_tmpl\nrecursive-include {{package}}/public *\nrecursive-include {{package}}/temp"
},
{
"path": "pylons/templates/default_project/README.txt_tmpl",
"chars": 467,
"preview": "This file is for you to describe the {{project}} application. Typically\nyou would include information such as the inform"
},
{
"path": "pylons/templates/default_project/development.ini_tmpl",
"chars": 2076,
"preview": "#\n# {{project}} - Pylons development environment configuration\n#\n# The %(here)s variable will be replaced with the paren"
},
{
"path": "pylons/templates/default_project/ez_setup.py",
"chars": 9716,
"preview": "#!python\n\"\"\"Bootstrap setuptools installation\n\nIf you want to use setuptools in your package's setup.py, just include th"
},
{
"path": "pylons/templates/default_project/setup.cfg_tmpl",
"chars": 573,
"preview": "[egg_info]\ntag_build = dev\ntag_svn_revision = true\n\n[easy_install]\nfind_links = http://www.pylonshq.com/download/\n\n# Bab"
},
{
"path": "pylons/templates/default_project/setup.py_tmpl",
"chars": 1219,
"preview": "try:\n from setuptools import setup, find_packages\nexcept ImportError:\n from ez_setup import use_setuptools\n use"
},
{
"path": "pylons/templates/default_project/test.ini_tmpl",
"chars": 510,
"preview": "#\n# {{project}} - Pylons testing environment configuration\n#\n# The %(here)s variable will be replaced with the parent di"
},
{
"path": "pylons/templates/minimal_project/+package+/__init__.py_tmpl",
"chars": 0,
"preview": ""
},
{
"path": "pylons/templates/minimal_project/+package+/config/deployment.ini_tmpl_tmpl",
"chars": 1349,
"preview": "#\n# {{project}} - Pylons configuration\n#\n# The %(here)s variable will be replaced with the parent directory of this file"
},
{
"path": "pylons/templates/minimal_project/+package+/controllers/__init__.py_tmpl",
"chars": 643,
"preview": "\"\"\"The base Controller API\n\nProvides the BaseController class for subclassing.\n\"\"\"\nfrom pylons.controllers import WSGICo"
},
{
"path": "pylons/templates/minimal_project/+package+/helpers.py_tmpl",
"chars": 273,
"preview": "\"\"\"Helper functions\n\nConsists of functions to typically be used within templates, but also\navailable to Controllers. Thi"
},
{
"path": "pylons/templates/minimal_project/+package+/public/index.html_tmpl",
"chars": 4660,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html \n PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n \"http://www.w3"
},
{
"path": "pylons/templates/minimal_project/+package+/routing.py_tmpl",
"chars": 889,
"preview": "\"\"\"Routes configuration\n\nThe more specific and detailed routes should be defined first so they\nmay take precedent over t"
},
{
"path": "pylons/templates/minimal_project/+package+/templates/.distutils_placeholder",
"chars": 0,
"preview": ""
},
{
"path": "pylons/templates/minimal_project/+package+/templates/__init__.py_tmpl",
"chars": 78,
"preview": "{{if template_engine not in ['genshi', 'kid']}}\n{{skip_template()}}\n{{endif}}\n"
},
{
"path": "pylons/templates/minimal_project/+package+/tests/__init__.py_tmpl",
"chars": 1018,
"preview": "\"\"\"Pylons application test package\n\nThis package assumes the Pylons environment is already loaded, such as\nwhen this scr"
},
{
"path": "pylons/templates/minimal_project/+package+/wsgiapp.py_tmpl",
"chars": 5155,
"preview": "\"\"\"The {{project}} WSGI application\"\"\"\nimport os\n\nfrom beaker.cache import CacheManager\nfrom beaker.middleware import Se"
},
{
"path": "pylons/templates/minimal_project/MANIFEST.in_tmpl",
"chars": 128,
"preview": "include {{package}}/config/deployment.ini_tmpl\nrecursive-include {{package}}/public *\nrecursive-include {{package}}/temp"
},
{
"path": "pylons/templates/minimal_project/README.txt_tmpl",
"chars": 467,
"preview": "This file is for you to describe the {{project}} application. Typically\nyou would include information such as the inform"
},
{
"path": "pylons/templates/minimal_project/development.ini_tmpl",
"chars": 1929,
"preview": "#\n# {{project}} - Pylons development environment configuration\n#\n# The %(here)s variable will be replaced with the paren"
},
{
"path": "pylons/templates/minimal_project/ez_setup.py",
"chars": 9716,
"preview": "#!python\n\"\"\"Bootstrap setuptools installation\n\nIf you want to use setuptools in your package's setup.py, just include th"
},
{
"path": "pylons/templates/minimal_project/setup.cfg_tmpl",
"chars": 150,
"preview": "[egg_info]\ntag_build = dev\ntag_svn_revision = true\n\n[easy_install]\nfind_links = http://www.pylonshq.com/download/\n\n[nose"
},
{
"path": "pylons/templates/minimal_project/setup.py_tmpl",
"chars": 1209,
"preview": "try:\n from setuptools import setup, find_packages\nexcept ImportError:\n from ez_setup import use_setuptools\n use"
},
{
"path": "pylons/templates/minimal_project/test.ini_tmpl",
"chars": 510,
"preview": "#\n# {{project}} - Pylons testing environment configuration\n#\n# The %(here)s variable will be replaced with the parent di"
},
{
"path": "pylons/templates/restcontroller.py_tmpl",
"chars": 2062,
"preview": "import logging\n\nfrom pylons import request, response, session, tmpl_context as c, url\nfrom pylons.controllers.util impor"
},
{
"path": "pylons/templates/test_controller.py_tmpl",
"chars": 215,
"preview": "from {{base_package}}.tests import *\n\nclass Test{{name}}Controller(TestController):\n\n def test_index(self):\n r"
},
{
"path": "pylons/templates/test_restcontroller.py_tmpl",
"chars": 1663,
"preview": "from {{base_package}}.tests import *\n\nclass Test{{name}}Controller(TestController):\n\n def test_index(self):\n r"
},
{
"path": "pylons/templating.py",
"chars": 11711,
"preview": "\"\"\"Render functions and helpers\n\nRender functions and helpers\n============================\n\n:mod:`pylons.templating` inc"
},
{
"path": "pylons/test.py",
"chars": 2710,
"preview": "\"\"\"Test related functionality\n\nAdds a Pylons plugin to `nose\n<http://www.somethingaboutorange.com/mrl/projects/nose/>`_ "
},
{
"path": "pylons/testutil.py",
"chars": 3105,
"preview": "\"\"\"Utility classes for creating workable pylons controllers for unit\ntesting.\n\nThese classes are used solely by Pylons f"
},
{
"path": "pylons/url.py",
"chars": 1507,
"preview": "from repoze.bfg.encode import urlencode\nfrom repoze.bfg.threadlocal import get_current_registry\nfrom repoze.bfg.url impo"
},
{
"path": "pylons/util.py",
"chars": 8179,
"preview": "\"\"\"Paste Template and Pylons utility functions\n\nPylonsTemplate is a Paste Template sub-class that configures the source\n"
},
{
"path": "pylons/wsgiapp.py",
"chars": 13278,
"preview": "\"\"\"WSGI App Creator\n\nThis module is responsible for creating the basic Pylons WSGI\napplication (PylonsApp). It's general"
},
{
"path": "rtd.txt",
"chars": 34,
"preview": "repoze.sphinx.autointerface\nbabel\n"
},
{
"path": "scripts/gen-go-pylons.py",
"chars": 1324,
"preview": "#!/usr/bin/env python\n\"\"\"Generate go-pylons.py\"\"\"\nimport sys\nimport textwrap\nimport virtualenv\n\nfilename = 'go-pylons.py"
},
{
"path": "scripts/go-pylons.py",
"chars": 99773,
"preview": "#!/usr/bin/env python\n## WARNING: This file is generated\n#!/usr/bin/env python\n\"\"\"Create a \"virtual\" Python installation"
},
{
"path": "scripts/pylintrc",
"chars": 8807,
"preview": "# lint Python modules using external checkers.\n# \n# This is the main checker controling the other ones and the reports\n#"
},
{
"path": "setup.cfg",
"chars": 277,
"preview": "[egg_info]\ntag_build = dev\ntag_date = true\n\n[bdist_wheel]\nuniversal = 1\n\n[nosetests]\n# constrain nosetests to the tests "
},
{
"path": "setup.py",
"chars": 4638,
"preview": "import sys\n\ntry:\n from setuptools import setup, find_packages\nexcept ImportError:\n from ez_setup import use_setupt"
},
{
"path": "test_files/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "test_files/event_file.py",
"chars": 217,
"preview": "from pylons.events import NewRequest, NewResponse, subscriber\n\n\n@subscriber(NewRequest)\ndef add_reggy(event):\n event."
},
{
"path": "test_files/sample_controllers/__init__.py",
"chars": 2,
"preview": "#\n"
},
{
"path": "test_files/sample_controllers/controllers/__init__.py",
"chars": 2,
"preview": "#\n"
},
{
"path": "test_files/sample_controllers/controllers/goodbye.py",
"chars": 456,
"preview": "import logging\n\nfrom pylons import request, response, session, tmpl_context as c, url\nfrom pylons.controllers import WSG"
},
{
"path": "test_files/sample_controllers/controllers/hello.py",
"chars": 947,
"preview": "import logging\n\nfrom pylons import request, response, session, tmpl_context as c, url\nfrom pylons.controllers import WSG"
},
{
"path": "test_files/sample_controllers/controllers/i18nc.py",
"chars": 1438,
"preview": "import datetime\n\nfrom pylons import request, response, session, url\nfrom pylons import tmpl_context as c\nfrom pylons imp"
},
{
"path": "test_files/sample_controllers/i18n/es/LC_MESSAGES/sample_controllers.po",
"chars": 502,
"preview": "# -*- coding: utf-8 -*-\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PROJECT VERSION\\n\"\n\"Report-Msgid-Bugs-To: EMAIL@ADDRESS\\"
},
{
"path": "test_files/sample_controllers/i18n/fr/LC_MESSAGES/sample_controllers.po",
"chars": 502,
"preview": "# -*- coding: utf-8 -*-\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PROJECT VERSION\\n\"\n\"Report-Msgid-Bugs-To: EMAIL@ADDRESS\\"
},
{
"path": "test_files/sample_controllers/i18n/ja/LC_MESSAGES/sample_controllers.po",
"chars": 875,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
},
{
"path": "test_files/sample_controllers/templates/hello.html",
"chars": 18,
"preview": "Hi there ${4 + 2}\n"
},
{
"path": "test_files/sample_controllers/templates/time.html",
"chars": 74,
"preview": "<%!\nfrom datetime import datetime\n%>\nHello, the time is ${datetime.now()}\n"
},
{
"path": "tests/__init__.py",
"chars": 2,
"preview": "#\n"
},
{
"path": "tests/conftest.py",
"chars": 416,
"preview": "import sys\nimport os\nimport shutil\nimport pkg_resources\n\nhere = os.path.dirname(__file__)\nbase = os.path.dirname(here)\ns"
},
{
"path": "tests/test_units/__init__.py",
"chars": 2788,
"preview": "import json\nimport os\nimport sys\nfrom unittest import TestCase\nfrom urllib import quote_plus\nfrom xmlrpclib import loads"
},
{
"path": "tests/test_units/test_basic_app.py",
"chars": 5868,
"preview": "import os\nimport re\nimport sys\n\n\nfrom nose.tools import raises\n\nfrom __init__ import test_root\n\n\ndef make_app(global_con"
},
{
"path": "tests/test_units/test_controller.py",
"chars": 6763,
"preview": "# -*- coding: utf-8 -*-\nfrom paste.fixture import TestApp\nfrom paste.registry import RegistryManager\nfrom webob.exc impo"
},
{
"path": "tests/test_units/test_decorator_authenticate_form.py",
"chars": 3673,
"preview": "# -*- coding: utf-8 -*-\nimport logging\nimport logging.handlers\nimport os\n\nfrom beaker.middleware import SessionMiddlewar"
},
{
"path": "tests/test_units/test_decorator_cache.py",
"chars": 11628,
"preview": "import os\nimport shutil\nimport time\n\nfrom webtest import TestApp\nfrom paste.registry import RegistryManager\n\nfrom beaker"
},
{
"path": "tests/test_units/test_decorator_https.py",
"chars": 3420,
"preview": "from paste.fixture import TestApp\nfrom paste.registry import RegistryManager\n\nfrom routes.middleware import RoutesMiddle"
},
{
"path": "tests/test_units/test_decorator_jsonify.py",
"chars": 1648,
"preview": "import warnings\n\nfrom paste.fixture import TestApp\nfrom paste.registry import RegistryManager\n\nfrom __init__ import Test"
},
{
"path": "tests/test_units/test_decorator_validate.py",
"chars": 4784,
"preview": "# -*- coding: utf-8 -*-\nimport formencode\nfrom formencode.htmlfill import html_quote\nfrom paste.fixture import TestApp\nf"
},
{
"path": "tests/test_units/test_helpers.py",
"chars": 1531,
"preview": "import warnings\nfrom unittest import TestCase\n\nfrom paste.fixture import TestApp\nfrom paste.httpexceptions import HTTPMo"
},
{
"path": "tests/test_units/test_i18n.py",
"chars": 1611,
"preview": "# -*- coding: utf-8 -*-\nimport os\nimport sys\n\nfrom paste.fixture import TestApp\n\nfrom __init__ import test_root\n\nlang_se"
},
{
"path": "tests/test_units/test_jsonrpc.py",
"chars": 7114,
"preview": "# -*- coding: utf-8 -*-\nfrom paste.fixture import TestApp\nfrom paste.registry import RegistryManager\n\nimport webob.exc a"
},
{
"path": "tests/test_units/test_middleware.py",
"chars": 1971,
"preview": "# -*- coding: utf-8 -*-\nfrom webtest import TestApp\n\ndef simple_app(environ, start_response):\n start_response('200 OK"
},
{
"path": "tests/test_units/test_templating.py",
"chars": 2846,
"preview": "import os\nimport re\nimport sys\n\nfrom beaker.cache import CacheManager\nfrom beaker.middleware import SessionMiddleware, C"
},
{
"path": "tests/test_units/test_xmlrpc.py",
"chars": 6046,
"preview": "# -*- coding: utf-8 -*-\nfrom paste.fixture import TestApp\nfrom paste.registry import RegistryManager\n\nimport webob.exc a"
},
{
"path": "tests/test_webapps/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "tests/test_webapps/filestotest/app_globals.py",
"chars": 621,
"preview": "\"\"\"The application's Globals object\"\"\"\nfrom pylons import config\n\nfrom beaker.cache import CacheManager\nfrom beaker.util"
},
{
"path": "tests/test_webapps/filestotest/base_with_xmlrpc.py",
"chars": 914,
"preview": "from pylons import tmpl_context as c, app_globals, cache, request, session\nfrom pylons.controllers import WSGIController"
},
{
"path": "tests/test_webapps/filestotest/cache_controller.py",
"chars": 1014,
"preview": "from pylons import app_globals\nfrom pylons.decorators.cache import beaker_cache\nfrom projectname.lib.base import BaseCon"
},
{
"path": "tests/test_webapps/filestotest/controller_sample.py",
"chars": 2693,
"preview": "import datetime\n\nfrom projectname.lib.base import *\nimport projectname.lib.helpers as h\nfrom pylons import request, resp"
},
{
"path": "tests/test_webapps/filestotest/controller_sqlatest.py",
"chars": 1833,
"preview": "import datetime\n\nfrom projectname.lib.base import *\ntry:\n import sqlalchemy as sa\n from projectname.model.meta imp"
},
{
"path": "tests/test_webapps/filestotest/controller_xmlrpc.py",
"chars": 554,
"preview": "from projectname.lib.base import *\nfrom pylons.controllers import XMLRPCController\n\nclass XmlrpcController(XMLRPCControl"
}
]
// ... and 31 more files (download for full content)
About this extraction
This page contains the full source code of the Pylons/pylons GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 231 files (1.1 MB), approximately 350.8k tokens, and a symbol index with 590 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.