Example #1
0
File: api.py Project: krectra/lark
# Lazily register oauth, redis
def init_blueprint(state):
    oauth.init_app(state.app)
    redis.init_app(state.app)
    db.init_app(state.app)
    bind_models(oauth,
                user=User,
                token=Token,
                client=Client,
                grant=Grant,
                current_user=current_user)


lark_admin_api = Blueprint('lark_admin_api', __name__)
lark_admin_api.record(init_blueprint)


def api_func(func, oauth_obj, schema=None, *args, **kwargs):
    status_code = 200
    try:
        try:
            request_json = request.get_json()
        except:
            request_json = None

        if schema:
            schema_inst = schema()
            data = schema_inst.serialize(request_json)
        else:
            data = request_json
Example #2
0
def record_bcrypt(state):
    if (getattr(Bcrypt, 'is_fallback_bcrypt', None) is True and
            not state.app.config.get('FOODTRUCK_CMDLINE_MODE', False)):
        raise Exception(
                "You're running FoodTruck outside of `chef`, and will need to "
                "install Flask-Bcrypt to get more proper security.")


# Create the FoodTruck blueprint.
foodtruck_bp = Blueprint(
        'FoodTruck', __name__,
        template_folder='templates',
        static_folder='static')

foodtruck_bp.record(record_login_manager)
foodtruck_bp.record(record_bcrypt)


def after_this_request(f):
    if not hasattr(g, 'after_request_callbacks'):
        g.after_request_callbacks = []
    g.after_request_callbacks.append(f)
    return f


class LazySomething(object):
    def __init__(self, factory):
        self._factory = factory
        self._something = None
Example #3
0
                                   
@mod.route('/create-profile', methods=['GET', 'POST'])
def create_profile():
    if current_user.is_authenticated() or 'openid' not in session:
        return redirect(url_for('account.profile'))
        
    if request.method == 'POST':
        username = request.form['username']
        name = request.form['name']
        email = request.form['email']
        if not username:
            flash(u'Error: you have to provide a username')
        elif '@' not in email:
            flash(u'Error: you have to enter a valid email address')
        else:
            user = current_app.security.datastore.create_user(username=username, email=email, nickname=name, password='******', openid=session['openid'], active=True)
            user_registered.send(user, app=current_app._get_current_object())
            flash(u'Profile successfully created')
            return redirect(openid.views.oid.get_next_url())
            
    return render_template('create_profile.html', next_url=openid.views.oid.get_next_url())


@mod.route('/profile')
@login_required
def profile():
    return render_template('profile.html', content='Profile');


mod.record(init_blueprint)
Example #4
0
import pathlib
import pymongo
from pymongo.errors import ServerSelectionTimeoutError
from flask import Response, request, jsonify, Blueprint, send_from_directory

from appchen.server_send_events import server
from appchen.server_send_events.routes import route

db: pymongo.mongo_client.database.Database
static_folder = pathlib.Path(__file__).parent
app = Blueprint('weblet',
                __name__,
                static_folder=static_folder,
                static_url_path='')

app.record(
    lambda state: globals().setdefault('db', state.app.config.get('db', None)))


def import_weblets(src_dir: pathlib.Path):
    """Initializes the database."""
    logging.warning(f'Dropping weblets collection from database')
    collection: pymongo.collection.Collection = db.get_collection('weblets')
    collection.drop()
    logging.info(f'Importing weblets from {src_dir.resolve()}')
    weblets = src_dir.glob('*.js')
    for path in weblets:
        logging.info(f'Importing weblet {path}')
        weblet = dict(code=path.read_text(encoding='utf8'),
                      name=path.stem,
                      createAt=datetime.datetime.utcnow(),
                      createBy='importer')
