Esempio n. 1
0
# -*- coding: utf-8 -*-
from pylon.frame import App, request
from rule_console.settings import MONGO_CONFIG


app = App(__name__)
app.config['mongodb_conf'] = MONGO_CONFIG
Esempio n. 2
0
 def __init__(self, app_name):
     self.app_name = app_name
     self.app = App(app_name)
Esempio n. 3
0
# -*- coding: utf-8 -*-
from pylon.frame import App, request, session


app = App(__name__)
app.secret_key = 'why would I tell you my secret key?'
Esempio n. 4
0
class Barracks(object):

    """Barracks application class.
    """
    BLUEPRINTNAME_FORMAT = '{0}{1}'

    URL_PREFIX = '/barracks'

    def __init__(self, app_name):
        self.app_name = app_name
        self.app = App(app_name)

    def init_conf(self, app_conf, model_list, debug=False):
        self.app_conf = app_conf
        self.postprocessors = app_conf.get('postprocessors', {})
        self.preprocessors = app_conf.get('preprocessors', {})
        for method in ('GET_MANY', ):
            self.postprocessors.setdefault(
                method, []).insert(0, self._add_filters)

        self.manager = manager.RESTManager(self.app)
        for model_class in model_list:
            postprocessors = getattr(model_class, 'postprocessors', {})
            preprocessors = getattr(model_class, 'preprocessors', {})
            # model level preprocessors will be applied after app level
            if isinstance(preprocessors, dict):
                for method, processors in self.preprocessors.iteritems():
                    preprocessors.setdefault(method, [])
                    preprocessors[method].extend(processors)
            # model level postprocessors will be applied before app level
            if isinstance(postprocessors, dict):
                for method, processors in self.postprocessors.iteritems():
                    postprocessors.setdefault(method, [])
                    postprocessors[method].extend(processors)
            # TODO: allow custom data validate and expose validation exception
            # to flask-restless, see http://goo.gl/4UajA8
            self.manager.create_api(
                model_class, methods=ADMIN_METHODS,
                allow_patch_many=app_conf.get('allow_patch_many', True),
                allow_delete_many=app_conf.get('allow_delete_many', True),
                preprocessors=preprocessors,
                postprocessors=postprocessors, url_prefix=Barracks.URL_PREFIX)
        self.DEBUG = debug

    def _add_filters(self, result=None, search_params=None, model=None):
        assert result['status'] == RespCode.OK
        # TODO: parse conf and add filters here
        filters_conf = getattr(model, '__filters__', {})

        multi_list = []
        cascade_dict = {}

        multi_conf_list = filters_conf.get('multi')
        cascade_conf_dict = filters_conf.get('cascade')

        if multi_conf_list is not None:
            # create multi filters list
            for filter_name in multi_conf_list:
                distinct_items = distinct_field(model, filter_name)
                multi_list.append({
                    'name': filter_name,
                    'items': sorted([
                        {
                            'value': v[0],
                            'display_value': v[0]
                        } for v in distinct_items],
                        key=lambda x: x['display_value'])
                })

        filters = {}
        if len(multi_list) > 0:
            filters.update({'multi': multi_list})
        if len(cascade_dict) > 0:
            filters.update({'cascade': cascade_dict})

        result['data']['filters'] = filters

    def run(self, host=DEFAULT_HTTP_HOST, port=DEFAULT_HTTP_PORT):
        self.app.run(host=host, port=port,
                     processes=DEFAULT_PROCESS_NUM,
                     debug=self.DEBUG)

    def _next_blueprint_name(self, basename):
        """Returns the next name for a blueprint with the specified base name.

        For example, if `basename` is ``'personapi'`` and blueprints already
        exist with names ``'personapi0'``, ``'personapi1'``, and
        ``'personapi2'``, then this function would return ``'personapi3'``.

        """
        # blueprints is a dict whose keys are the names of the blueprints
        blueprints = self.app.blueprints
        existing = [name for name in blueprints if name.startswith(basename)]
        # if this is the first one...
        if not existing:
            next_number = 0
        else:
            # for brevity
            b = basename
            existing_numbers = [int(n.partition(b)[-1]) for n in existing]
            next_number = max(existing_numbers) + 1
        return Barracks.BLUEPRINTNAME_FORMAT.format(basename, next_number)

    def create_api(self, api_path, methods, view_func):
        """This function used to add extend api for multalisk application
        `api_path`: the new api path without the part of api prefix
        `methods`: the http function supported by the new api, must be list
        `view_func`: the view function of the new api
        """
        # create new blueprint with different name from exists
        api_name = api_path.split('/')[-1]
        blueprintname = self._next_blueprint_name(api_name)
        blueprint = Blueprint(blueprintname,
                              self.app_name,
                              url_prefix=Barracks.URL_PREFIX)
        # add url rule to blueprint
        api_endpoint = (api_path if api_path.startswith('/') else
                        '/{0}'.format(api_path))
        api_methods = frozenset(methods)
        blueprint.add_url_rule(api_endpoint,
                               methods=api_methods,
                               view_func=view_func)
        self.app.register_blueprint(blueprint)

    def _search_data(self, model_class, search_filter):
        search_filter = SearchParams.inspect_filter(search_filter)
        if search_filter is None:
            msg = 'search_filter[%s] invalid!' % search_filter
            _LOGGER.warn(msg)
            raise Exception(msg)

        search_params = SearchParams.from_dictionary(search_filter)
        query = search(model_class, search_params)

        return query


    def get_data(self, model_class, search_filter):
        query = self._search_data(model_class, search_filter)
        db_type = getattr(model_class, '__db_type__', 'sqlorm')
        if db_type == 'sqlorm':
            objects = [inst_to_dict(model_class, x) for x in query]
        else:
            objects = [x for x in query]

        return objects

    def add_data(self, model_class, data_obj):
        """add new data to database, `data_obj` must be a json object
        """
        if type(data_obj) is not dict:
            raise Exception('data_obj is not dict!')

        session = getattr(model_class, '__session__')
        db_type = getattr(model_class, '__db_type__', 'sqlorm')

        if db_type == 'sqlorm':
            instance = dict_to_inst(model_class, data_obj)
            session.begin()
            session.add(instance)
            session.commit()
        else:
            pass

    def del_data(self, model_class, search_filter):
        query = self._search_data(model_class, search_filter)
        session = getattr(model_class, '__session__')
        db_type = getattr(model_class, '__db_type__', 'sqlorm')
        if db_type == 'sqlorm':
            try:
                session.begin()
                query.delete(synchronize_session=False)
                session.commit()
            except sqlalchemy.exc.IntegrityError as exception:
                _LOGGER.warn('ORM IntergirtError:%s' % exception)
                
        else:
            pass

    def mod_data(self, model_class, search_filter, data_obj):
        # validate data_obj
        if type(data_obj) is not dict:
            raise Exception('data_obj is not dict!')
        for field in data_obj:
            if not has_field(model_class, field):
                msg = "Model does not have field '{0}'".format(field)
                raise Exception(msg)

        session = getattr(model_class, '__session__')
        db_type = getattr(model_class, '__db_type__', 'sqlorm')

        # create query from query string
        query = self._search_data(model_class, search_filter)

        if db_type == 'sqlorm':
            relations = update_relations(model_class, query, data_obj)
            field_list = frozenset(data_obj) ^ relations
            data = dict((field, data_obj[field]) for field in field_list)

            # Special case: if there are any dates, convert the string form of the
            # date into an instance of the Python ``datetime`` object.
            data = strings_to_dates(model_class, data)

            try:
                # Let's update all instances present in the query
                num_modified = 0
                session.begin()
                if data:
                    for item in query.all():
                        for field, value in data.items():
                            setattr(item, field, value)
                        num_modified += 1
                session.commit()
            except Exception as exception:
                _LOGGER.exception(str(exception))
        else:
            pass