initial Pylons code (fixes #3)

git-svn-id: file:///var/www/wwwusers/usr01/svn/pyalchemybiz/trunk@5 389c73d4-bf09-4d3d-a15e-f94a37d0667a
This commit is contained in:
Jan Dittberner 2008-10-05 15:23:54 +00:00
parent 38d4c952cf
commit 554276ed23
42 changed files with 930 additions and 47 deletions

2
MANIFEST.in Normal file
View file

@ -0,0 +1,2 @@
recursive-include pyalchemybiz/public *
recursive-include pyalchemybiz/templates *

19
README.txt Normal file
View file

@ -0,0 +1,19 @@
This file is for you to describe the pyalchemybiz application. Typically
you would include information such as the information below:
Installation and Setup
======================
Install ``pyalchemybiz`` using easy_install::
easy_install pyalchemybiz
Make a config file as follows::
paster make-config pyalchemybiz config.ini
Tweak the config file as appropriate and then setup the application::
paster setup-app config.ini
Then you are ready to go.

View file

@ -0,0 +1,45 @@
from mako import runtime, filters, cache
UNDEFINED = runtime.UNDEFINED
__M_dict_builtin = dict
__M_locals_builtin = locals
_magic_number = 4
_modified_time = 1223071301.6449161
_template_filename=u'/home/jan/src/pyalchemybiz/pyalchemybiz/templates/base.mako'
_template_uri=u'/base.mako'
_template_cache=cache.Cache(__name__, _modified_time)
_source_encoding=None
_exports = []
def render_body(context,**pageargs):
context.caller_stack._push_frame()
try:
__M_locals = __M_dict_builtin(pageargs=pageargs)
h = context.get('h', UNDEFINED)
next = context.get('next', UNDEFINED)
__M_writer = context.writer()
# SOURCE LINE 1
__M_writer(u'<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.1//EN"\n "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n<html>\n <head>\n <title>PyAlchemyBiz</title>\n ')
# SOURCE LINE 6
__M_writer(unicode(h.stylesheet_link_tag('/pyalchemybiz.css')))
__M_writer(u'\n ')
# SOURCE LINE 7
__M_writer(unicode(h.javascript_include_tag(
'/javascripts/pyalchemybiz.js', builtins=True)))
# SOURCE LINE 8
__M_writer(u'\n </head>\n <body>\n <div class="content">\n ')
# SOURCE LINE 12
__M_writer(unicode(next.body()))
__M_writer(u'')
# SOURCE LINE 13
__M_writer(u' <p class="footer">\n Return to the\n ')
# SOURCE LINE 15
__M_writer(unicode(h.link_to('FrontPage',
h.url_for(action="index"))))
# SOURCE LINE 16
__M_writer(u'\n </p>\n </div>\n </body>\n</html>\n')
return ''
finally:
context.caller_stack._pop_frame()

View file

@ -0,0 +1,50 @@
from mako import runtime, filters, cache
UNDEFINED = runtime.UNDEFINED
__M_dict_builtin = dict
__M_locals_builtin = locals
_magic_number = 4
_modified_time = 1223072023.421654
_template_filename='/home/jan/src/pyalchemybiz/pyalchemybiz/templates/customer.mako'
_template_uri='/customer.mako'
_template_cache=cache.Cache(__name__, _modified_time)
_source_encoding=None
_exports = []
def _mako_get_namespace(context, name):
try:
return context.namespaces[(__name__, name)]
except KeyError:
_mako_generate_namespaces(context)
return context.namespaces[(__name__, name)]
def _mako_generate_namespaces(context):
pass
def _mako_inherit(template, context):
_mako_generate_namespaces(context)
return runtime._inherit_from(context, u'base.mako', _template_uri)
def render_body(context,**pageargs):
context.caller_stack._push_frame()
try:
__M_locals = __M_dict_builtin(pageargs=pageargs)
h = context.get('h', UNDEFINED)
c = context.get('c', UNDEFINED)
__M_writer = context.writer()
# SOURCE LINE 1
__M_writer(u'\n\n<h1>Hallo</h1>\n\n<ul id="customers">\n')
# SOURCE LINE 6
for customer in c.customers:
# SOURCE LINE 7
__M_writer(u' <li>')
__M_writer(unicode(customer.firstname))
__M_writer(u'&nbsp;')
__M_writer(unicode(customer.lastname))
__M_writer(u' [')
__M_writer(unicode(h.link_to('edit', h.url_for(id=customer.id, action="edit"))))
__M_writer(u']</li>\n')
# SOURCE LINE 9
__M_writer(u'</ul>\n')
return ''
finally:
context.caller_stack._pop_frame()

70
development.ini Normal file
View file

@ -0,0 +1,70 @@
#
# pyalchemybiz - Pylons development environment configuration
#
# The %(here)s variable will be replaced with the parent directory of this file
#
[DEFAULT]
debug = true
# Uncomment and replace with the address which should receive any error reports
#email_to = you@yourdomain.com
smtp_server = localhost
error_email_from = paste@localhost
[server:main]
use = egg:Paste#http
host = 0.0.0.0
port = 5000
[app:main]
use = egg:pyalchemybiz
full_stack = true
cache_dir = %(here)s/data
beaker.session.key = pyalchemybiz
beaker.session.secret = somesecret
# If you'd like to fine-tune the individual locations of the cache data dirs
# for the Cache data, or the Session saves, un-comment the desired settings
# here:
#beaker.cache.data_dir = %(here)s/data/cache
#beaker.session.data_dir = %(here)s/data/sessions
# 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
# 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
# Logging configuration
[loggers]
keys = root, pyalchemybiz
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = INFO
handlers = console
[logger_pyalchemybiz]
level = DEBUG
handlers =
qualname = pyalchemybiz
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S

12
docs/index.txt Normal file
View file

@ -0,0 +1,12 @@
pyalchemybiz
++++++++++++
This is the main index page of your documentation. It should be written in
`reStructuredText format <http://docutils.sourceforge.net/rst.html>`_.
You can generate your documentation in HTML format by running this command::
setup.py pudge
For this to work you will need to download and install ``buildutils`` and
``pudge``.

View file

@ -0,0 +1,10 @@
Metadata-Version: 1.0
Name: pyalchemybiz
Version: 0.0.0dev
Summary: UNKNOWN
Home-page: UNKNOWN
Author: UNKNOWN
Author-email: UNKNOWN
License: UNKNOWN
Description: UNKNOWN
Platform: UNKNOWN

View file

@ -0,0 +1,29 @@
MANIFEST.in
README.txt
setup.cfg
setup.py
pyalchemybiz/__init__.py
pyalchemybiz/websetup.py
pyalchemybiz.egg-info/PKG-INFO
pyalchemybiz.egg-info/SOURCES.txt
pyalchemybiz.egg-info/dependency_links.txt
pyalchemybiz.egg-info/entry_points.txt
pyalchemybiz.egg-info/paste_deploy_config.ini_tmpl
pyalchemybiz.egg-info/requires.txt
pyalchemybiz.egg-info/top_level.txt
pyalchemybiz/config/__init__.py
pyalchemybiz/config/environment.py
pyalchemybiz/config/middleware.py
pyalchemybiz/config/routing.py
pyalchemybiz/controllers/__init__.py
pyalchemybiz/controllers/error.py
pyalchemybiz/controllers/template.py
pyalchemybiz/lib/__init__.py
pyalchemybiz/lib/app_globals.py
pyalchemybiz/lib/base.py
pyalchemybiz/lib/helpers.py
pyalchemybiz/model/__init__.py
pyalchemybiz/public/index.html
pyalchemybiz/tests/__init__.py
pyalchemybiz/tests/test_models.py
pyalchemybiz/tests/functional/__init__.py

View file

@ -0,0 +1 @@

View file

@ -0,0 +1,7 @@
[paste.app_factory]
main = pyalchemybiz.config.middleware:make_app
[paste.app_install]
main = pylons.util:PylonsInstaller

View file

@ -0,0 +1,64 @@
#
# pyalchemybiz - Pylons configuration
#
# The %(here)s variable will be replaced with the parent directory of this file
#
[DEFAULT]
debug = true
email_to = you@yourdomain.com
smtp_server = localhost
error_email_from = paste@localhost
[server:main]
use = egg:Paste#http
host = 0.0.0.0
port = 5000
[app:main]
use = egg:pyalchemybiz
full_stack = true
cache_dir = %(here)s/data
beaker.session.key = pyalchemybiz
beaker.session.secret = ${app_instance_secret}
app_instance_uuid = ${app_instance_uuid}
# If you'd like to fine-tune the individual locations of the cache data dirs
# for the Cache data, or the Session saves, un-comment the desired settings
# here:
#beaker.cache.data_dir = %(here)s/data/cache
#beaker.session.data_dir = %(here)s/data/sessions
# 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
# 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
# Logging configuration
[loggers]
keys = root
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = INFO
handlers = console
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s] %(message)s