Example #5
0
class Api(restful.Api):
    '''
    The main entry point for the application.
    You need to initialize it with a Flask Application: ::

    >>> app = Flask(__name__)
    >>> api = Api(app)

    Alternatively, you can use :meth:`init_app` to set the Flask application
    after it has been constructed.

    The endpoint parameter prefix all views and resources:

        - The API root/documentation will be ``{endpoint}.root``
        - A resource registered as 'resource' will be available as ``{endpoint}.resource``

    :param app: the Flask application object
    :type app: flask.Flask

    :param version: The API version (used in Swagger documentation)
    :type version: str

    :param title: The API title (used in Swagger documentation)
    :type title: str

    :param description: The API description (used in Swagger documentation)
    :type description: str

    :param terms_url: The API terms page URL (used in Swagger documentation)
    :type terms_url: str

    :param contact: A contact email for the API (used in Swagger documentation)
    :type contact: str

    :param license: The license associated to the API (used in Swagger documentation)
    :type license: str

    :param license_url: The license page URL (used in Swagger documentation)
    :type license_url: str

    :param endpoint: The API base endpoint (default to 'api).
    :type endpoint: str

    :param default: The default namespace base name (default to 'default')
    :type default: str

    :param default_label: The default namespace label (used in Swagger documentation)
    :type default_label: str

    :param prefix: Prefix all routes with a value, eg v1 or 2010-04-01
    :type prefix: str

    :param default_mediatype: The default media type to return
    :type default_mediatype: str

    :param decorators: Decorators to attach to every resource
    :type decorators: list

    :param catch_all_404s: Use :meth:`handle_error`
        to handle 404 errors throughout your app
    :param url_part_order: A string that controls the order that the pieces
        of the url are concatenated when the full url is constructed.  'b'
        is the blueprint (or blueprint registration) prefix, 'a' is the api
        prefix, and 'e' is the path component the endpoint is added with
    :type catch_all_404s: bool

    :param errors: A dictionary to define a custom response for each
        exception or error raised during a request
    :type errors: dict

    :param authorizations: A Swagger Authorizations declaration as dictionary
    :type authorizations: dict

    '''

    def __init__(self, app=None, version='1.0', title=None, description=None,
            terms_url=None, contact=None, license=None, license_url=None,
            endpoint='api', prefix=None, authorizations=None,
            default='default', default_label='Default namespace', **kwargs):
        self.version = version
        self.title = title
        self.description = description
        self.terms_url = terms_url
        self.contact = contact
        self.license = license
        self.license_url = license_url
        self.endpoint = endpoint
        self.authorizations = authorizations

        self.models = {}
        self.namespaces = []
        self.default_namespace = ApiNamespace(self, '', default_label,
            endpoint='{0}-declaration'.format(default),
            json_path='/{0}.json'.format(default)
        )

        self.blueprint = Blueprint(self.endpoint, __name__,
            template_folder='templates',
            static_folder='static',
            static_url_path='/swaggerui',
            url_prefix=prefix,
        )

        @self.blueprint.route('/images/throbber.gif')
        def fix_throbber():
            return redirect(url_for('.static'.format(self.endpoint),
                filename='bower/swagger-ui/dist/images/throbber.gif'
            ))

        self.blueprint.record(self._deferred_blueprint_init)

        super(Api, self).__init__(self.blueprint, **kwargs)

        view_func = self.output(ApiSpecs.as_view(str('specs'), api=self))
        url = self._complete_url('/specs.json', '')
        self.blueprint.add_url_rule(url, view_func=view_func)
        self.blueprint.add_url_rule('/', 'root', self.render_ui)
        self.blueprint.add_app_template_global(self.swagger_static)
        self.add_namespace(self.default_namespace)

        if app:
            app.register_blueprint(self.blueprint)

    def init_app(self, app, **kwargs):
        if isinstance(app, Blueprint):
            return
        self.title = kwargs.get('title', self.title)
        self.description = kwargs.get('description', self.description)
        self.terms_url = kwargs.get('terms_url', self.terms_url)
        self.contact = kwargs.get('contact', self.contact)
        self.license = kwargs.get('license', self.license)
        self.license_url = kwargs.get('license_url', self.license_url)

        app.register_blueprint(self.blueprint)

    def render_ui(self):
        '''Override this method to customize the documentation page'''
        return render_template('swagger-ui.html', api_endpoint=self.endpoint, specs_url=self.specs_url)

    def swagger_static(self, filename):
        return url_for(
            '{0}.static'.format(self.endpoint),
            filename='bower/swagger-ui/dist/{0}'.format(filename)
        )

    def _register_namespace(self, ns):
        '''Register a Swagger API declaration for a given API Namespace'''
        endpoint = str(ns.endpoint)
        view_func = self.output(ApiDeclaration.as_view(endpoint, api=self, namespace=ns))
        url = self._complete_url(ns.json_path, '')
        self.blueprint.add_url_rule(url, view_func=view_func)

    def _register_view(self, app, resource, *urls, **kwargs):
        super(Api, self)._register_view(app, resource, *urls, **kwargs)
        # Ugly fix on owned endpoints
        prefix = '{0}.'.format(self.blueprint.name)
        self.endpoints = set(e if e.startswith(prefix) else ''.join((prefix, e)) for e in self.endpoints)

    def add_resource(self, resource, *urls, **kwargs):
        '''Register a Swagger API declaration for a given API Namespace'''
        kwargs['endpoint'] = str(kwargs.pop('endpoint', None) or resource.__name__.lower())
        if not kwargs.pop('namespace', None):
            self.default_namespace.resources.append((resource, urls, kwargs))

        # If blueprint is already registered, force URL declaration
        if self.blueprint_setup:
            kwargs['endpoint'] = str('{0}.{1}'.format(self.blueprint.name, kwargs['endpoint']))
            self._register_view(self.blueprint_setup.app, resource, *urls, **kwargs)
        else:
            super(Api, self).add_resource(resource, *urls, **kwargs)

    def add_namespace(self, ns):
        if ns not in self.namespaces:
            view_func = self.output(ApiDeclaration.as_view(ns.endpoint, api=self, namespace=ns))
            url = self._complete_url(ns.json_path, '')
            self.namespaces.append(ns)
            self.endpoints.add(ns.endpoint)
            if self.blueprint_setup:
                # Set the rule to a string directly, as the blueprint is already set up.
                self.blueprint_setup.add_url_rule(url, view_func=view_func)
            else:
                self.blueprint.add_url_rule(url, view_func=view_func)

    def namespace(self, *args, **kwargs):
        ns = ApiNamespace(self, *args, **kwargs)
        self.add_namespace(ns)
        return ns

    def route(self, *urls, **kwargs):
        def wrapper(cls):
            doc = kwargs.pop('doc', None)
            if doc:
                self._handle_api_doc(cls, doc)
            self.add_resource(cls, *urls, **kwargs)
            return cls
        return wrapper

    def _handle_api_doc(self, cls, doc):
        unshortcut_params_description(doc)
        for key in 'get', 'post', 'put', 'delete':
            if key in doc:
                unshortcut_params_description(doc[key])
        cls.__apidoc__ = merge(getattr(cls, '__apidoc__', {}), doc)

    @property
    def specs_url(self):
        return url_for('{0}.specs'.format(self.endpoint), _external=True)

    @property
    def base_url(self):
        return url_for('{0}.root'.format(self.endpoint), _external=True)

    def doc(self, **kwargs):
        '''Add some api documentation to the decorated object'''
        def wrapper(documented):
            self._handle_api_doc(documented, kwargs)
            return documented
        return wrapper

    def owns_endpoint(self, endpoint):
        '''Override the default implementation as there is always a Blueprint'''
        return endpoint in self.endpoints

    def abort(self, code=500, message=None, **kwargs):
        '''Properly abort the current request'''
        if message or kwargs and 'status' not in kwargs:
            kwargs['status'] = code
        if message:
            kwargs['message'] = str(message)
        restful.abort(code, **kwargs)

    def model(self, name, model=None, fields=None, **kwargs):
        '''
        Register a model

        Model can be either a dictionnary or a fields.Raw subclass.
        '''
        if isinstance(model, dict):
            model = ApiModel(model)
            model.__apidoc__['name'] = name
            self.models[name] = model
            return model
        else:
            def wrapper(cls):
                cls.__apidoc__ = merge(getattr(cls, '__apidoc__', {}), kwargs)
                cls.__apidoc__['name'] = name
                if fields:
                    self.models[name] = fields
                return cls
            return wrapper

    def parser(self):
        '''Instanciate a RequestParser'''
        return restful.reqparse.RequestParser()

    def as_list(self, field):
        '''Allow to specify nested lists for documentation'''
        field.__apidoc__ = merge(getattr(field, '__apidoc__', {}), {'as_list': True})
        return field

    def marshal_with(self, fields, as_list=False):
        '''
        A decorator specifying the fields to use for serialization

        :param as_list: Indicate that the return type is a list (for the documentation)
        :type as_list: bool
        '''
        def wrapper(func):
            doc = {'model': [fields]} if as_list else {'model': fields}
            func.__apidoc__ = merge(getattr(func, '__apidoc__', {}), doc)
            return restful.marshal_with(fields)(func)
        return wrapper

    def marshal_list_with(self, fields):
        '''A shortcut decorator for ``marshal_with(as_list=True)``'''
        return self.marshal_with(fields, True)

    def marshal(self, data, fields):
        '''A shortcut to the ``marshal`` helper'''
        return restful.marshal(data, fields)
