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
python:
- "2.6"
- "2.7"
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.ext.cache import Cache
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 werkzeug.routing import BaseConverter
from werkzeug.exceptions import HTTPException
from realms.lib.util import to_canonical, remove_ext, mkdir_safe, gravatar_url, to_dict
from realms.lib.hook import HookModelMeta
class Application(Flask):
@ -55,6 +56,7 @@ class Application(Flask):
'commands',
'models',
'views',
'hooks'
)
start_time = time.time()
@ -88,6 +90,16 @@ class Application(Flask):
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):
default_filters = {'js': 'rjsmin', 'css': 'cleancss'}
default_output = {'js': 'assets/%(version)s.js', 'css': 'assets/%(version)s.css'}
@ -181,7 +193,7 @@ def cli():
login_manager = LoginManager(app)
login_manager.login_view = 'auth.login'
db = SQLAlchemy(app)
db = MySQLAlchemy(app)
cache = Cache(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}
"""
__abstract__ = True
# Stores changes made to this model's attributes. Can be retrieved
# with model.changes
_changes = {}

View file

View file

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