View file

@ -0,0 +1,2 @@
Pylons
WebHelpers

View file

@ -0,0 +1 @@
Pylons>=0.9.6.2

View file

@ -0,0 +1 @@
pyalchemybiz

View file

@ -1,8 +0,0 @@
# -*- coding: utf-8 -*-
#
# Package pyalchemybiz
#
# Author: Jan Dittberner <jan@dittberner.info>
# Version: $Id$
#
# This file is part of pyalchemybiz

View file

View file

@ -0,0 +1,38 @@
"""Pylons environment configuration"""
import os
from pylons import config
from sqlalchemy import engine_from_config
from pyalchemybiz.model import init_model
import pyalchemybiz.lib.app_globals as app_globals
import pyalchemybiz.lib.helpers
from pyalchemybiz.config.routing import make_map
def load_environment(global_conf, app_conf):
"""Configure the Pylons environment via the ``pylons.config``
object
"""
# Pylons paths
root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
paths = dict(root=root,
controllers=os.path.join(root, 'controllers'),
static_files=os.path.join(root, 'public'),
templates=[os.path.join(root, 'templates')])
# Initialize config with the basic options
config.init_app(global_conf, app_conf, package='pyalchemybiz',
template_engine='mako', paths=paths)
config['routes.map'] = make_map()
config['pylons.g'] = app_globals.Globals()
config['pylons.h'] = pyalchemybiz.lib.helpers
# Customize templating options via this variable
tmpl_options = config['buffet.template_options']
# CONFIGURATION OPTIONS HERE (note: all config options will override
# any Pylons config options)
engine = \
engine_from_config(config, 'sqlalchemy.default.')
init_model(engine)

