diff --git a/development.ini b/development.ini index c233af4..3bd319d 100644 --- a/development.ini +++ b/development.ini @@ -33,6 +33,8 @@ beaker.session.secret = somesecret # execute malicious code after an exception is raised. #set debug = false +sqlalchemy.url = sqlite:///%(here)s/gvaweb.sqlite + # Logging configuration [loggers] diff --git a/gnuviechadminweb/config/environment.py b/gnuviechadminweb/config/environment.py index 86ba83c..e9e44a2 100644 --- a/gnuviechadminweb/config/environment.py +++ b/gnuviechadminweb/config/environment.py @@ -7,6 +7,9 @@ import gnuviechadminweb.lib.app_globals as app_globals import gnuviechadminweb.lib.helpers from gnuviechadminweb.config.routing import make_map +from sqlalchemy import engine_from_config +from gnuviechadminweb.model import init_model + def load_environment(global_conf, app_conf): """Configure the Pylons environment via the ``pylons.config`` object @@ -31,3 +34,5 @@ def load_environment(global_conf, app_conf): # CONFIGURATION OPTIONS HERE (note: all config options will override # any Pylons config options) + engine = engine_from_config(config, 'sqlalchemy.') + init_model(engine) diff --git a/gnuviechadminweb/controllers/gva.py b/gnuviechadminweb/controllers/gva.py index 0b5e2d7..f31d46f 100644 --- a/gnuviechadminweb/controllers/gva.py +++ b/gnuviechadminweb/controllers/gva.py @@ -6,7 +6,6 @@ from gnuviechadminweb.lib.base import * log = logging.getLogger(__name__) class GvaController(BaseController): - def index(self): # Return a rendered template return render('/main.mako') diff --git a/gnuviechadminweb/lib/base.py b/gnuviechadminweb/lib/base.py index 509d315..8b3b5bc 100644 --- a/gnuviechadminweb/lib/base.py +++ b/gnuviechadminweb/lib/base.py @@ -12,15 +12,24 @@ from pylons.templating import render import gnuviechadminweb.lib.helpers as h import gnuviechadminweb.model as model +from gnuviechadminweb.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'] - return WSGIController.__call__(self, environ, start_response) + conn = meta.engine.connect() + meta.Session.configure(bind=conn) + c.menu = model.Menu.allowed(session['user'] if 'user' in session \ + else None) + try: + # WSGIController.__call__ dispatches to the Controller method + # the request is routed to. This routing information is + # available in environ['pylons.routes_dict'] + 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('_') \ diff --git a/gnuviechadminweb/lib/helpers.py b/gnuviechadminweb/lib/helpers.py index 0eb7c8f..7fd55e9 100644 --- a/gnuviechadminweb/lib/helpers.py +++ b/gnuviechadminweb/lib/helpers.py @@ -4,3 +4,11 @@ Consists of functions to typically be used within templates, but also available to Controllers. This module is available to both as 'h'. """ from webhelpers import * + +def cssclasses(menuitem): + cssclassnames=['menuitem'] + return " ".join(cssclassnames) + +def menulink(menuitem): + return link_to(menuitem.title, url(controller=menuitem.controller, + action=menuitem.action)) diff --git a/gnuviechadminweb/model/__init__.py b/gnuviechadminweb/model/__init__.py index e69de29..9ec32d0 100644 --- a/gnuviechadminweb/model/__init__.py +++ b/gnuviechadminweb/model/__init__.py @@ -0,0 +1,15 @@ +import sqlalchemy as sa +from sqlalchemy import orm + +from gnuviechadminweb.model import meta + +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) + +from gnuviechadminweb.model import menu +from gnuviechadminweb.model.menu import Menu, User, Role diff --git a/gnuviechadminweb/model/menu.py b/gnuviechadminweb/model/menu.py new file mode 100644 index 0000000..f39ac5e --- /dev/null +++ b/gnuviechadminweb/model/menu.py @@ -0,0 +1,64 @@ +# -*- python -*- +# -*- coding: utf-8 -*- +import sqlalchemy as sa +from sqlalchemy import orm + +from gnuviechadminweb.model import meta + +t_menu = \ + sa.Table("menu", meta.metadata, + sa.Column("id", sa.types.Integer, primary_key=True), + sa.Column("title", sa.types.String(40), nullable=False), + sa.Column("controller", sa.types.String(40), nullable=False), + sa.Column("action", sa.types.String(40), nullable=False) + ) + +t_user = \ + sa.Table("user", meta.metadata, + sa.Column("id", sa.types.Integer, primary_key=True), + sa.Column("name", sa.types.String(40), nullable=False), + sa.Column("password", sa.types.String(128), nullable=False) + ) + +t_role = \ + sa.Table("role", meta.metadata, + sa.Column("id", sa.types.Integer, primary_key=True), + sa.Column("name", sa.types.String(40), nullable=False) + ) + +t_menu_role = \ + sa.Table("menu_role", meta.metadata, + sa.Column("id", sa.types.Integer, primary_key=True), + sa.Column("menu_id", sa.types.Integer, sa.ForeignKey(t_menu.c.id)), + sa.Column("role_id", sa.types.Integer, sa.ForeignKey(t_role.c.id)) + ) + +t_user_role = \ + sa.Table("user_role", meta.metadata, + sa.Column("id", sa.types.Integer, primary_key=True), + sa.Column("user_id", sa.types.Integer, sa.ForeignKey(t_user.c.id)), + sa.Column("role_id", sa.types.Integer, sa.ForeignKey(t_role.c.id)) + ) + +class Menu(object): + @classmethod + def allowed(cls, user=None): + menu_q = meta.Session.query(cls) + return menu_q.all() + +class User(object): + pass + +class Role(object): + pass + +orm.mapper(Menu, t_menu, { + 'roles' : orm.relation(Role, secondary = t_menu_role), + }) +orm.mapper(Role, t_role, properties = { + 'users' : orm.relation(User, secondary = t_user_role), + 'menus' : orm.relation(Menu, secondary = t_menu_role), + }) +orm.mapper(User, t_role, properties = { + 'roles' : orm.relation(User, secondary = t_user_role) + }) diff --git a/gnuviechadminweb/model/meta.py b/gnuviechadminweb/model/meta.py new file mode 100644 index 0000000..578584a --- /dev/null +++ b/gnuviechadminweb/model/meta.py @@ -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() diff --git a/gnuviechadminweb/websetup.py b/gnuviechadminweb/websetup.py index 0748af1..db29ed2 100644 --- a/gnuviechadminweb/websetup.py +++ b/gnuviechadminweb/websetup.py @@ -5,6 +5,7 @@ from paste.deploy import appconfig from pylons import config from gnuviechadminweb.config.environment import load_environment +from gnuviechadminweb.model import meta log = logging.getLogger(__name__) @@ -12,3 +13,6 @@ def setup_config(command, filename, section, vars): """Place any commands to setup gnuviechadminweb here""" conf = appconfig('config:' + filename) load_environment(conf.global_conf, conf.local_conf) + log.info("Creating tables") + meta.metadata.create_all(bind=meta.engine) + log.info("Successfully setup")