Example #6
0
        path = '/var/lib/arkos/genesis'
    if not os.path.exists(path):
        return
    backend.add_url_rule('/', defaults={'path': None}, view_func=genesis, 
        methods=['GET',])
    backend.add_url_rule('/<path:path>', view_func=genesis, methods=['GET',])
    for x in os.listdir(os.path.join(path, 'lib')):
        if os.path.islink(os.path.join(path, 'lib', x)):
            os.unlink(os.path.join(path, 'lib', x))
    libpaths = []
    for x in apps:
        genpath = "/var/lib/arkos/applications/%s/genesis" % x.id
        if os.path.exists(genpath):
            libpaths.append("lib/%s"%x.id)
            os.symlink(genpath, os.path.join(path, 'lib', x.id))
    if libpaths:
        with open(os.path.join(path, 'package.json'), 'r') as f:
            data = json.loads(f.read())
        data["ember-addon"] = {"paths": libpaths}
        with open(os.path.join(path, 'package.json'), 'w') as f:
            f.write(json.dumps(data, sort_keys=True, 
                indent=2, separators=(',', ': ')))
    mydir = os.getcwd()
    os.chdir(path)
    s = shell("ember build")
    os.chdir(mydir)
    if s["code"] != 0:
        raise Exception("Genesis rebuild process failed")

