Merge pull request #27 from scragg0x/hooks

Hooks
This commit is contained in:
Matthew Scragg 2014-10-09 10:45:16 -05:00
commit 992cfb96d2
7 changed files with 74 additions and 6 deletions

View file

@ -1,6 +1,5 @@
language: python language: python
python: python:
- "2.6"
- "2.7" - "2.7"
before_install: before_install:

View file

@ -1 +1 @@
0.3.0 0.3.1

View file

@ -20,12 +20,13 @@ import click
from flask import Flask, request, render_template, url_for, redirect, g from flask import Flask, request, render_template, url_for, redirect, g
from flask.ext.cache import Cache from flask.ext.cache import Cache
from flask.ext.login import LoginManager, current_user from flask.ext.login import LoginManager, current_user
from flask.ext.sqlalchemy import SQLAlchemy from flask.ext.sqlalchemy import SQLAlchemy, declarative_base, Model, _QueryProperty
from flask.ext.assets import Environment, Bundle from flask.ext.assets import Environment, Bundle
from werkzeug.routing import BaseConverter from werkzeug.routing import BaseConverter
from werkzeug.exceptions import HTTPException from werkzeug.exceptions import HTTPException
from realms.lib.util import to_canonical, remove_ext, mkdir_safe, gravatar_url, to_dict from realms.lib.util import to_canonical, remove_ext, mkdir_safe, gravatar_url, to_dict
from realms.lib.hook import HookModelMeta
class Application(Flask): class Application(Flask):
@ -55,6 +56,7 @@ class Application(Flask):
'commands', 'commands',
'models', 'models',
'views', 'views',
'hooks'
) )
start_time = time.time() start_time = time.time()
@ -88,6 +90,16 @@ class Application(Flask):
return super(Application, self).make_response(tuple(rv)) return super(Application, self).make_response(tuple(rv))
class MySQLAlchemy(SQLAlchemy):
def make_declarative_base(self):
"""Creates the declarative base."""
base = declarative_base(cls=Model, name='Model',
metaclass=HookModelMeta)
base.query = _QueryProperty(self)
return base
class Assets(Environment): class Assets(Environment):
default_filters = {'js': 'rjsmin', 'css': 'cleancss'} default_filters = {'js': 'rjsmin', 'css': 'cleancss'}
default_output = {'js': 'assets/%(version)s.js', 'css': 'assets/%(version)s.css'} default_output = {'js': 'assets/%(version)s.js', 'css': 'assets/%(version)s.css'}
@ -181,7 +193,7 @@ def cli():
login_manager = LoginManager(app) login_manager = LoginManager(app)
login_manager.login_view = 'auth.login' login_manager.login_view = 'auth.login'
db = SQLAlchemy(app) db = MySQLAlchemy(app)
cache = Cache(app) cache = Cache(app)
assets = Assets(app) assets = Assets(app)

57
realms/lib/hook.py Normal file
View file

@ -0,0 +1,57 @@
from flask.ext.sqlalchemy import DeclarativeMeta
from functools import wraps
def hook_func(name, fn):
@wraps(fn)
def wrapper(self, *args, **kwargs):
for hook, a, kw in self.__class__._pre_hooks.get(name) or []:
hook(*a, **kw)
rv = fn(self, *args, **kwargs)
for hook, a, kw in self.__class__._post_hooks.get(name) or []:
hook(*a, **kw)
return rv
return wrapper
class HookMixinMeta(type):
def __new__(cls, name, bases, attrs):
super_new = super(HookMixinMeta, cls).__new__
for key, value in attrs.items():
if callable(value):
attrs[key] = hook_func(key, value)
return super_new(cls, name, bases, attrs)
class HookMixin(object):
__metaclass__ = HookMixinMeta
_pre_hooks = {}
_post_hooks = {}
@classmethod
def after(cls, method_name):
def outer(f, *args, **kwargs):
cls._post_hooks.setdefault(method_name, []).append((f, args, kwargs))
return f
return outer
@classmethod
def before(cls, method_name):
def outer(f, *args, **kwargs):
cls._pre_hooks.setdefault(method_name, []).append((f, args, kwargs))
return f
return outer
class HookModelMeta(DeclarativeMeta, HookMixinMeta):
pass

View file

@ -44,7 +44,6 @@ class Model(db.Model):
>>> {u'email': u'john@localhost', u'posts': [{u'id': 1, u'title': u'My First Post'}], u'name': u'John', u'id': 1} >>> {u'email': u'john@localhost', u'posts': [{u'id': 1, u'title': u'My First Post'}], u'name': u'John', u'id': 1}
""" """
__abstract__ = True __abstract__ = True
# Stores changes made to this model's attributes. Can be retrieved # Stores changes made to this model's attributes. Can be retrieved
# with model.changes # with model.changes
_changes = {} _changes = {}

View file

View file

@ -10,9 +10,10 @@ from dulwich.repo import NotGitRepository
from werkzeug.utils import escape, unescape from werkzeug.utils import escape, unescape
from realms.lib.util import to_canonical from realms.lib.util import to_canonical
from realms import cache from realms import cache
from realms.lib.hook import HookMixin
class Wiki(): class Wiki(HookMixin):
path = None path = None
base_path = '/' base_path = '/'
default_ref = 'master' default_ref = 'master'