View file

@ -0,0 +1,57 @@
"""Pylons middleware initialization"""
from paste.cascade import Cascade
from paste.registry import RegistryManager
from paste.urlparser import StaticURLParser
from paste.deploy.converters import asbool
from pylons import config
from pylons.error import error_template
from pylons.middleware import error_mapper, ErrorDocuments, ErrorHandler, \
StaticJavascripts
from pylons.wsgiapp import PylonsApp
from pyalchemybiz.config.environment import load_environment
def make_app(global_conf, full_stack=True, **app_conf):
"""Create a Pylons WSGI application and return it
``global_conf``
The inherited configuration for this application. Normally from
the [DEFAULT] section of the Paste ini file.
``full_stack``
Whether or not this application provides a full WSGI stack (by
default, meaning it handles its own exceptions and errors).
Disable full_stack when this application is "managed" by
another WSGI middleware.
``app_conf``
The application's local configuration. Normally specified in the
[app:<name>] section of the Paste ini file (where <name>
defaults to main).
"""
# Configure the Pylons environment
load_environment(global_conf, app_conf)
# The Pylons WSGI app
app = PylonsApp()
# CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
if asbool(full_stack):
# Handle Python exceptions
app = ErrorHandler(app, global_conf, error_template=error_template,
**config['pylons.errorware'])
# Display error documents for 401, 403, 404 status codes (and
# 500 when debug is disabled)
app = ErrorDocuments(app, global_conf, mapper=error_mapper, **app_conf)
# Establish the Registry for this application
app = RegistryManager(app)
# Static files
javascripts_app = StaticJavascripts()
static_app = StaticURLParser(config['pylons.paths']['static_files'])
app = Cascade([static_app, javascripts_app, app])
return app

