move to Pylons 0.9.7 and related packages
This commit is contained in:
parent
787f6050d4
commit
30b74165c6
28 changed files with 199 additions and 173 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
||||||
*~
|
*~
|
||||||
*.pyc
|
*.pyc
|
||||||
data
|
data
|
||||||
pyalchemybiz.db
|
development.db
|
||||||
|
pyalchemybiz/public/js/jquery.js
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
|
include pyalchemybiz/config/deployment.ini_tmpl
|
||||||
recursive-include pyalchemybiz/public *
|
recursive-include pyalchemybiz/public *
|
||||||
recursive-include pyalchemybiz/templates *
|
recursive-include pyalchemybiz/templates *
|
||||||
|
|
|
@ -12,12 +12,14 @@ error_email_from = paste@localhost
|
||||||
|
|
||||||
[server:main]
|
[server:main]
|
||||||
use = egg:Paste#http
|
use = egg:Paste#http
|
||||||
host = 0.0.0.0
|
host = 127.0.0.1
|
||||||
port = 5000
|
port = 5000
|
||||||
|
|
||||||
[app:main]
|
[app:main]
|
||||||
use = egg:pyalchemybiz
|
use = egg:pyalchemybiz
|
||||||
full_stack = true
|
full_stack = true
|
||||||
|
static_files = true
|
||||||
|
|
||||||
cache_dir = %(here)s/data
|
cache_dir = %(here)s/data
|
||||||
beaker.session.key = pyalchemybiz
|
beaker.session.key = pyalchemybiz
|
||||||
beaker.session.secret = somesecret
|
beaker.session.secret = somesecret
|
||||||
|
@ -28,26 +30,24 @@ beaker.session.secret = somesecret
|
||||||
#beaker.cache.data_dir = %(here)s/data/cache
|
#beaker.cache.data_dir = %(here)s/data/cache
|
||||||
#beaker.session.data_dir = %(here)s/data/sessions
|
#beaker.session.data_dir = %(here)s/data/sessions
|
||||||
|
|
||||||
# WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*
|
# SQLAlchemy database URL
|
||||||
# Debug mode will enable the interactive debugging tool, allowing ANYONE to
|
sqlalchemy.url = sqlite:///%(here)s/development.db
|
||||||
# execute malicious code after an exception is raised.
|
sqlalchemy.echo = true
|
||||||
#set debug = false
|
|
||||||
|
|
||||||
# Specify the database for SQLAlchemy to use.
|
|
||||||
# %(here)s may include a ':' character on Windows environments; this can
|
|
||||||
# invalidate the URI when specifying a SQLite db via path name
|
|
||||||
sqlalchemy.default.url = sqlite:///%(here)s/pyalchemybiz.db
|
|
||||||
sqlalchemy.default.echo = true
|
|
||||||
sqlalchemy.convert_unicode = true
|
sqlalchemy.convert_unicode = true
|
||||||
|
|
||||||
# settings for sqlalchemy-migrate
|
# settings for sqlalchemy-migrate
|
||||||
migrate.repo.version = 2
|
migrate.repo.version = 2
|
||||||
migrate.repo.dir = %(here)s/data/dbrepo
|
migrate.repo.dir = %(here)s/data/dbrepo
|
||||||
|
|
||||||
|
# WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*
|
||||||
|
# Debug mode will enable the interactive debugging tool, allowing ANYONE to
|
||||||
|
# execute malicious code after an exception is raised.
|
||||||
|
#set debug = false
|
||||||
|
|
||||||
|
|
||||||
# Logging configuration
|
# Logging configuration
|
||||||
[loggers]
|
[loggers]
|
||||||
keys = root, pyalchemybiz
|
keys = root, routes, pyalchemybiz, sqlalchemy
|
||||||
|
|
||||||
[handlers]
|
[handlers]
|
||||||
keys = console
|
keys = console
|
||||||
|
@ -59,11 +59,25 @@ keys = generic
|
||||||
level = INFO
|
level = INFO
|
||||||
handlers = console
|
handlers = console
|
||||||
|
|
||||||
|
[logger_routes]
|
||||||
|
level = INFO
|
||||||
|
handlers =
|
||||||
|
qualname = routes.middleware
|
||||||
|
# "level = DEBUG" logs the route matched and routing variables.
|
||||||
|
|
||||||
[logger_pyalchemybiz]
|
[logger_pyalchemybiz]
|
||||||
level = DEBUG
|
level = DEBUG
|
||||||
handlers =
|
handlers =
|
||||||
qualname = pyalchemybiz
|
qualname = pyalchemybiz
|
||||||
|
|
||||||
|
[logger_sqlalchemy]
|
||||||
|
level = INFO
|
||||||
|
handlers =
|
||||||
|
qualname = sqlalchemy.engine
|
||||||
|
# "level = INFO" logs SQL queries.
|
||||||
|
# "level = DEBUG" logs SQL queries and results.
|
||||||
|
# "level = WARN" logs neither. (Recommended for production systems.)
|
||||||
|
|
||||||
[handler_console]
|
[handler_console]
|
||||||
class = StreamHandler
|
class = StreamHandler
|
||||||
args = (sys.stderr,)
|
args = (sys.stderr,)
|
||||||
|
|
|
@ -8,5 +8,12 @@ You can generate your documentation in HTML format by running this command::
|
||||||
|
|
||||||
setup.py pudge
|
setup.py pudge
|
||||||
|
|
||||||
For this to work you will need to download and install ``buildutils`` and
|
For this to work you will need to download and install `buildutils`_,
|
||||||
``pudge``.
|
`pudge`_, and `pygments`_. The ``pudge`` command is disabled by
|
||||||
|
default; to ativate it in your project, run::
|
||||||
|
|
||||||
|
setup.py addcommand -p buildutils.pudge_command
|
||||||
|
|
||||||
|
.. _buildutils: http://pypi.python.org/pypi/buildutils
|
||||||
|
.. _pudge: http://pudge.lesscode.org/
|
||||||
|
.. _pygments: http://pygments.org/
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Metadata-Version: 1.0
|
Metadata-Version: 1.0
|
||||||
Name: pyalchemybiz
|
Name: pyalchemybiz
|
||||||
Version: 0.1dev-r6
|
Version: 0.1dev
|
||||||
Summary: python based small business suite.
|
Summary: python based small business suite.
|
||||||
Home-page: http://www.dittberner.info/projects/pyalchemybiz
|
Home-page: http://www.dittberner.info/projects/pyalchemybiz
|
||||||
Author: Jan Dittberner
|
Author: Jan Dittberner
|
||||||
|
|
|
@ -18,11 +18,12 @@ pyalchemybiz.egg-info/PKG-INFO
|
||||||
pyalchemybiz.egg-info/SOURCES.txt
|
pyalchemybiz.egg-info/SOURCES.txt
|
||||||
pyalchemybiz.egg-info/dependency_links.txt
|
pyalchemybiz.egg-info/dependency_links.txt
|
||||||
pyalchemybiz.egg-info/entry_points.txt
|
pyalchemybiz.egg-info/entry_points.txt
|
||||||
pyalchemybiz.egg-info/paste_deploy_config.ini_tmpl
|
pyalchemybiz.egg-info/not-zip-safe
|
||||||
pyalchemybiz.egg-info/paster_plugins.txt
|
pyalchemybiz.egg-info/paster_plugins.txt
|
||||||
pyalchemybiz.egg-info/requires.txt
|
pyalchemybiz.egg-info/requires.txt
|
||||||
pyalchemybiz.egg-info/top_level.txt
|
pyalchemybiz.egg-info/top_level.txt
|
||||||
pyalchemybiz/config/__init__.py
|
pyalchemybiz/config/__init__.py
|
||||||
|
pyalchemybiz/config/deployment.ini_tmpl
|
||||||
pyalchemybiz/config/environment.py
|
pyalchemybiz/config/environment.py
|
||||||
pyalchemybiz/config/middleware.py
|
pyalchemybiz/config/middleware.py
|
||||||
pyalchemybiz/config/routing.py
|
pyalchemybiz/config/routing.py
|
||||||
|
@ -40,9 +41,13 @@ pyalchemybiz/model/customer.py
|
||||||
pyalchemybiz/model/meta.py
|
pyalchemybiz/model/meta.py
|
||||||
pyalchemybiz/model/person.py
|
pyalchemybiz/model/person.py
|
||||||
pyalchemybiz/model/product.py
|
pyalchemybiz/model/product.py
|
||||||
pyalchemybiz/templates/base.mako
|
pyalchemybiz/templates/base/base.mako
|
||||||
pyalchemybiz/templates/customer.mako
|
pyalchemybiz/templates/base/customer.mako
|
||||||
pyalchemybiz/templates/index.mako
|
pyalchemybiz/templates/derived/customer/edit.mako
|
||||||
|
pyalchemybiz/templates/derived/customer/list.mako
|
||||||
|
pyalchemybiz/templates/derived/customer/new.mako
|
||||||
|
pyalchemybiz/templates/derived/customer/view.mako
|
||||||
|
pyalchemybiz/templates/derived/index/index.mako
|
||||||
pyalchemybiz/tests/__init__.py
|
pyalchemybiz/tests/__init__.py
|
||||||
pyalchemybiz/tests/test_models.py
|
pyalchemybiz/tests/test_models.py
|
||||||
pyalchemybiz/tests/functional/__init__.py
|
pyalchemybiz/tests/functional/__init__.py
|
||||||
|
|
1
pyalchemybiz.egg-info/not-zip-safe
Normal file
1
pyalchemybiz.egg-info/not-zip-safe
Normal file
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
|
PasteScript
|
||||||
Pylons
|
Pylons
|
||||||
WebHelpers
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
Pylons>=0.9.6.2
|
Pylons>=0.9.7
|
||||||
SQLAlchemy>=0.4.7
|
SQLAlchemy>=0.5.2,<0.6
|
||||||
sqlalchemy-migrate>=0.4.5
|
sqlalchemy-migrate>=0.5.2,<0.6
|
||||||
|
Mako
|
||||||
|
FormBuild>=2.0,<3
|
|
@ -17,6 +17,8 @@ port = 5000
|
||||||
[app:main]
|
[app:main]
|
||||||
use = egg:pyalchemybiz
|
use = egg:pyalchemybiz
|
||||||
full_stack = true
|
full_stack = true
|
||||||
|
static_files = true
|
||||||
|
|
||||||
cache_dir = %(here)s/data
|
cache_dir = %(here)s/data
|
||||||
beaker.session.key = pyalchemybiz
|
beaker.session.key = pyalchemybiz
|
||||||
beaker.session.secret = ${app_instance_secret}
|
beaker.session.secret = ${app_instance_secret}
|
||||||
|
@ -28,22 +30,14 @@ app_instance_uuid = ${app_instance_uuid}
|
||||||
#beaker.cache.data_dir = %(here)s/data/cache
|
#beaker.cache.data_dir = %(here)s/data/cache
|
||||||
#beaker.session.data_dir = %(here)s/data/sessions
|
#beaker.session.data_dir = %(here)s/data/sessions
|
||||||
|
|
||||||
|
# SQLAlchemy database URL
|
||||||
|
sqlalchemy.url = sqlite:///production.db
|
||||||
|
|
||||||
# WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*
|
# WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*
|
||||||
# Debug mode will enable the interactive debugging tool, allowing ANYONE to
|
# Debug mode will enable the interactive debugging tool, allowing ANYONE to
|
||||||
# execute malicious code after an exception is raised.
|
# execute malicious code after an exception is raised.
|
||||||
set debug = false
|
set debug = false
|
||||||
|
|
||||||
# Specify the database for SQLAlchemy to use.
|
|
||||||
# %(here)s may include a ':' character on Windows environments; this can
|
|
||||||
# invalidate the URI when specifying a SQLite db via path name
|
|
||||||
#sqlalchemy.default.url = sqlite:///%(here)s/pyalchemybiz.db
|
|
||||||
#sqlalchemy.default.echo = false
|
|
||||||
sqlalchemy.default.convert_unicode = true
|
|
||||||
|
|
||||||
# settings for sqlalchemy-migrate
|
|
||||||
migrate.repo.version = 2
|
|
||||||
migrate.repo.dir = %(here)s/data/dbrepo
|
|
||||||
|
|
||||||
|
|
||||||
# Logging configuration
|
# Logging configuration
|
||||||
[loggers]
|
[loggers]
|
|
@ -1,9 +1,11 @@
|
||||||
"""Pylons environment configuration"""
|
"""Pylons environment configuration"""
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from mako.lookup import TemplateLookup
|
||||||
from pylons import config
|
from pylons import config
|
||||||
|
from pylons.error import handle_mako_error
|
||||||
from sqlalchemy import engine_from_config
|
from sqlalchemy import engine_from_config
|
||||||
from sqlalchemy.exceptions import NoSuchTableError
|
from sqlalchemy.exc import NoSuchTableError
|
||||||
from migrate.versioning.api import db_version
|
from migrate.versioning.api import db_version
|
||||||
|
|
||||||
from pyalchemybiz.model import init_model
|
from pyalchemybiz.model import init_model
|
||||||
|
@ -12,6 +14,7 @@ import pyalchemybiz.lib.app_globals as app_globals
|
||||||
import pyalchemybiz.lib.helpers
|
import pyalchemybiz.lib.helpers
|
||||||
from pyalchemybiz.config.routing import make_map
|
from pyalchemybiz.config.routing import make_map
|
||||||
|
|
||||||
|
from pyalchemybiz.model import init_model
|
||||||
|
|
||||||
def load_environment(global_conf, app_conf):
|
def load_environment(global_conf, app_conf):
|
||||||
"""Configure the Pylons environment via the ``pylons.config``
|
"""Configure the Pylons environment via the ``pylons.config``
|
||||||
|
@ -25,31 +28,36 @@ def load_environment(global_conf, app_conf):
|
||||||
templates=[os.path.join(root, 'templates')])
|
templates=[os.path.join(root, 'templates')])
|
||||||
|
|
||||||
# Initialize config with the basic options
|
# Initialize config with the basic options
|
||||||
config.init_app(global_conf, app_conf, package='pyalchemybiz',
|
config.init_app(global_conf, app_conf, package='pyalchemybiz', paths=paths)
|
||||||
template_engine='mako', paths=paths)
|
|
||||||
|
|
||||||
config['routes.map'] = make_map()
|
config['routes.map'] = make_map()
|
||||||
config['pylons.g'] = app_globals.Globals()
|
config['pylons.app_globals'] = app_globals.Globals()
|
||||||
config['pylons.h'] = pyalchemybiz.lib.helpers
|
config['pylons.h'] = pyalchemybiz.lib.helpers
|
||||||
|
|
||||||
# Customize templating options via this variable
|
# Create the Mako TemplateLookup, with the default auto-escaping
|
||||||
tmpl_options = config['buffet.template_options']
|
config['pylons.app_globals'].mako_lookup = TemplateLookup(
|
||||||
|
directories=paths['templates'],
|
||||||
|
error_handler=handle_mako_error,
|
||||||
|
module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
|
||||||
|
input_encoding='utf-8', default_filters=['escape'],
|
||||||
|
imports=['from webhelpers.html import escape'])
|
||||||
|
|
||||||
# CONFIGURATION OPTIONS HERE (note: all config options will override
|
# Setup the SQLAlchemy database engine
|
||||||
# any Pylons config options)
|
engine = engine_from_config(config, 'sqlalchemy.')
|
||||||
engine = \
|
|
||||||
engine_from_config(config, 'sqlalchemy.default.')
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
init_model(engine)
|
init_model(engine)
|
||||||
except Exception:
|
except NoSuchTableError:
|
||||||
# special handling for calls in websetup.py
|
# special handling for calls in websetup.py
|
||||||
import inspect
|
import inspect
|
||||||
frame = inspect.currentframe()
|
frame = inspect.currentframe()
|
||||||
try:
|
try:
|
||||||
functions = [current[3] for current in \
|
functions = [current[3] for current in \
|
||||||
inspect.getouterframes(frame)]
|
inspect.getouterframes(frame)]
|
||||||
if functions[1] != 'setup_config':
|
if functions[1] != 'setup_app':
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
del frame
|
del frame
|
||||||
|
|
||||||
|
# CONFIGURATION OPTIONS HERE (note: all config options will override
|
||||||
|
# any Pylons config options)
|
||||||
|
|
|
@ -1,19 +1,17 @@
|
||||||
"""Pylons middleware initialization"""
|
"""Pylons middleware initialization"""
|
||||||
|
from beaker.middleware import CacheMiddleware, SessionMiddleware
|
||||||
from paste.cascade import Cascade
|
from paste.cascade import Cascade
|
||||||
from paste.registry import RegistryManager
|
from paste.registry import RegistryManager
|
||||||
from paste.urlparser import StaticURLParser
|
from paste.urlparser import StaticURLParser
|
||||||
from paste.deploy.converters import asbool
|
from paste.deploy.converters import asbool
|
||||||
|
|
||||||
from pylons import config
|
from pylons import config
|
||||||
from pylons.error import error_template
|
from pylons.middleware import ErrorHandler, StatusCodeRedirect
|
||||||
from pylons.middleware import error_mapper, ErrorDocuments, ErrorHandler, \
|
|
||||||
StaticJavascripts
|
|
||||||
from pylons.wsgiapp import PylonsApp
|
from pylons.wsgiapp import PylonsApp
|
||||||
|
from routes.middleware import RoutesMiddleware
|
||||||
|
|
||||||
from pyalchemybiz.config.environment import load_environment
|
from pyalchemybiz.config.environment import load_environment
|
||||||
|
|
||||||
|
def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
|
||||||
def make_app(global_conf, full_stack=True, **app_conf):
|
|
||||||
"""Create a Pylons WSGI application and return it
|
"""Create a Pylons WSGI application and return it
|
||||||
|
|
||||||
``global_conf``
|
``global_conf``
|
||||||
|
@ -21,15 +19,20 @@ def make_app(global_conf, full_stack=True, **app_conf):
|
||||||
the [DEFAULT] section of the Paste ini file.
|
the [DEFAULT] section of the Paste ini file.
|
||||||
|
|
||||||
``full_stack``
|
``full_stack``
|
||||||
Whether or not this application provides a full WSGI stack (by
|
Whether this application provides a full WSGI stack (by default,
|
||||||
default, meaning it handles its own exceptions and errors).
|
meaning it handles its own exceptions and errors). Disable
|
||||||
Disable full_stack when this application is "managed" by
|
full_stack when this application is "managed" by another WSGI
|
||||||
another WSGI middleware.
|
middleware.
|
||||||
|
|
||||||
|
``static_files``
|
||||||
|
Whether this application serves its own static files; disable
|
||||||
|
when another web server is responsible for serving them.
|
||||||
|
|
||||||
``app_conf``
|
``app_conf``
|
||||||
The application's local configuration. Normally specified in the
|
The application's local configuration. Normally specified in
|
||||||
[app:<name>] section of the Paste ini file (where <name>
|
the [app:<name>] section of the Paste ini file (where <name>
|
||||||
defaults to main).
|
defaults to main).
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# Configure the Pylons environment
|
# Configure the Pylons environment
|
||||||
load_environment(global_conf, app_conf)
|
load_environment(global_conf, app_conf)
|
||||||
|
@ -37,22 +40,30 @@ def make_app(global_conf, full_stack=True, **app_conf):
|
||||||
# The Pylons WSGI app
|
# The Pylons WSGI app
|
||||||
app = PylonsApp()
|
app = PylonsApp()
|
||||||
|
|
||||||
|
# Routing/Session/Cache Middleware
|
||||||
|
app = RoutesMiddleware(app, config['routes.map'])
|
||||||
|
app = SessionMiddleware(app, config)
|
||||||
|
app = CacheMiddleware(app, config)
|
||||||
|
|
||||||
# CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
|
# CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
|
||||||
|
|
||||||
if asbool(full_stack):
|
if asbool(full_stack):
|
||||||
# Handle Python exceptions
|
# Handle Python exceptions
|
||||||
app = ErrorHandler(app, global_conf, error_template=error_template,
|
app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
|
||||||
**config['pylons.errorware'])
|
|
||||||
|
|
||||||
# Display error documents for 401, 403, 404 status codes (and
|
# Display error documents for 401, 403, 404 status codes (and
|
||||||
# 500 when debug is disabled)
|
# 500 when debug is disabled)
|
||||||
app = ErrorDocuments(app, global_conf, mapper=error_mapper, **app_conf)
|
if asbool(config['debug']):
|
||||||
|
app = StatusCodeRedirect(app)
|
||||||
|
else:
|
||||||
|
app = StatusCodeRedirect(app, [400, 401, 403, 404, 500])
|
||||||
|
|
||||||
# Establish the Registry for this application
|
# Establish the Registry for this application
|
||||||
app = RegistryManager(app)
|
app = RegistryManager(app)
|
||||||
|
|
||||||
# Static files
|
if asbool(static_files):
|
||||||
javascripts_app = StaticJavascripts()
|
# Serve static files
|
||||||
static_app = StaticURLParser(config['pylons.paths']['static_files'])
|
static_app = StaticURLParser(config['pylons.paths']['static_files'])
|
||||||
app = Cascade([static_app, javascripts_app, app])
|
app = Cascade([static_app, app])
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
|
@ -7,19 +7,21 @@ refer to the routes manual at http://routes.groovie.org/docs/
|
||||||
from pylons import config
|
from pylons import config
|
||||||
from routes import Mapper
|
from routes import Mapper
|
||||||
|
|
||||||
|
|
||||||
def make_map():
|
def make_map():
|
||||||
"""Create, configure and return the routes Mapper"""
|
"""Create, configure and return the routes Mapper"""
|
||||||
map = Mapper(directory=config['pylons.paths']['controllers'],
|
map = Mapper(directory=config['pylons.paths']['controllers'],
|
||||||
always_scan=config['debug'])
|
always_scan=config['debug'])
|
||||||
|
map.minimization = False
|
||||||
|
|
||||||
# The ErrorController route (handles 404/500 error pages); it should
|
# The ErrorController route (handles 404/500 error pages); it should
|
||||||
# likely stay at the top, ensuring it can always be resolved
|
# likely stay at the top, ensuring it can always be resolved
|
||||||
map.connect('error/:action/:id', controller='error')
|
map.connect('/error/{action}', controller='error')
|
||||||
|
map.connect('/error/{action}/{id}', controller='error')
|
||||||
|
|
||||||
# CUSTOM ROUTES HERE
|
# CUSTOM ROUTES HERE
|
||||||
map.connect('', controller='index', action='index')
|
|
||||||
map.connect(':controller/:action/:id')
|
map.connect('/', controller='index', action='index')
|
||||||
map.connect('*url', controller='template', action='view')
|
map.connect('/{controller}/{action}')
|
||||||
|
map.connect('/{controller}/{action}/{id}')
|
||||||
|
|
||||||
return map
|
return map
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
import cgi
|
import cgi
|
||||||
import os.path
|
|
||||||
|
|
||||||
from paste.urlparser import StaticURLParser
|
from paste.urlparser import PkgResourcesParser
|
||||||
from pylons.middleware import error_document_template, media_path
|
from pylons import request
|
||||||
|
from pylons.controllers.util import forward
|
||||||
from pyalchemybiz.lib.base import *
|
from pylons.middleware import error_document_template
|
||||||
|
from webhelpers.html.builder import literal
|
||||||
|
|
||||||
|
from pyalchemybiz.lib.base import BaseController
|
||||||
|
|
||||||
class ErrorController(BaseController):
|
class ErrorController(BaseController):
|
||||||
|
|
||||||
"""Generates error documents as and when they are required.
|
"""Generates error documents as and when they are required.
|
||||||
|
|
||||||
The ErrorDocuments middleware forwards to ErrorController when error
|
The ErrorDocuments middleware forwards to ErrorController when error
|
||||||
|
@ -20,24 +22,25 @@ class ErrorController(BaseController):
|
||||||
|
|
||||||
def document(self):
|
def document(self):
|
||||||
"""Render the error document"""
|
"""Render the error document"""
|
||||||
|
resp = request.environ.get('pylons.original_response')
|
||||||
|
content = literal(resp.body) or cgi.escape(request.GET.get('message', ''))
|
||||||
page = error_document_template % \
|
page = error_document_template % \
|
||||||
dict(prefix=request.environ.get('SCRIPT_NAME', ''),
|
dict(prefix=request.environ.get('SCRIPT_NAME', ''),
|
||||||
code=cgi.escape(request.params.get('code', '')),
|
code=cgi.escape(request.GET.get('code', str(resp.status_int))),
|
||||||
message=cgi.escape(request.params.get('message', '')))
|
message=content)
|
||||||
return page
|
return page
|
||||||
|
|
||||||
def img(self, id):
|
def img(self, id):
|
||||||
"""Serve Pylons' stock images"""
|
"""Serve Pylons' stock images"""
|
||||||
return self._serve_file(os.path.join(media_path, 'img'), id)
|
return self._serve_file('/'.join(['media/img', id]))
|
||||||
|
|
||||||
def style(self, id):
|
def style(self, id):
|
||||||
"""Serve Pylons' stock stylesheets"""
|
"""Serve Pylons' stock stylesheets"""
|
||||||
return self._serve_file(os.path.join(media_path, 'style'), id)
|
return self._serve_file('/'.join(['media/style', id]))
|
||||||
|
|
||||||
def _serve_file(self, root, path):
|
def _serve_file(self, path):
|
||||||
"""Call Paste's FileApp (a WSGI application) to serve the file
|
"""Call Paste's FileApp (a WSGI application) to serve the file
|
||||||
at the specified path
|
at the specified path
|
||||||
"""
|
"""
|
||||||
static = StaticURLParser(root)
|
|
||||||
request.environ['PATH_INFO'] = '/%s' % path
|
request.environ['PATH_INFO'] = '/%s' % path
|
||||||
return static(request.environ, self.start_response)
|
return forward(PkgResourcesParser('pylons', 'pylons'))
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from pyalchemybiz.lib.base import *
|
from pyalchemybiz.lib.base import *
|
||||||
|
from pylons.i18n.translation import ugettext, _, set_lang, get_lang
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
"""The application's Globals object"""
|
"""The application's Globals object"""
|
||||||
from pylons import config
|
|
||||||
|
|
||||||
|
|
||||||
class Globals(object):
|
class Globals(object):
|
||||||
|
|
||||||
"""Globals acts as a container for objects available throughout the
|
"""Globals acts as a container for objects available throughout the
|
||||||
life of the application
|
life of the application
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""One instance of Globals is created during application
|
"""One instance of Globals is created during application
|
||||||
initialization and is available during requests via the 'g'
|
initialization and is available during requests via the
|
||||||
variable
|
'app_globals' variable
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pass
|
|
||||||
|
|
|
@ -1,40 +1,37 @@
|
||||||
"""The base Controller API
|
"""The base Controller API
|
||||||
|
|
||||||
Provides the BaseController class for subclassing, and other objects
|
Provides the BaseController class for subclassing.
|
||||||
utilized by Controllers.
|
|
||||||
"""
|
"""
|
||||||
from pylons import c, cache, config, g, request, response, session
|
from pylons import c, cache, config, g, request, response, session
|
||||||
from pylons.controllers import WSGIController
|
from pylons.controllers import WSGIController
|
||||||
from pylons.controllers.util import abort, etag_cache, redirect_to
|
from pylons.controllers.util import abort, etag_cache, redirect_to
|
||||||
from pylons.decorators import jsonify, validate
|
from pylons.decorators import jsonify, validate
|
||||||
from pylons.i18n import _, ungettext, N_, add_fallback, set_lang
|
from pylons.i18n.translation import _, ugettext, add_fallback
|
||||||
from pylons.templating import render
|
from pylons.templating import render_mako as render
|
||||||
|
|
||||||
import pyalchemybiz.lib.helpers as h
|
import pyalchemybiz.lib.helpers as h
|
||||||
|
|
||||||
from pyalchemybiz.model import meta
|
from pyalchemybiz.model import meta
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class BaseController(WSGIController):
|
class BaseController(WSGIController):
|
||||||
|
|
||||||
def __call__(self, environ, start_response):
|
def __before__(self):
|
||||||
"""Invoke the Controller"""
|
|
||||||
# WSGIController.__call__ dispatches to the Controller method
|
|
||||||
# the request is routed to. This routing information is
|
|
||||||
# available in environ['pylons.routes_dict']
|
|
||||||
# set language environment
|
# set language environment
|
||||||
for lang in request.languages:
|
for lang in request.languages:
|
||||||
try:
|
try:
|
||||||
add_fallback(lang)
|
add_fallback(lang)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def __call__(self, environ, start_response):
|
||||||
|
"""Invoke the Controller"""
|
||||||
|
# WSGIController.__call__ dispatches to the Controller method
|
||||||
|
# the request is routed to. This routing information is
|
||||||
|
# available in environ['pylons.routes_dict']
|
||||||
# connect to database
|
# connect to database
|
||||||
try:
|
try:
|
||||||
return WSGIController.__call__(self, environ, start_response)
|
return WSGIController.__call__(self, environ, start_response)
|
||||||
finally:
|
finally:
|
||||||
meta.Session.remove()
|
meta.Session.remove()
|
||||||
|
|
||||||
|
|
||||||
# Include the '_' function in the public names
|
|
||||||
__all__ = [__name for __name in locals().keys() if not __name.startswith('_') \
|
|
||||||
or __name == '_']
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
"""Helper functions
|
"""Helper functions
|
||||||
|
|
||||||
Consists of functions to typically be used within templates, but also
|
Consists of functions to typically be used within templates, but also
|
||||||
available to Controllers. This module is available to both as 'h'.
|
available to Controllers. This module is available to templates as 'h'.
|
||||||
"""
|
"""
|
||||||
from webhelpers.html.tags import *
|
from webhelpers.html.tags import *
|
||||||
from routes import url_for, redirect_to
|
from routes import url_for, redirect_to
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
"""SQLAlchemy Metadata and Session object"""
|
"""SQLAlchemy Metadata and Session object"""
|
||||||
from sqlalchemy import MetaData
|
from sqlalchemy import MetaData
|
||||||
|
from sqlalchemy.orm import scoped_session, sessionmaker
|
||||||
|
|
||||||
__all__ = ['engine', 'metadata', 'Session']
|
__all__ = ['Session', 'engine', 'metadata']
|
||||||
|
|
||||||
# SQLAlchemy database engine. Updated by model.init_model().
|
# SQLAlchemy database engine. Updated by model.init_model()
|
||||||
engine = None
|
engine = None
|
||||||
|
|
||||||
# SQLAlchemy session manager. Updated by model.init_model().
|
# SQLAlchemy session manager. Updated by model.init_model()
|
||||||
Session = None
|
Session = scoped_session(sessionmaker())
|
||||||
|
|
||||||
# Global metadata. If you have multiple databases with overlapping table
|
# Global metadata. If you have multiple databases with overlapping table
|
||||||
# names, you'll need a metadata for each database.
|
# names, you'll need a metadata for each database
|
||||||
metadata = MetaData()
|
metadata = MetaData()
|
||||||
|
|
0
pyalchemybiz/public/js/pyalchemybiz.js
Normal file
0
pyalchemybiz/public/js/pyalchemybiz.js
Normal file
0
pyalchemybiz/public/pyalchemybiz.css
Normal file
0
pyalchemybiz/public/pyalchemybiz.css
Normal file
|
@ -6,7 +6,7 @@
|
||||||
<head>
|
<head>
|
||||||
<title>${self.title()}</title>
|
<title>${self.title()}</title>
|
||||||
${h.stylesheet_link('/pyalchemybiz.css')}
|
${h.stylesheet_link('/pyalchemybiz.css')}
|
||||||
${h.javascript_link('/javascripts/jquery.js', '/javascripts/pyalchemybiz.js')}
|
${h.javascript_link('/js/jquery.js', '/js/pyalchemybiz.js')}
|
||||||
${self.head()}
|
${self.head()}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<ul id="customers">
|
<ul id="customers">
|
||||||
% for customer in c.customers:
|
% for customer in c.customers:
|
||||||
<li>${customer | h} [${h.link_to(_('view customer'), h.url_for(id=customer.id, action='view'))}] [${h.link_to(_('edit customer'), h.url_for(id=customer.id, action="edit"))}] [${h.link_to(_('delete customer'), h.url_for(id=customer.id, action="delete"))}]</li>
|
<li>${customer} [${h.link_to(_('view customer'), h.url_for(id=customer.id, action='view'))}] [${h.link_to(_('edit customer'), h.url_for(id=customer.id, action="edit"))}] [${h.link_to(_('delete customer'), h.url_for(id=customer.id, action="delete"))}]</li>
|
||||||
% endfor
|
% endfor
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
|
@ -1,41 +1,36 @@
|
||||||
"""Pylons application test package
|
"""Pylons application test package
|
||||||
|
|
||||||
When the test runner finds and executes tests within this directory,
|
This package assumes the Pylons environment is already loaded, such as
|
||||||
this file will be loaded to setup the test environment.
|
when this script is imported from the `nosetests --with-pylons=test.ini`
|
||||||
|
command.
|
||||||
|
|
||||||
It registers the root directory of the project in sys.path and
|
This module initializes the application via ``websetup`` (`paster
|
||||||
pkg_resources, in case the project hasn't been installed with
|
setup-app`) and provides the base testing objects.
|
||||||
setuptools. It also initializes the application via websetup (paster
|
|
||||||
setup-app) with the project's test.ini configuration file.
|
|
||||||
"""
|
"""
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
import pkg_resources
|
|
||||||
import paste.fixture
|
|
||||||
import paste.script.appinstall
|
|
||||||
from paste.deploy import loadapp
|
from paste.deploy import loadapp
|
||||||
from routes import url_for
|
from paste.script.appinstall import SetupCommand
|
||||||
|
from pylons import config, url
|
||||||
|
from routes.util import URLGenerator
|
||||||
|
from webtest import TestApp
|
||||||
|
|
||||||
__all__ = ['url_for', 'TestController']
|
import pylons.test
|
||||||
|
|
||||||
here_dir = os.path.dirname(os.path.abspath(__file__))
|
__all__ = ['environ', 'url', 'TestController']
|
||||||
conf_dir = os.path.dirname(os.path.dirname(here_dir))
|
|
||||||
|
|
||||||
sys.path.insert(0, conf_dir)
|
# Invoke websetup with the current config file
|
||||||
pkg_resources.working_set.add_entry(conf_dir)
|
SetupCommand('setup-app').run([config['__file__']])
|
||||||
pkg_resources.require('Paste')
|
|
||||||
pkg_resources.require('PasteScript')
|
|
||||||
|
|
||||||
test_file = os.path.join(conf_dir, 'test.ini')
|
|
||||||
cmd = paste.script.appinstall.SetupCommand('setup-app')
|
|
||||||
cmd.run([test_file])
|
|
||||||
|
|
||||||
|
environ = {}
|
||||||
|
|
||||||
class TestController(TestCase):
|
class TestController(TestCase):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
wsgiapp = loadapp('config:test.ini', relative_to=conf_dir)
|
if pylons.test.pylonsapp:
|
||||||
self.app = paste.fixture.TestApp(wsgiapp)
|
wsgiapp = pylons.test.pylonsapp
|
||||||
|
else:
|
||||||
|
wsgiapp = loadapp('config:%s' % config['__file__'])
|
||||||
|
self.app = TestApp(wsgiapp)
|
||||||
|
url._push_object(URLGenerator(config['routes.map'], environ))
|
||||||
TestCase.__init__(self, *args, **kwargs)
|
TestCase.__init__(self, *args, **kwargs)
|
||||||
|
|
|
@ -13,14 +13,13 @@ from pyalchemybiz.config.environment import load_environment
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def setup_config(command, filename, section, vars):
|
def setup_app(command, conf, vars):
|
||||||
"""Place any commands to setup pyalchemybiz here"""
|
"""Place any commands to setup pyalchemybiz here"""
|
||||||
conf = appconfig('config:' + filename)
|
|
||||||
load_environment(conf.global_conf, conf.local_conf)
|
load_environment(conf.global_conf, conf.local_conf)
|
||||||
|
|
||||||
repoversion = int(config.get('migrate.repo.version'))
|
repoversion = int(config.get('migrate.repo.version'))
|
||||||
repodir = config.get('migrate.repo.dir')
|
repodir = config.get('migrate.repo.dir')
|
||||||
dburl = config.get('sqlalchemy.default.url')
|
dburl = config.get('sqlalchemy.url')
|
||||||
|
|
||||||
# Populate the DB on 'paster setup-app'
|
# Populate the DB on 'paster setup-app'
|
||||||
|
|
||||||
|
|
32
setup.cfg
32
setup.cfg
|
@ -5,36 +5,8 @@ tag_svn_revision = true
|
||||||
[easy_install]
|
[easy_install]
|
||||||
find_links = http://www.pylonshq.com/download/
|
find_links = http://www.pylonshq.com/download/
|
||||||
|
|
||||||
[pudge]
|
[nosetests]
|
||||||
theme = pythonpaste.org
|
with-pylons = test.ini
|
||||||
|
|
||||||
# Add extra doc files here with spaces between them
|
|
||||||
docs = docs/index.txt
|
|
||||||
|
|
||||||
# Doc Settings
|
|
||||||
doc_base = docs/
|
|
||||||
dest = docs/html
|
|
||||||
|
|
||||||
# Add extra modules here separated with commas
|
|
||||||
modules = pyalchemybiz
|
|
||||||
title = Pyalchemybiz
|
|
||||||
organization = Pylons
|
|
||||||
|
|
||||||
# Highlight code-block sections with Pygments
|
|
||||||
highlighter = pygments
|
|
||||||
|
|
||||||
# Optionally add extra links
|
|
||||||
#organization_url = http://pylonshq.com/
|
|
||||||
#trac_url = http://pylonshq.com/project
|
|
||||||
settings = no_about=true
|
|
||||||
|
|
||||||
# Optionally add extra settings
|
|
||||||
# link1=/community/ Community
|
|
||||||
# link2=/download/ Download
|
|
||||||
|
|
||||||
[publish]
|
|
||||||
doc-dir=docs/html
|
|
||||||
make-dirs=1
|
|
||||||
|
|
||||||
# Babel configuration
|
# Babel configuration
|
||||||
[compile_catalog]
|
[compile_catalog]
|
||||||
|
|
19
setup.py
19
setup.py
|
@ -7,21 +7,32 @@ except ImportError:
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='pyalchemybiz',
|
name='pyalchemybiz',
|
||||||
version="0.1",
|
version='0.1',
|
||||||
description='python based small business suite.',
|
description='python based small business suite.',
|
||||||
author='Jan Dittberner',
|
author='Jan Dittberner',
|
||||||
author_email='jan@dittberner.info',
|
author_email='jan@dittberner.info',
|
||||||
url='http://www.dittberner.info/projects/pyalchemybiz',
|
url='http://www.dittberner.info/projects/pyalchemybiz',
|
||||||
install_requires=["Pylons>=0.9.7", "SQLAlchemy>=0.5.2",
|
install_requires=[
|
||||||
"sqlalchemy-migrate>=0.5.2"],
|
"Pylons>=0.9.7",
|
||||||
|
"SQLAlchemy>=0.5.2,<0.6",
|
||||||
|
"sqlalchemy-migrate>=0.5.2,<0.6",
|
||||||
|
"Mako",
|
||||||
|
"FormBuild>=2.0,<3",
|
||||||
|
],
|
||||||
|
setup_requires=[
|
||||||
|
"PasteScript>=1.6.3",
|
||||||
|
"Babel>=0.9.1",
|
||||||
|
],
|
||||||
packages=find_packages(exclude=['ez_setup']),
|
packages=find_packages(exclude=['ez_setup']),
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
test_suite='nose.collector',
|
test_suite='nose.collector',
|
||||||
package_data={'pyalchemybiz': ['i18n/*/LC_MESSAGES/*.mo']},
|
package_data={'pyalchemybiz': ['i18n/*/LC_MESSAGES/*.mo']},
|
||||||
message_extractors = {'pyalchemybiz': [
|
message_extractors = {'pyalchemybiz': [
|
||||||
('**.py', 'python', None),
|
('**.py', 'python', None),
|
||||||
('templates/**.mako', 'mako', None),
|
('templates/**.mako', 'mako', {'input_encoding': 'utf-8'}),
|
||||||
('public/**', 'ignore', None)]},
|
('public/**', 'ignore', None)]},
|
||||||
|
zip_safe=False,
|
||||||
|
paster_plugins=['PasteScript', 'Pylons'],
|
||||||
entry_points="""
|
entry_points="""
|
||||||
[paste.app_factory]
|
[paste.app_factory]
|
||||||
main = pyalchemybiz.config.middleware:make_app
|
main = pyalchemybiz.config.middleware:make_app
|
||||||
|
|
2
test.ini
2
test.ini
|
@ -12,7 +12,7 @@ error_email_from = paste@localhost
|
||||||
|
|
||||||
[server:main]
|
[server:main]
|
||||||
use = egg:Paste#http
|
use = egg:Paste#http
|
||||||
host = 0.0.0.0
|
host = 127.0.0.1
|
||||||
port = 5000
|
port = 5000
|
||||||
|
|
||||||
[app:main]
|
[app:main]
|
||||||
|
|
Loading…
Reference in a new issue