backend.record(genesis_init)
Example #7
0
        'Content-Disposition': 'attachment;filename=' + event_slug + '.ics'
    }


def record_state(state):
    """
    Record the application state when this blueprint is registered.
    Here we exact appropriate configuration values from the application
    config, if they're available, and use environment variables or
    defaults if not.
    """
    global EVENTICS_CONFIG
    app = state.app

    # For each of these values get the app config value. If it doesn't exist,
    # get an environment variable. If that doesn't exist, use the default.
    # This is a simple function to do that.
    get_config = lambda k: app.config.get(k, os.environ.get(k, EVENTICS_CONFIG[k]))

    for config_key in EVENTICS_CONFIG:
        EVENTICS_CONFIG[config_key] = get_config(config_key)

    # Set the route for generate_ics?
    eventics.route(EVENTICS_CONFIG['EVENT_ICS_URL'], methods=['GET'])(generate_ics)

# Weakness in Python decorators is that you can't mport and directly test the
# decorated functions, which is why this (and generate_ics) are
# undecorated.
eventics.record(record_state)

Example #8
0
        path = os.path.abspath(os.path.join(sdir, '../../genesis'))
    elif os.path.exists('/var/lib/arkos/genesis'):
        path = '/var/lib/arkos/genesis'
    if not os.path.exists(path):
        return
    backend.add_url_rule('/',
                         defaults={'path': None},
                         view_func=genesis,
                         methods=[
                             'GET',
                         ])
    backend.add_url_rule('/<path:path>', view_func=genesis, methods=[
        'GET',
    ])


def verify_genesis():
    if config.get("enviro", "run") == "vagrant":
        vpath = '/home/vagrant/genesis/dist'
    elif config.get("enviro", "run") == "dev":
        vpath = os.path.dirname(os.path.realpath(__file__))
        vpath = os.path.abspath(os.path.join(vpath, '../../genesis/dist'))
    else:
        vpath = '/var/lib/arkos/genesis'
    if not os.path.exists(vpath):
        return False
    return True


backend.record(genesis_init)
Example #9
0
from flask import Blueprint

from models.answer import AnswerModel
from views.LocationModelView import LocationModelView

answer_bp = Blueprint('/answers', __name__)
answer_bp.record(lambda _: register())


def register():
    AnswerList.register(answer_bp, '/answers/', '/answers/<int:_id>')


class AnswerList(LocationModelView):
    def __init__(self):
        super().__init__(AnswerModel)
        self.field_name = "answer"