View file

@ -0,0 +1,24 @@
"""Routes configuration
The more specific and detailed routes should be defined first so they
may take precedent over the more generic routes. For more information
refer to the routes manual at http://routes.groovie.org/docs/
"""
from pylons import config
from routes import Mapper
def make_map():
"""Create, configure and return the routes Mapper"""
map = Mapper(directory=config['pylons.paths']['controllers'],
always_scan=config['debug'])
# The ErrorController route (handles 404/500 error pages); it should
# likely stay at the top, ensuring it can always be resolved
map.connect('error/:action/:id', controller='error')
# CUSTOM ROUTES HERE
map.connect(':controller/:action/:id')
map.connect('*url', controller='template', action='view')
return map

View file

View file

@ -0,0 +1,20 @@
import logging
from pyalchemybiz.lib.base import *
from pyalchemybiz.model import customer, meta
log = logging.getLogger(__name__)
class CustomerController(BaseController):
def index(self):
sess = meta.Session()
cust_q = sess.query(customer.Customer)
c.customers = cust_q.all()
return render('/customer.mako')
def edit(self, id):
sess = meta.Session()
cust_q = sess.query(customer.Customer)
c.customer = cust_q.filter(customer.Customer.id==id).one()
return c.customer

View file

@ -0,0 +1,41 @@
import cgi
import os.path
from paste.urlparser import StaticURLParser
from pylons.middleware import error_document_template, media_path
from pyalchemybiz.lib.base import *
class ErrorController(BaseController):
"""Generates error documents as and when they are required.
The ErrorDocuments middleware forwards to ErrorController when error
related status codes are returned from the application.
This behaviour can be altered by changing the parameters to the
ErrorDocuments middleware in your config/middleware.py file.
"""
def document(self):
"""Render the error document"""
page = error_document_template % \
dict(prefix=request.environ.get('SCRIPT_NAME', ''),
code=cgi.escape(request.params.get('code', '')),
message=cgi.escape(request.params.get('message', '')))
return page
def img(self, id):
"""Serve Pylons' stock images"""
return self._serve_file(os.path.join(media_path, 'img'), id)
def style(self, id):
"""Serve Pylons' stock stylesheets"""
return self._serve_file(os.path.join(media_path, 'style'), id)
def _serve_file(self, root, path):
"""Call Paste's FileApp (a WSGI application) to serve the file
at the specified path
"""
static = StaticURLParser(root)
request.environ['PATH_INFO'] = '/%s' % path
return static(request.environ, self.start_response)

View file

@ -0,0 +1,27 @@
from pyalchemybiz.lib.base import *
class TemplateController(BaseController):
def view(self, url):
"""By default, the final controller tried to fulfill the request
when no other routes match. It may be used to display a template
when all else fails, e.g.::
def view(self, url):
return render('/%s' % url)
Or if you're using Mako and want to explicitly send a 404 (Not
Found) response code when the requested template doesn't exist::
import mako.exceptions
def view(self, url):
try:
return render('/%s' % url)
except mako.exceptions.TopLevelLookupException:
abort(404)
By default this controller aborts the request with a 404 (Not
Found)
"""
abort(404)

