Commits

Anonymous committed e550400

[all][s]: create pylons app called commentonit.

Comments (0)

Files changed (24)

+syntax: glob
+*.pyc
+commentonit.egg-info/*
+development.ini*
+pip-requirements-local.txt
+include commentonit/config/deployment.ini_tmpl
+recursive-include commentonit/public *
+recursive-include commentonit/templates *
+Comment on stuff.

commentonit/__init__.py

Empty file added.

commentonit/config/__init__.py

Empty file added.

commentonit/config/deployment.ini_tmpl

+#
+# commentonit - 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:commentonit
+full_stack = true
+static_files = true
+
+cache_dir = %(here)s/data
+beaker.session.key = commentonit
+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
+
+# SQLAlchemy database URL
+sqlalchemy.url = sqlite:///production.db
+
+# 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
+[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

commentonit/config/environment.py

+"""Pylons environment configuration"""
+import os
+
+from genshi.template import TemplateLoader
+from pylons import config
+from sqlalchemy import engine_from_config
+
+import commentonit.lib.app_globals as app_globals
+import commentonit.lib.helpers
+from commentonit.config.routing import make_map
+from commentonit.model import init_model
+
+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='commentonit', paths=paths)
+
+    config['routes.map'] = make_map()
+    config['pylons.app_globals'] = app_globals.Globals()
+    config['pylons.h'] = commentonit.lib.helpers
+
+    # Create the Genshi TemplateLoader
+    config['pylons.app_globals'].genshi_loader = TemplateLoader(
+        paths['templates'], auto_reload=True)
+
+    # Setup the SQLAlchemy database engine
+    engine = engine_from_config(config, 'sqlalchemy.')
+    init_model(engine)
+
+    # CONFIGURATION OPTIONS HERE (note: all config options will override
+    # any Pylons config options)

commentonit/config/middleware.py

+"""Pylons middleware initialization"""
+from beaker.middleware import CacheMiddleware, SessionMiddleware
+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.middleware import ErrorHandler, StatusCodeRedirect
+from pylons.wsgiapp import PylonsApp
+from routes.middleware import RoutesMiddleware
+
+from commentonit.config.environment import load_environment
+
+def make_app(global_conf, full_stack=True, static_files=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 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.
+
+    ``static_files``
+        Whether this application serves its own static files; disable
+        when another web server is responsible for serving them.
+
+    ``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()
+
+    # 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)
+
+    if asbool(full_stack):
+        # Handle Python exceptions
+        app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
+
+        # Display error documents for 401, 403, 404 status codes (and
+        # 500 when debug is disabled)
+        if asbool(config['debug']):
+            app = StatusCodeRedirect(app)
+        else:
+            app = StatusCodeRedirect(app, [400, 401, 403, 404, 500])
+
+    # Establish the Registry for this application
+    app = RegistryManager(app)
+
+    if asbool(static_files):
+        # Serve static files
+        static_app = StaticURLParser(config['pylons.paths']['static_files'])
+        app = Cascade([static_app, app])
+
+    return app

commentonit/config/routing.py

+"""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'])
+    map.minimization = False
+
+    # 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}', controller='error')
+    map.connect('/error/{action}/{id}', controller='error')
+
+    # CUSTOM ROUTES HERE
+
+    map.connect('/{controller}/{action}')
+    map.connect('/{controller}/{action}/{id}')
+
+    return map

commentonit/controllers/__init__.py

Empty file added.

commentonit/controllers/error.py

+import cgi
+
+from paste.urlparser import PkgResourcesParser
+from pylons import request
+from pylons.controllers.util import forward
+from pylons.middleware import error_document_template
+from webhelpers.html.builder import literal
+
+from commentonit.lib.base import BaseController
+
+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"""
+        resp = request.environ.get('pylons.original_response')
+        content = literal(resp.body) or cgi.escape(request.GET.get('message', ''))
+        page = error_document_template % \
+            dict(prefix=request.environ.get('SCRIPT_NAME', ''),
+                 code=cgi.escape(request.GET.get('code', str(resp.status_int))),
+                 message=content)
+        return page
+
+    def img(self, id):
+        """Serve Pylons' stock images"""
+        return self._serve_file('/'.join(['media/img', id]))
+
+    def style(self, id):
+        """Serve Pylons' stock stylesheets"""
+        return self._serve_file('/'.join(['media/style', id]))
+
+    def _serve_file(self, path):
+        """Call Paste's FileApp (a WSGI application) to serve the file
+        at the specified path
+        """
+        request.environ['PATH_INFO'] = '/%s' % path
+        return forward(PkgResourcesParser('pylons', 'pylons'))

commentonit/lib/__init__.py

Empty file added.

commentonit/lib/app_globals.py

+"""The application's Globals object"""
+
+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
+        'app_globals' variable
+
+        """

commentonit/lib/base.py

+"""The base Controller API
+
+Provides the BaseController class for subclassing.
+"""
+from pylons.controllers import WSGIController
+from pylons.templating import render_genshi as render
+
+from commentonit.model import meta
+
+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']
+        try:
+            return WSGIController.__call__(self, environ, start_response)
+        finally:
+            meta.Session.remove()

commentonit/lib/helpers.py

+"""Helper functions
+
+Consists of functions to typically be used within templates, but also
+available to Controllers. This module is available to templates as 'h'.
+"""
+# Import helpers as desired, or define your own, ie:
+#from webhelpers.html.tags import checkbox, password

commentonit/model/__init__.py

+"""The application's model objects"""
+import sqlalchemy as sa
+from sqlalchemy import orm
+
+from commentonit.model import meta
+
+def init_model(engine):
+    """Call me before using any of the tables or classes in the model"""
+    ## Reflected tables must be defined and mapped here
+    #global reflected_table
+    #reflected_table = sa.Table("Reflected", meta.metadata, autoload=True,
+    #                           autoload_with=engine)
+    #orm.mapper(Reflected, reflected_table)
+    #
+    meta.Session.configure(bind=engine)
+    meta.engine = engine
+
+
+## Non-reflected tables may be defined and mapped at module level
+#foo_table = sa.Table("Foo", meta.metadata,
+#    sa.Column("id", sa.types.Integer, primary_key=True),
+#    sa.Column("bar", sa.types.String(255), nullable=False),
+#    )
+#
+#class Foo(object):
+#    pass
+#
+#orm.mapper(Foo, foo_table)
+
+
+## Classes for reflected tables may be defined here, but the table and
+## mapping itself must be done in the init_model function
+#reflected_table = None
+#
+#class Reflected(object):
+#    pass

commentonit/model/meta.py

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

commentonit/templates/__init__.py

Empty file added.

commentonit/tests/__init__.py

+"""Pylons application test package
+
+This package assumes the Pylons environment is already loaded, such as
+when this script is imported from the `nosetests --with-pylons=test.ini`
+command.
+
+This module initializes the application via ``websetup`` (`paster
+setup-app`) and provides the base testing objects.
+"""
+from unittest import TestCase
+
+from paste.deploy import loadapp
+from paste.script.appinstall import SetupCommand
+from pylons import config, url
+from routes.util import URLGenerator
+from webtest import TestApp
+
+import pylons.test
+
+__all__ = ['environ', 'url', 'TestController']
+
+# Invoke websetup with the current config file
+SetupCommand('setup-app').run([config['__file__']])
+
+environ = {}
+
+class TestController(TestCase):
+
+    def __init__(self, *args, **kwargs):
+        if pylons.test.pylonsapp:
+            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)

commentonit/tests/functional/__init__.py

Empty file added.

commentonit/websetup.py

+"""Setup the commentonit application"""
+import logging
+
+from commentonit.config.environment import load_environment
+from commentonit.model import meta
+
+log = logging.getLogger(__name__)
+
+def setup_app(command, conf, vars):
+    """Place any commands to setup commentonit here"""
+    load_environment(conf.global_conf, conf.local_conf)
+
+    # Create the tables if they don't already exist
+    meta.metadata.create_all(bind=meta.engine)
+[egg_info]
+tag_build = dev
+tag_svn_revision = true
+
+[easy_install]
+find_links = http://www.pylonshq.com/download/
+
+[nosetests]
+with-pylons = test.ini
+
+# Babel configuration
+[compile_catalog]
+domain = commentonit
+directory = commentonit/i18n
+statistics = true
+
+[extract_messages]
+add_comments = TRANSLATORS:
+output_file = commentonit/i18n/commentonit.pot
+width = 80
+
+[init_catalog]
+domain = commentonit
+input_file = commentonit/i18n/commentonit.pot
+output_dir = commentonit/i18n
+
+[update_catalog]
+domain = commentonit
+input_file = commentonit/i18n/commentonit.pot
+output_dir = commentonit/i18n
+previous = true
+from setuptools import setup, find_packages
+
+setup(
+    name='commentonit',
+    version='0.1',
+    description='',
+    author='',
+    author_email='',
+    url='',
+    install_requires=[
+        "Pylons>=0.9.7",
+        "SQLAlchemy>=0.5",
+        "Genshi>=0.4",
+    ],
+    setup_requires=["PasteScript>=1.6.3"],
+    packages=find_packages(exclude=['ez_setup']),
+    include_package_data=True,
+    test_suite='nose.collector',
+    package_data={'commentonit': ['i18n/*/LC_MESSAGES/*.mo']},
+    #message_extractors={'commentonit': [
+    #        ('**.py', 'python', None),
+    #        ('public/**', 'ignore', None)]},
+    zip_safe=False,
+    paster_plugins=['PasteScript', 'Pylons'],
+    entry_points="""
+    [paste.app_factory]
+    main = commentonit.config.middleware:make_app
+
+    [paste.app_install]
+    main = pylons.util:PylonsInstaller
+    """,
+)
+#
+# commentonit - 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 = 127.0.0.1
+port = 5000
+
+[app:main]
+use = config:development.ini
+
+# Add additional test specific configuration options as necessary.