Example #10
0
class ModelEditor(object):
    """Factory class for creating model editor views
    TODO: write documentation
    """
    def __init__(self, app=None, modeldb=None):
        self.bp = Blueprint('modeleditor',
                            __name__,
                            static_folder='static',
                            template_folder='templates')
        self.bp.record(self.onregister)
        self.bp.context_processor(self.context_processor)

        @self.bp.before_request
        def before_request():
            if not request.form:
                request.form = None

        @self.bp.app_template_global()
        def savemodelform(model):
            return forms.SaveModelForm(obj=model, prefix='savemodel')

        self.modeldb = modeldb or ModelDB()

        #set up the spec registry and add the defaults
        self.specregistry = OrderedDict()
        self.registerspectype(emissionspec.CombinedSpec,
                              forms.RadioactiveContamForm, "RadioactiveContam")
        self.registerspectype(emissionspec.RadonExposure,
                              forms.RadonExposureForm)
        self.registerspectype(emissionspec.CosmogenicActivation,
                              forms.CosmogenicActivationForm)
        #dust is not well developed yet...
        #self.registerspectype(emissionspec.DustAccumulation,
        #forms.DustAccumulationForm)

        #apply all our routes
        baseroute = '/edit/<modelid>'
        self.bp.add_url_rule('/new',
                             view_func=self.newmodel,
                             methods=('POST', ))
        self.bp.add_url_rule('/del',
                             view_func=self.delmodel,
                             methods=('POST', ))
        self.bp.add_url_rule(baseroute + '/',
                             view_func=self.editmodel,
                             methods=('GET', 'POST'))
        self.bp.add_url_rule(baseroute + '/save',
                             view_func=self.savemodel,
                             methods=('POST', ))
        self.bp.add_url_rule(baseroute + '/newcomponent',
                             view_func=self.newcomponent,
                             methods=('POST', ))
        self.bp.add_url_rule(baseroute + '/delcomponent/<componentid>',
                             view_func=self.delcomponent,
                             methods=('POST', ))
        self.bp.add_url_rule(baseroute + '/newplacement/<parentid>/<childid>',
                             view_func=self.newplacement,
                             methods=('POST', ))
        self.bp.add_url_rule(baseroute +
                             '/delplacement/<parentid>/<int:index>',
                             view_func=self.delplacement,
                             methods=('POST', ))
        self.bp.add_url_rule(baseroute + '/newspec',
                             view_func=self.newspec,
                             methods=('POST', ))
        self.bp.add_url_rule(baseroute + '/delspec/<specid>',
                             view_func=self.delspec,
                             methods=('POST', ))
        self.bp.add_url_rule(baseroute + '/attachspec/<compid>/<specid>',
                             view_func=self.attachspec,
                             methods=('POST', ))
        self.bp.add_url_rule(baseroute + '/detachspec/<compid>/<int:index>',
                             view_func=self.detachspec,
                             methods=('POSt', ))
        self.bp.add_url_rule(baseroute + '/setquerymod/<compid>/<specid>',
                             view_func=self.setquerymod,
                             methods=('POST', ))
        self.bp.add_url_rule(baseroute + '/editcomponent/<componentid>',
                             view_func=self.editcomponent,
                             methods=('GET', 'POST'))
        self.bp.add_url_rule(baseroute + '/editspec/<specid>',
                             view_func=self.editspec,
                             methods=('GET', 'POST'))
        self.bp.add_url_rule(baseroute + '/bindsimdata',
                             view_func=self.bindsimdata,
                             methods=('GET', 'POST'))

        @self.bp.route('/help')
        def help():
            return render_template('help.html')

        if app:
            self.init_app(app)

    def onregister(self, setupstate):
        #make sure bootstrap is registered
        if not 'bootstrap' in setupstate.app.blueprints:
            Bootstrap(setupstate.app)
        setupstate.app.jinja_env.globals['bootstrap_is_hidden_field'] = \
            is_hidden_field

        #initialize the modeldb
        #todo: make sure this only gets done once
        self.modeldb.init_app(setupstate.app)

        #update the spec form choices
        forms.BoundSpecForm.category.choices = [
            (val.cls, name) for name, val in self.specregistry.items()
        ]

    def init_app(self, app, url_prefix='/models'):
        app.register_blueprint(self.bp, url_prefix=url_prefix)

    def registerspectype(self, cls, form, name=None):
        """Register a new EmissionSpec class and form for editing
        Args:
            cls: class or constructor, should inherit from EmissionSpec
            form: WTForm for editing, should inherit from EmissionspecForm
            name (str): Name for this class, if None, use cls.__name__
        """
        name = name or cls.__name__
        self.specregistry[name] = SpecEntry(cls, form)

    def context_processor(self):
        """Register global variables available to templates"""
        return dict(spectypes=list(self.specregistry.keys()), forms=forms)

    def addlinks(self, form, modelid):
        """Replace names in subfield forms with links"""
        for field in form:
            if hasattr(field, 'entries'):
                for entry in field:
                    href = None
                    field = None
                    if entry.form_class is forms.PlacementForm:
                        href = url_for('.editcomponent',
                                       modelid=modelid,
                                       componentid=entry['component'].data)
                        field = 'cls'
                    elif entry.form_class is forms.BoundSpecForm:
                        href = url_for('.editspec',
                                       modelid=modelid,
                                       specid=entry['id'].data)
                        field = 'name'
                    if href:
                        entry[field].link = href
                        #entry[field].data = ("<a href='%s'>%s</a>"
                        #                      %(href, entry[field].data))

    ##### modeleditor API #######
    #todo: implement some caching here!
    def newmodel(self):
        """Create a new bare model or clone an existing one for editing"""
        name = ""
        simsdbview = None
        if request.form:
            name = request.form.get('name', name)
            simsdbview = request.form.get('backend', simsdbview)
        importfile = None
        if request.files:
            importfile = request.files.get('importmodel', importfile)

        if importfile:
            #try to convert file data
            try:
                filecontents = importfile.read()
                rawmodel = json.loads(filecontents.decode())
                newmodel = bgmodel.BgModel.buildfromdict(rawmodel)
            except BaseException as e:
                flash("Error raised parsing input file: '%s'" % e, "danger")
                return redirect(url_for('index'))
            if name:
                newmodel.name = name
            if simsdbview:
                newmodel.simsdb = simsdbview
            newid = self.modeldb.write_model(newmodel, temp=True)
        else:
            derivedFrom = request.values.get('derivedFrom', None)
            newmodel = self.modeldb.new_model(derivedFrom, name=name)
            newid = newmodel.id
        #todo: handle error no model returned, probably DB down
        return redirect(url_for('.editmodel', modelid=str(newid)))

    def delmodel(self):
        modelid = request.form.get('modelid', None)
        try:
            ndeleted = self.modeldb.del_model(modelid)
        except KeyError as e:
            abort(404, e)
        except ValueError as e:
            abort(403, e)

        if ndeleted == 1:
            flash("Successfully deleted model %s" % modelid, 'success')
        else:
            flash("An error occurred trying to delete this model", 'warning')
        return redirect(url_for('index'))

    #all endpoints build on the same route from here out
    def editmodel(self, modelid):
        """return a page with forms for model editing"""
        bypasscache = request.args.get('bypasscache', False)
        model = getmodelordie(modelid, toedit=True, bypasscache=bypasscache)
        return render_template('editmodel.html', model=model)

    def savemodel(self, modelid):
        """Save the model to the DB, making sure all edit details fields
        validated
        """
        model = getmodelordie(modelid, toedit=True)
        form = forms.SaveModelForm(request.form, obj=model, prefix='savemodel')
        if request.method == 'POST' and form.validate():
            form.populate_obj(model)
            # make sure the simulation data is updated
            simsdb = get_simsdb(model=model)
            error = ""
            if not simsdb:
                error += " No registered SimulationsDB"
            try:
                # temporarily force update always
                #update = form.updatesimdata.data
                update = True
                simsdb.updatesimdata(model,
                                     attach=True,
                                     findnewmatches=update,
                                     findnewdata=update)
            except units.errors.DimensionalityError as e:
                error += " Invalid unit settings: '%s'" % e
            # make sure the model is valid
            if error or not model.validate():
                flash("The model failed to validate: %s" % error, 'error')
                return url_for('.editmodel', modelid=modelid, bypasscache=True)
            self.modeldb.write_model(model, temp=False, bumpversion="major")
            flash("Model '%s' successfully saved" % (model.name), 'success')
            return redirect(url_for("index"))

        #we should only get here if the form failed...
        return redirect(url_for('.editmodel', modelid=modelid))

    #todo: implement delete functionality

    ###Component/spec editing API
    ###Actions are:
    # new component (child of X)
    # delete component
    # new placement
    # delete placement
    # new spec
    # delete spec
    # place spec
    # remove spec
    # edit query modifier
    # edit component (metadata, etc)

    def newcomponent(self, modelid):
        model = getmodelordie(modelid, toedit=True)
        clonefrom = request.values.get('clonefrom')
        if clonefrom:
            oldcomp = getcomponentordie(model, clonefrom)
            newcomp = oldcomp.clone()
        else:
            newcomp = (Assembly() if request.values.get('class') == 'Assembly'
                       else Component())
        parentid = request.values.get('parent')
        if parentid:
            parent = getcomponentordie(model, parentid)
            replace = int(request.values.get('replaceAt', -1))
            if replace >= 0 and replace < len(parent.components):
                placement = parent.components[replace]
                placement.component.placements.remove(placement)
                placement.component = newcomp
                newcomp.placements.add(placement)
            else:
                parent.addcomponent(newcomp)

        model.components[newcomp.id] = newcomp
        self.modeldb.write_model(model)
        return redirect(
            url_for('.editcomponent', modelid=modelid, componentid=newcomp.id))

    def delcomponent(self, modelid, componentid):
        model = getmodelordie(modelid, toedit=True)
        component = getcomponentordie(model, componentid)
        model.delcomponent(componentid)
        self.modeldb.write_model(model)
        return redirect(url_for('.editmodel', modelid=modelid))

    def newplacement(self, modelid, parentid, childid):
        model = getmodelordie(modelid, toedit=True)
        parent = getcomponentordie(model, parentid)
        child = getcomponentordie(model, childid)
        #we also call this for rearranging; if we're already a child, remove it
        if child in parent.getcomponents(deep=False, withweights=False):
            parent.delcomponent(child)
        number = request.values.get('number', 1)
        index = request.values.get('index')
        parent.addcomponent((child, number), index)
        self.modeldb.write_model(model)
        return redirect(
            url_for('.editcomponent', modelid=modelid, componentid=parentid))

    def delplacement(self, modelid, parentid, index):
        model = getmodelordie(modelid, toedit=True)
        parent = getcomponentordie(model, parentid)
        parent.delcomponent(index)
        self.modeldb.write_model(model)
        return redirect(
            url_for('.editcomponent', modelid=modelid, componentid=parentid))

    def newspec(self, modelid):
        model = getmodelordie(modelid, toedit=True)
        newspec = None
        clonefrom = request.values.get('clonefrom')
        if clonefrom:
            prior = getspecordie(model, clonefrom)
            newspec = prior.clone()
        else:
            spectype = request.values.get('type', 'RadioactiveContam')
            if spectype not in self.specregistry:
                abort(404, "Unknown EmissionSpec type ", spectype)
            newspec = self.specregistry[spectype].cls()

        model.specs[newspec.id] = newspec
        self.modeldb.write_model(model)
        return redirect(
            url_for('.editspec', modelid=modelid, specid=newspec.id))

    def delspec(self, modelid, specid):
        model = getmodelordie(modelid, toedit=True)
        spec = getspecordie(model, specid)
        model.delspec(specid)
        self.modeldb.write_model(model)
        return redirect(url_for('.editmodel', modelid=modelid))

    def attachspec(self, modelid, compid, specid):
        model = getmodelordie(modelid, toedit=True)
        comp = getcomponentordie(model, compid)
        spec = getspecordie(model, specid)
        index = request.values.get('index')
        comp.addspec(spec, index=index)
        self.modeldb.write_model(model)
        return redirect(
            url_for('.editcomponent', modelid=modelid, componentid=compid))

    def detachspec(self, modelid, compid, index):
        model = getmodelordie(modelid, toedit=True)
        comp = getcomponentordie(model, compid)
        comp.delspec(index)
        self.modeldb.write_model(model)
        return redirect(
            url_for('.editcomponent', modelid=modelid, componentid=compid))

    def setquerymod(self, modelid, compid, specid):
        model = getmodelordie(modelid, toedit=True)
        comp = getcomponentordie(model, compid)
        querymod = request.values.get('querymod')
        if querymod:
            if isinstance(querymod, str):
                querymod = json.loads(querymod)
                #todo: implement error handling here
            comp.querymods[specid] = querymod
        elif specid in comp.querymods:
            del comp.querymods[specid]

        self.modeldb.write_model(model)
        return redirect(
            url_for('.editcomponent', modelid=modelid, componentid=compid))

    def editcomponent(self, modelid, componentid):
        """return a page with forms for component editing"""
        #todo: do we need to pass different forms for component types here?
        model = getmodelordie(modelid, toedit=True)
        comp = getcomponentordie(model, componentid)
        form = forms.get_form(request.form, comp)
        if request.method == 'POST':
            if form.validate():
                form.populate_obj(comp)
                #make sure the fully assembled object works
                for bs in comp.specs:
                    bs.spec = model.specs.get(bs.spec, bs.spec)
                if hasattr(comp, 'components'):
                    for plc in comp.components:
                        sub = plc.component
                        plc.component = model.components.get(sub, sub)

                status = comp.getstatus()
                if not status:
                    #no errors, so save
                    # sim data associations almost all get out of whack when
                    # anything is changed, so take the heavy-handed method of
                    # deleting all
                    for match in model.getsimdata(rootcomponent=comp):
                        del model.simdata[match.id]
                    self.modeldb.write_model(model)
                    flash(
                        "Changes to component '%s' successfully saved" %
                        comp.name, 'success')
                    return redirect(
                        url_for('.editcomponent',
                                modelid=modelid,
                                componentid=componentid))
                else:
                    flash(
                        "Form validation failed. Correct errors and resubmit",
                        "danger")
                    form.specs.errors.append(status)
            else:
                flash("Form validation failed. Correct errors and resubmit",
                      "danger")

        self.addlinks(form, modelid)
        return render_template('editmodel.html',
                               model=model,
                               editcomponent=comp,
                               form=form)

    def editspec(self, modelid, specid):
        """return a page with forms for componentspec editing"""
        model = getmodelordie(modelid, toedit=True)
        spec = getspecordie(model, specid)
        #find the correct form
        possibleforms = [
            entry.form for entry in self.specregistry.values()
            if entry.cls == type(spec)
        ]
        if len(possibleforms) < 1:
            abort(404, "No form defined for class %s", type(spec).__name__)
        form = possibleforms[0](request.form, obj=spec)
        if request.method == 'POST':
            if form.validate():
                form.populate_obj(spec)
                #make sure the fully assembled spec works
                status = spec.getstatus()
                if not status:
                    #no errors, so save
                    # sim data associations almost all get out of whack when
                    # anything is changed, so take the heavy-handed method of
                    # deleting all
                    for match in model.getsimdata(rootspec=spec):
                        del model.simdata[match.id]
                    self.modeldb.write_model(model)
                    flash(
                        "Changes to spec '%s' successfully saved" % spec.name,
                        'success')
                    return redirect(
                        url_for('.editspec', modelid=modelid, specid=specid))
                else:
                    flash(
                        "Form validation failed. Correct errors and resubmit",
                        "danger")
                    form.normfunc.errors.append(status)
            else:
                flash("Form validation failed. Correct errors and resubmit",
                      "danger")
        self.addlinks(form, modelid)
        return render_template('editmodel.html',
                               model=model,
                               editspec=spec,
                               form=form)

    def bindsimdata(self, modelid):
        """Look for updated simulation data and return a highlight view
        Confirm whether to save new bindings or cancel.

        TODO: This seems like the place to implement manual binding
        """
        model = getmodelordie(modelid, toedit=False)
        if request.method == 'POST' and request.form:
            dbname = request.form.get('simsdb')
            if dbname:
                model.simsdb = dbname
        simsdb = get_simsdb(model=model)
        if not simsdb:
            abort(501, "No registered SimulationsDB")

        try:
            matches = simsdb.updatesimdata(model)
        except units.errors.DimensionalityError as e:
            abort(400, "Invalid unit settings: '%s'" % e)
        #form = forms.BindSimDataForm(request.form)
        if request.method == 'POST' and request.form.get(
                'confirm'):  # and form.validate():
            self.modeldb.removecache(model.id)
            istemp = self.modeldb.is_model_temp(modelid)
            model.simdata = {m.id: m for m in matches}
            try:
                newid = str(
                    self.modeldb.write_model(model,
                                             bumpversion="minor",
                                             temp=istemp))
            except Exception as e:
                abort(501, 'Error saving model: %s' % e)
            if istemp:
                return redirect(url_for('.editmodel', modelid=newid))
            else:
                #TODO: add a url for viewmodel here
                return redirect(url_for('modelviewer.overview', modelid=newid))
                #sort the requests by spec and assembly

        return render_template('bindsimdata.html',
                               model=model,
                               matches=matches)