View file

View file

@ -0,0 +1,14 @@
"""The application's Globals object"""
from pylons import config
class Globals(object):
"""Globals acts as a container for objects available throughout the
life of the application
"""
def __init__(self):
"""One instance of Globals is created during application
initialization and is available during requests via the 'g'
variable
"""
pass

36
pyalchemybiz/lib/base.py Normal file
View file

@ -0,0 +1,36 @@
"""The base Controller API
Provides the BaseController class for subclassing, and other objects
utilized by Controllers.
"""
from pylons import c, cache, config, g, request, response, session
from pylons.controllers import WSGIController
from pylons.controllers.util import abort, etag_cache, redirect_to
from pylons.decorators import jsonify, validate
from pylons.i18n import _, ungettext, N_
from pylons.templating import render
import pyalchemybiz.lib.helpers as h
import pyalchemybiz.model as model
from pyalchemybiz.model import meta
from sqlalchemy.orm import sessionmaker
class BaseController(WSGIController):
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']
conn = meta.engine.connect()
meta.Session.configure(bind=conn)
try:
return WSGIController.__call__(self, environ, start_response)
finally:
meta.Session.remove()
conn.close()
# Include the '_' function in the public names
__all__ = [__name for __name in locals().keys() if not __name.startswith('_') \
or __name == '_']

View file

@ -0,0 +1,7 @@
"""Helper functions
Consists of functions to typically be used within templates, but also
available to Controllers. This module is available to both as 'h'.
"""
from webhelpers.rails.wrapped import *
from routes import url_for, redirect_to

View file

@ -0,0 +1,17 @@
import sqlalchemy as sa
from sqlalchemy import orm
from pyalchemybiz.model import meta
from pyalchemybiz.model import customer
def init_model(engine):
"""Call me before using any of the tables or classes in the model."""
sm = orm.sessionmaker(autoflush=True, transactional=True, bind=engine)
meta.engine = engine
meta.Session = orm.scoped_session(sm)
customer.t_customer = sa.Table('customer', meta.metadata,
autoload=True, autoload_with=engine)
orm.mapper(customer.Customer, customer.t_customer)

View file

@ -0,0 +1,5 @@
t_customer = None
class Customer(object):
def __str__(self):
return "%s %s" % (self.firstname, self.lastname)

View file

@ -0,0 +1,14 @@
"""SQLAlchemy Metadata and Session object"""
from sqlalchemy import MetaData
__all__ = ['engine', 'metadata', 'Session']
# SQLAlchemy database engine. Updated by model.init_model().
engine = None
# SQLAlchemy session manager. Updated by model.init_model().
Session = None
# Global metadata. If you have multiple databases with overlapping table
# names, you'll need a metadata for each database.
metadata = MetaData()

View file

@ -1,20 +0,0 @@
# -*- coding: utf-8 -*-
#
# Package pyalchemybiz
#
# Author: Jan Dittberner <jan@dittberner.info>
# Version: $Id$
#
# This file is part of pyalchemybiz
from sqlalchemy import *
def create_schema(metadata):
"""Create the database schema for products."""
product_table = Table(
'product', metadata,
Column('product_id', Integer, primary_key=True),
Column('name', String(100), nullable=False),
Column('description', String(4096), nullable=False),
Column('product_type', Integer, nullable=False)
)
product_table.create()

View file

@ -0,0 +1,108 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Pylons Default Page</title>
<style>
body { background-color: #fff; color: #333; }
body, p {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 12px;
line-height: 18px;
}
pre {
background-color: #eee;
padding: 10px;
font-size: 11px;
line-height: 13px;
}
a { color: #000; }
a:visited { color: #666; }
a:hover { color: #fff; background-color:#000; }
</style>
</head>
<body>
<h1>Welcome to your Pylons Web Application</h1>
<h2>Weren't expecting to see this page?</h2>
<p>The <tt>pyalchemybiz/public/</tt> directory is searched for static files
<i>before</i> your controllers are run. Remove this file (<tt>pyalchemybiz/public/index.html</tt>)
and edit the routes in <tt>pyalchemybiz/config/routing.py</tt> to point the
<a href="/">root path</a> to a 'hello' controller we'll create below:
<pre> map.connect('', controller='hello', action='index')</pre>
</p>
<h2>Getting Started</h2>
<p>You're now ready to start creating your own web application. To create a 'hello' controller,
run the following command in your project's root directory:
<pre>
pyalchemybiz$ paster controller hello
</pre>
This generates the following the following code in <tt>pyalchemybiz/controllers/hello.py</tt>:
<pre>
import logging
from pyalchemybiz.lib.base import *
log = logging.getLogger(__name__)
class HelloController(BaseController):
def index(self):
# Return a rendered template
# return render('/some/template.mako)
# or, Return a response
return 'Hello World'
</pre>
</p>
<p>This controller simply prints out 'Hello World' to the browser. Pylons' default routes
automatically set up this controller to respond at the <a href="/hello">/hello</a> URL.
With the additional route described above, this controller will also respond at the
<a href="/">root path</a>.
</p>
<h3>Using a template</h3>
<p>To call a template and do something a little more complex, this following example
shows how to print out some request information from a
<a href="http://www.makotemplates.org">Mako</a> template.
</p>
<p>Create a <tt>serverinfo.mako</tt> file in your project's <tt>pyalchemybiz/templates/</tt>
directory with the following contents:
</p>
<pre>
&lt;h2&gt;
Server info for ${request.host}
&lt;/h2&gt;
&lt;p&gt;
The URL you called: ${h.url_for()}
&lt;/p&gt;
&lt;p&gt;
The name you set: ${c.name}
&lt;/p&gt;
&lt;p&gt;The WSGI environ:&lt;br /&gt;
&lt;pre&gt;${c.pretty_environ}&lt;/pre&gt;
&lt;/p&gt;
</pre>
Then add the following to your 'hello' controller class:
<pre>
def serverinfo(self):
import cgi
import pprint
c.pretty_environ = cgi.escape(pprint.pformat(request.environ))
c.name = 'The Black Knight'
return render('/serverinfo.mako')
</pre>
You can now view the page at: <tt><a href="/hello/serverinfo">/hello/serverinfo</a></tt>
</p>
</body>
</html>

View file

@ -0,0 +1,20 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<title>PyAlchemyBiz</title>
${h.stylesheet_link_tag('/pyalchemybiz.css')}
${h.javascript_include_tag(
'/javascripts/pyalchemybiz.js', builtins=True)}
</head>
<body>
<div class="content">
${next.body()}\
<p class="footer">
Return to the
${h.link_to('FrontPage',
h.url_for(action="index"))}
</p>
</div>
</body>
</html>

View file

@ -0,0 +1,9 @@
<%inherit file="base.mako" />
<h1>Hallo</h1>
<ul id="customers">
% for customer in c.customers:
<li>${customer.firstname}&nbsp;${customer.lastname} [${h.link_to('edit', h.url_for(id=customer.id, action="edit"))}]</li>
% endfor
</ul>

View file

@ -0,0 +1,40 @@
"""Pylons application test package
When the test runner finds and executes tests within this directory,
this file will be loaded to setup the test environment.
It registers the root directory of the project in sys.path and
pkg_resources, in case the project hasn't been installed with
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
import pkg_resources
import paste.fixture
import paste.script.appinstall
from paste.deploy import loadapp
from routes import url_for
__all__ = ['url_for', 'TestController']
here_dir = os.path.dirname(os.path.abspath(__file__))
conf_dir = os.path.dirname(os.path.dirname(here_dir))
sys.path.insert(0, conf_dir)
pkg_resources.working_set.add_entry(conf_dir)
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])
class TestController(TestCase):
def __init__(self, *args, **kwargs):
wsgiapp = loadapp('config:test.ini', relative_to=conf_dir)
self.app = paste.fixture.TestApp(wsgiapp)
TestCase.__init__(self, *args, **kwargs)

View file

@ -0,0 +1,7 @@
from pyalchemybiz.tests import *
class TestCustomerController(TestController):
def test_index(self):
response = self.app.get(url_for(controller='customer'))
# Test response...

View file

22
pyalchemybiz/websetup.py Normal file
View file

@ -0,0 +1,22 @@
"""Setup the pyalchemybiz application"""
import logging
from paste.deploy import appconfig
from pylons import config
from pyalchemybiz.config.environment import load_environment
log = logging.getLogger(__name__)
def setup_config(command, filename, section, vars):
"""Place any commands to setup pyalchemybiz here"""
conf = appconfig('config:' + filename)
load_environment(conf.global_conf, conf.local_conf)
# Populate the DB on 'paster setup-app'
import pyalchemybiz.model as model
log.info("Setting up database connectivity...")
log.info("Creating tables...")
model.meta.metadata.create_all(bind=model.meta.engine)
log.info("Successfully set up.")

59
setup.cfg Normal file
View file

@ -0,0 +1,59 @@
[egg_info]
tag_build = dev
tag_svn_revision = true
[easy_install]
find_links = http://www.pylonshq.com/download/
[pudge]
theme = pythonpaste.org
# 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
[compile_catalog]
domain = pyalchemybiz
directory = pyalchemybiz/i18n
statistics = true
[extract_messages]
add_comments = TRANSLATORS:
output_file = pyalchemybiz/i18n/pyalchemybiz.pot
width = 80
[init_catalog]
domain = pyalchemybiz
input_file = pyalchemybiz/i18n/pyalchemybiz.pot
output_dir = pyalchemybiz/i18n
[update_catalog]
domain = pyalchemybiz
input_file = pyalchemybiz/i18n/pyalchemybiz.pot
output_dir = pyalchemybiz/i18n
previous = true

View file

@ -1,19 +1,31 @@
#!/usr/bin/env python try:
# -*- coding: utf-8 -*- from setuptools import setup, find_packages
# except ImportError:
# Author: Jan Dittberner <jan@dittberner.info> from ez_setup import use_setuptools
# Version: $Id$ use_setuptools()
# from setuptools import setup, find_packages
# This file is part of pyalchemybiz
# setup(
from setuptools import setup name='pyalchemybiz',
setup(name='pyalchemybiz', version="0.1",
description='Python SQLAlchemy Business', description='python based small business suite.',
version='0.1dev', 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.6.2", "SQLAlchemy>=0.4"],
packages=['pyalchemybiz'], packages=find_packages(exclude=['ez_setup']),
install_requires=['sqlalchemy >= 0.3.10'], include_package_data=True,
license='GPL' test_suite='nose.collector',
) package_data={'pyalchemybiz': ['i18n/*/LC_MESSAGES/*.mo']},
#message_extractors = {'pyalchemybiz': [
# ('**.py', 'python', None),
# ('templates/**.mako', 'mako', None),
# ('public/**', 'ignore', None)]},
entry_points="""
[paste.app_factory]
main = pyalchemybiz.config.middleware:make_app
[paste.app_install]
main = pylons.util:PylonsInstaller
""",
)

21
test.ini Normal file
View file

@ -0,0 +1,21 @@
#
# pyalchemybiz - Pylons testing environment configuration
#
# The %(here)s variable will be replaced with the parent directory of this file
#
[DEFAULT]
debug = true
# Uncomment and replace with the address which should receive any error reports
#email_to = you@yourdomain.com
smtp_server = localhost
error_email_from = paste@localhost
[server:main]
use = egg:Paste#http
host = 0.0.0.0
port = 5000
[app:main]
use = config:development.ini
# Add additional test specific configuration options as necessary.