Example #11
0
from flask import Blueprint

from models.question import QuestionModel
from views.LocationModelView import LocationModelView

questions_bp = Blueprint('/questions', __name__)
questions_bp.record(lambda _: register())


def register():
    QuestionList.register(questions_bp, '/questions/',
                          '/questions/<string:_id>')


class QuestionList(LocationModelView):
    def __init__(self):
        super().__init__(QuestionModel)
        self.field_name = "question"
Example #12
0
File: api.py Project: Erez-IL/lark

def current_user():
    return g.user


# Lazily register oauth, redis
def init_blueprint(state):
    oauth.init_app(state.app)
    redis.init_app(state.app)
    db.init_app(state.app)
    bind_models(oauth, user=User, token=Token,
                client=Client, grant=Grant, current_user=current_user)

lark_admin_api = Blueprint('lark_admin_api', __name__)
lark_admin_api.record(init_blueprint)


def api_func(func, oauth_obj, schema=None, *args, **kwargs):
    status_code = 200
    try:
        try:
            request_json = request.get_json()
        except:
            request_json = None

        if schema:
            schema_inst = schema()
            data = schema_inst.serialize(request_json)
        else:
            data = request_json
Example #13
0
            and not state.app.config.get('FOODTRUCK_CMDLINE_MODE', False)):
        raise Exception(
            "You're running FoodTruck outside of `chef`, and will need to "
            "install Flask-Bcrypt to get more proper security.")

    bcrypt_ext.init_app(state.app)
    state.app.bcrypt = bcrypt_ext


# Create the FoodTruck blueprint.
foodtruck_bp = Blueprint('FoodTruck',
                         __name__,
                         template_folder='templates',
                         static_folder='static')

foodtruck_bp.record(record_login_manager)
foodtruck_bp.record(record_bcrypt)


def after_this_request(f):
    if not hasattr(g, 'after_request_callbacks'):
        g.after_request_callbacks = []
    g.after_request_callbacks.append(f)
    return f


class LazySomething(object):
    def __init__(self, factory):
        self._factory = factory
        self._something = None