Ejemplo n.º 1
0
class Statics(object):
    """Static css/js resources for Flask applications.

    Relevant configuration settings from the Flask app config:
    STATICS_MINIFY -- set to True to have minified resources selected instead of uncompressed resources.

    Optional settings to enable specific static resources on all templates by default instead of on-demand:
    STATICS_ENABLE_RESOURCE_<resource name> -- refer to resource_definitions.py for list of options. Set to True to
        enable everywhere.
    """
    def __init__(self, app=None):
        self.all_variables = None
        self.all_resources = None
        self.blueprint = None
        if app is not None:
            self.init_app(app)

    def init_app(self, app):
        """Initialize the extension."""
        # Set default Flask config option.
        app.config.setdefault('STATICS_MINIFY', False)

        # Select resources.
        self.all_resources = ALL_RESOURCES_MINIFIED if app.config.get(
            'STATICS_MINIFY') else ALL_RESOURCES
        self.all_variables = ALL_VARIABLES

        # Add this instance to app.extensions.
        if not hasattr(app, 'extensions'):
            app.extensions = dict()
        if 'statics' in app.extensions:
            raise ValueError('Already registered extension STATICS.')
        app.extensions['statics'] = _StaticsState(self, app)

        # Initialize blueprint.
        name = 'flask_statics_helper'
        static_url_path = '{0}/{1}'.format(app.static_url_path, name)
        self.blueprint = Blueprint(name,
                                   __name__,
                                   template_folder='templates',
                                   static_folder='static',
                                   static_url_path=static_url_path)
        self.blueprint.add_app_template_global(
            self.all_variables, '_flask_statics_helper_all_variables')
        self.blueprint.add_app_template_global(
            self.all_resources, '_flask_statics_helper_all_resources')
        app.register_blueprint(self.blueprint)
Ejemplo n.º 2
0
class Statics(object):
    """Static css/js resources for Flask applications.

    Relevant configuration settings from the Flask app config:
    STATICS_MINIFY -- set to True to have minified resources selected instead of uncompressed resources.

    Optional settings to enable specific static resources on all templates by default instead of on-demand:
    STATICS_ENABLE_RESOURCE_<resource name> -- refer to resource_definitions.py for list of options. Set to True to
        enable everywhere.
    """

    def __init__(self, app=None):
        self.all_variables = None
        self.all_resources = None
        self.blueprint = None
        if app is not None:
            self.init_app(app)

    def init_app(self, app):
        """Initialize the extension."""
        # Set default Flask config option.
        app.config.setdefault('STATICS_MINIFY', False)

        # Select resources.
        self.all_resources = ALL_RESOURCES_MINIFIED if app.config.get('STATICS_MINIFY') else ALL_RESOURCES
        self.all_variables = ALL_VARIABLES

        # Add this instance to app.extensions.
        if not hasattr(app, 'extensions'):
            app.extensions = dict()
        if 'statics' in app.extensions:
            raise ValueError('Already registered extension STATICS.')
        app.extensions['statics'] = _StaticsState(self, app)

        # Initialize blueprint.
        name = 'flask_statics_helper'
        static_url_path = '{0}/{1}'.format(app.static_url_path, name)
        self.blueprint = Blueprint(name, __name__, template_folder='templates', static_folder='static',
                                   static_url_path=static_url_path)
        self.blueprint.add_app_template_global(self.all_variables, '_flask_statics_helper_all_variables')
        self.blueprint.add_app_template_global(self.all_resources, '_flask_statics_helper_all_resources')
        app.register_blueprint(self.blueprint)
Ejemplo n.º 3
0
# -*- coding: utf-8 -*-
__author__ = 'wushuyi'
from flask import current_app, abort
from flask import Blueprint, render_template, redirect, url_for
from model import db
from model.blog import BlogPost, BlogClassify
import math
import view.blog as blog

blog_page = Blueprint('blog_page ', __name__, template_folder='templates')

blog_page.add_app_template_global(blog.get_public, name='blog_public')
blog_page.add_app_template_global(blog.get_classify_list,
                                  name='blog_get_classify_list')

blog_page.add_url_rule('/favicon.ico', endpoint='page', view_func=blog.favicon)
blog_page.add_url_rule('/list/<int:page>',
                       endpoint='post_list',
                       view_func=blog.post_list)
blog_page.add_url_rule('/', endpoint='home', view_func=blog.post_list)

blog_page.add_url_rule('/tag/<string:query_classify>/<int:page>',
                       endpoint='tag_list',
                       view_func=blog.tag_list)
blog_page.add_url_rule('/tag/<string:query_classify>',
                       endpoint='tag',
                       view_func=blog.tag_list)

blog_page.add_url_rule('/article/<string:query_path>',
                       endpoint='posts',
                       view_func=blog.posts)
Ejemplo n.º 4
0
trips.add_url_rule('/new', view_func=CreateTripView.as_view('new'))
trips.add_url_rule('/<slug>/update',
                   view_func=UpdateTripView.as_view('update'))

# Points CRUD


def weekday_class(weekday: str) -> str:
    weekday = escape(weekday)
    wday_short = weekday[0:3]
    weekday_classes = TwScheduleClasses.WEEKDAYS
    return weekday_classes.get(wday_short, weekday_classes['_default'])


trips.add_app_template_filter(weekday_class, 'weekday_class')
trips.add_app_template_global(TwScheduleClasses.CELL_CLASS,
                              'schedule_cell_class')
trips.add_app_template_global(TwScheduleClasses.COMMON_WEEKDAY_CLASS,
                              'schedule_weekday_class')


def trip_point_wrapper(f):
    @wraps(f)
    def handler(slug: str, id: int):
        trip = Trip.query.filter_by(slug=slug).first_or_404()
        point = Point.query.filter(Point.trip == trip, Point.id == id)\
                           .first_or_404()

        add_breadcrumb('Trips', url_for('.index'))
        add_breadcrumb(trip.name, url_for('.show', slug=trip.slug))

        return f(trip, point)
Ejemplo n.º 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)
Ejemplo n.º 6
0
from pptx import Presentation

from pptxbuilder.constants import *
from pptxbuilder.excel_parser import parse, UnsupportedFileException, IncompatibleExcelException
from pptxbuilder.helper import str_chart_type, str_series_opt
from pptxbuilder.pptx_helper import (
    add_bar_chart,
    add_column_chart,
    add_line_chart,
    add_doughnut_chart,
    PPT_CUSTOM_LABEL_SEPERATOR)
from pptxbuilder.util import random_alphanum

builder_bp = Blueprint('builder', __name__)

builder_bp.add_app_template_global(SERIES_BY_CATEGORIES, name='SERIES_BY_CATEGORIES')
builder_bp.add_app_template_global(SERIES_BY_OPTIONS, name='SERIES_BY_OPTIONS')
builder_bp.add_app_template_global(str_series_opt)

builder_bp.add_app_template_global(CHART_TYPE_BAR, name='CHART_TYPE_BAR')
builder_bp.add_app_template_global(CHART_TYPE_COLUMN, name='CHART_TYPE_COLUMN')
builder_bp.add_app_template_global(CHART_TYPE_LINE, name='CHART_TYPE_LINE')
builder_bp.add_app_template_global(CHART_TYPE_PIE, name='CHART_TYPE_PIE')
builder_bp.add_app_template_global(str_chart_type)

this_dir = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))


class Create(MethodView):
    def post(self):
        xls_str = request.form.get('file')
Ejemplo n.º 7
0
    prozorro_api_item_path,
    prozorro_api_complaint_path,
    prozorro_portal_tender_path,
    prozorro_api_url,
    prozorro_portal_url,
    url_for_search,
)

bp = Blueprint("app_views", __name__, template_folder="templates")

bp.add_app_template_filter(typing_is_dict, "typing_is_dict")
bp.add_app_template_filter(typing_is_list, "typing_is_list")

bp.add_app_template_filter(prozorro_portal_url, "prozorro_portal_url")
bp.add_app_template_filter(prozorro_portal_tender_path,
                           "prozorro_portal_tender_path")
bp.add_app_template_filter(prozorro_api_url, "prozorro_api_url")
bp.add_app_template_filter(prozorro_api_tender_path,
                           "prozorro_api_tender_path")
bp.add_app_template_filter(prozorro_api_item_path, "prozorro_api_item_path")
bp.add_app_template_filter(prozorro_api_complaint_path,
                           "prozorro_api_complaint_path")

bp.add_app_template_global(url_for_search, "url_for_search")


@bp.route("/", methods=["GET"])
@login_groups_required(["admins", "accountants"])
def index():
    return render_template("index.html")
Ejemplo n.º 8
0
class ModelViewer(object):
    """Blueprint for inspecting saved model definitions
    Args:
        app:  The bgexplorer Flask object
        modeldb: a ModelDB object. If None, will get from the Flask object
        url_prefix (str): Where to mount this blueprint relative to root
    """
    defaultversion = 'HEAD'
    joinkey = '___'

    def __init__(self,
                 app=None,
                 modeldb=None,
                 cacher=InMemoryCacher(),
                 url_prefix='/explore'):
        self.app = app
        self._modeldb = modeldb

        self.bp = Blueprint('modelviewer',
                            __name__,
                            static_folder='static',
                            template_folder='templates',
                            url_prefix='/<modelname>/<version>')

        self.bp.add_app_template_global(lambda: self, 'getmodelviewer')
        self.set_url_processing()
        self.register_endpoints()

        if self.app:
            self.init_app(app, url_prefix)

        self._threads = {}
        self._cacher = cacher
        #### User Overrides ####
        self.bomcols = bomfuncs.getdefaultcols()

    def init_app(self, app, url_prefix=''):
        """Register ourselves with the app"""
        app.register_blueprint(self.bp,
                               url_prefix=url_prefix + self.bp.url_prefix)
        app.extensions['ModelViewer'] = self

    @property
    def modeldb(self):
        return self._modeldb or utils.get_modeldb()

    @property
    def simsdb(self):
        return g.simsdbview.simsdb

    def set_url_processing(self):
        """process model objects into URL strings, and pre-load models
        into the `flask.g` object before passing to endpoint functions
        """
        @self.bp.after_request
        def addpostheaders(response):
            """ Add cache-control headers to all modelviewer responses """
            if self.app.config.get('NO_CLIENT_CACHE'):
                return
            # todo: add Last-Modified
            response.headers["Cache-Control"] = "private, max-age=100"
            try:
                response.headers['ETag'] = make_etag(g.model)
            except (AttributeError, KeyError):  # model is not loaded in g
                pass
            return response

        @self.bp.url_defaults
        def add_model(endpoint, values):
            model = values.pop('model', None) or g.get('model', None)
            if model:
                #model could be object or dict
                name = getattr(model, 'name', None) or model.get('name', None)
                version = getattr(model, 'version', None)
                if version is None and hasattr(model, 'get'):
                    version = model.get('version', None)
                values.setdefault('modelname', name)
                permalink = values.pop('permalink', None)
                if permalink is not None:
                    values['version'] = (version
                                         if permalink else self.defaultversion)
                else:
                    values.setdefault(
                        'version', version
                        if not g.get('permalink') else self.defaultversion)
            elif 'modelid' in values:
                values['modelname'] = values.pop('modelid')
                values['version'] = '_'
                values['permalink'] = 1

            #transform components, specs into IDs
            if 'component' in values:
                values['componentid'] = values.pop('component').id
            if 'spec' in values:
                values['specid'] = values.pop('spec').getrootspec().id
            if 'match' in values:
                values['matchid'] = values.pop('match').id

        @self.bp.url_value_preprocessor
        def find_model(endpoint, values):
            # URL has different formats that result in different queries
            query = None
            if 'modelid' in values:
                query = values.pop('modelid')
            elif 'modelname' in values:
                query = {'name': values.pop('modelname')}
                version = values.pop('version', self.defaultversion)
                if version == '_':  #special, means name is actually ID
                    query['_id'] = query.pop('name')
                elif version != self.defaultversion:
                    query['version'] = version
            if not query:
                abort(400, "Incomplete model specification")

            # this function is called before `before_requests`, but we don't
            # want to extract the model if the client requested a cached
            # view. So we have to do the cache checking here
            etagreq = request.headers.get('If-None-Match')
            if etagreq and not self.app.config.get('NO_CLIENT_CACHE'):
                # construct the etag from the DB entry
                projection = {'editDetails.date': True}
                modeldict = self.modeldb.get_raw_model(query, projection)
                etag = make_etag(modeldict)
                if etagreq == etag:
                    abort(make_response('', '304 Not Modified',
                                        {'ETag': etag}))

            # if we get here, it's not in client cache
            g.model = utils.getmodelordie(query, self.modeldb)
            if version == self.defaultversion:
                g.permalink = url_for(endpoint, permalink=True, **values)
            g.simsdbview = utils.get_simsdbview(model=g.model)
            #construct the cached datatable in the background
            if self._cacher:
                self.build_datatable(g.model)

    def register_endpoints(self):
        """Define the view functions here"""
        @self.bp.route('/')
        def overview():
            history = self.modeldb.get_model_history(g.model.id)
            return render_template('overview.html', history=history)

        @self.bp.route('/component/')
        @self.bp.route('/component/<componentid>')  #should be uuid type?
        def componentview(componentid=None):
            if componentid:
                component = utils.getcomponentordie(g.model, componentid)
                matches = g.model.getsimdata(component=component)
                datasets = sum((m.dataset or [] for m in matches), [])
                return render_template("componentview.html",
                                       component=component,
                                       datasets=datasets)
            else:
                return render_template("componentsoverview.html")

        @self.bp.route('/emissions/')
        def emissionsoverview():
            rootspecs = [s for s in g.model.specs.values() if not s.parent]
            return render_template("emissionsoverview.html",
                                   rootspecs=rootspecs)

        @self.bp.route('/emission/<specid>')
        def emissionview(specid):
            spec = utils.getspecordie(g.model, specid)
            #find all simulation datasets associated to this spec
            matches = []
            if spec.getrootspec() == spec:
                matches = g.model.getsimdata(rootspec=spec)
            else:
                matches = g.model.getsimdata(spec=spec)
            datasets = sum((m.dataset or [] for m in matches), [])
            return render_template('emissionview.html',
                                   spec=spec,
                                   matches=matches,
                                   datasets=datasets)

        @self.bp.route('/simulations/')
        def simulationsoverview():
            return render_template("simulationsoverview.html")

        @self.bp.route('/queries/')
        def queriesoverview():
            #build a unique list of all queries
            queries = {}
            for m in g.model.getsimdata():
                key = str(m.query)
                if key not in queries:
                    queries[key] = []
                queries[key].append(m)

            return render_template('queriesoverview.html', queries=queries)

        @self.bp.route('/dataset/<dataset>')
        def datasetview(dataset):
            detail = self.simsdb.getdatasetdetails(dataset)
            return render_template("datasetview.html",
                                   dataset=dataset,
                                   detail=detail)

        @self.bp.route('/simdatamatch/<matchid>')
        def simdatamatchview(matchid):
            match = utils.getsimdatamatchordie(g.model, matchid)
            linkspec = match.spec.getrootspec()
            return render_template("simdatamatchview.html", match=match)

        @self.bp.route('/billofmaterials')
        def billofmaterials():
            bomrows = bomfuncs.getbomrows()
            return render_template("billofmaterials.html",
                                   bomrows=bomrows,
                                   bomcols=self.bomcols)

        @self.bp.route('/datatable')
        def datatable():
            """Return groups and values for all simdatamatches"""
            return self.get_datatable(g.model)

        @self.bp.route('/tables/default')
        def tablesdefault():
            """Show some default tables with the calculated rows"""
            return render_template("tablesdefault.html")

        @self.bp.route('/charts/default')
        def chartsdefault():
            """Show some default charts with the calculated rates"""
            return render_template("chartsdefault.html")

        @self.bp.route('/spectra/default')
        def spectradefault():
            return render_template("spectradefault.html")

        @self.bp.route('/export')
        def export():
            """Present the model as a JSON document"""
            d = g.model.todict()
            #replace ObjectIds with strings
            if isinstance(d.get('_id'), ObjectId):
                d['_id'] = str(d['_id'])
            if isinstance(d.get('derivedFrom'), ObjectId):
                d['derivedFrom'] = str(d['derivedFrom'])
            return Response(json.dumps(d), mimetype="application/json")

        @self.bp.route('/getspectrum')
        @self.bp.route('/getspectrum/<specname>')
        def getspectrum(specname=None):
            # get the generator for the spectrum
            if not specname:
                valname = request.args.get('val')
                if not valname:
                    abort(404,
                          "Either spectrum name or value name is required")
                specname = g.simsdbview.values_spectra.get(valname)
                if not specname:
                    # valname might have a unit suffix applied to it
                    index = valname.rfind(' [')
                    valname = valname[:index]
                    specname = g.simsdbview.values_spectra.get(valname)
                if not specname:
                    abort(404, f"No spectrum associated to value '{valname}'")
            speceval = g.simsdbview.spectra.get(specname)
            if speceval is None:
                abort(404, f"No spectrum generator for '{specname}'")

            log.debug(f"Generating spectrum: {specname}")
            title = specname
            # get the matches
            matches = request.args.getlist('m')
            try:
                matches = [g.model.simdata[m] for m in matches]
            except KeyError:
                abort(404, "Request for unknown sim data match")
            if not matches:
                # matches may be filtered by component or spec
                component = None
                if 'componentid' in request.args:
                    component = utils.getcomponentordie(
                        g.model, request.args['componentid'])
                    title += ", Component = " + component.name
                rootspec = None
                if 'specid' in request.args:
                    rootspec = utils.getspecordie(g.model,
                                                  request.args['specid'])
                    title += ", Source = " + rootspec.name
                matches = g.model.getsimdata(rootcomponent=component,
                                             rootspec=rootspec)

            # test for a group filter
            groupname = request.args.get('groupname')
            groupval = request.args.get('groupval')
            if groupname and groupval and groupval != g.simsdbview.groupjoinkey:
                try:
                    groupfunc = g.simsdbview.groups[groupname]
                except KeyError:
                    abort(404, f"No registered grouping function {groupname}")

                def _filter_group(match):
                    mgval = g.simsdbview.evalgroup(match, groupname, False)
                    return g.simsdbview.is_subgroup(mgval, groupval)

                matches = list(filter(_filter_group, matches))
                title += ", " + groupname + " = "
                title += '/'.join(g.simsdbview.unflatten_gval(groupval, True))

            if not matches:
                abort(404, "No sim data matching query")

            spectrum = self.simsdb.evaluate([speceval], matches)[0]
            if not hasattr(spectrum, 'hist') or not hasattr(
                    spectrum, 'bin_edges'):
                abort(500, f"Error generating spectrum, got {type(spectrum)}")

            unit = g.simsdbview.spectra_units.get(specname, None)
            if unit is not None:
                try:
                    spectrum.hist.ito(unit)
                except AttributeError:  #not a quantity
                    pass

            fmt = request.args.get("format", "png").lower()
            response = None
            if fmt == 'tsv':
                response = Response(self.streamspectrum(spectrum, sep='\t'),
                                    mimetype='text/tab-separated-value')
            elif fmt == 'csv':
                response = Response(self.streamspectrum(spectrum, sep=','),
                                    mimetype='text/csv')
            elif fmt == 'png':
                response = self.specimage(spectrum, title=title)
            else:
                abort(400, f"Unhandled format specifier {fmt}")

            return response

    def streamspectrum(self,
                       spectrum,
                       sep=',',
                       include_errs=True,
                       fmt='{:.5g}'):
        """ Return a generator response for a spectrum
        Args:
            spectrum (Histogram): spectrum to stream
            sep (str): separator (e.g. csv or tsv)
            include_errs (bool): if True, include a column for errors
            fmt (str): format specifier
        Returns:
            generator to construct Response
        """
        bins, vals = spectrum.bin_edges, spectrum.hist
        vals_has_units = hasattr(vals, 'units')
        bins_has_units = hasattr(bins, 'units')

        # yield the header
        head = ["Bin", "Value"]
        if bins_has_units:
            head[0] += f' [{bins.units}]'
        if vals_has_units:
            head[1] += f' [{vals.units}]'
        if include_errs:
            head.append('Error')
        yield sep.join(head) + '\n'

        # now remove units and extract errors
        if vals_has_units:
            vals = vals.m
        if bins_has_units:
            bins = bins.m
        vals, errs = unumpy.nominal_values(vals), unumpy.std_devs(vals)

        for abin, aval, anerr in zip(bins, vals, errs):
            yield sep.join(
                (str(abin), fmt.format(aval), fmt.format(anerr))) + '\n'

    def specimage(self, spectrum, title=None, logx=True, logy=True):
        """ Generate a png image of a spectrum
        Args:
            spectrum (Histogram): spectrum to plot
            title (str): title
            logx (bool): set x axis to log scale
            logy (bool): set y axis to log scale
        Returns:
            a Response object
        """
        if Figure is None:
            abort(500, "Matplotlib is not available")
        log.debug("Generating spectrum image")
        # apparently this aborts sometimes?
        try:
            x = spectrum.bin_edges.m
        except AttributeError:
            x = spectrum.bin_edges
        fig = Figure()
        ax = fig.subplots()
        ax.errorbar(
            x=x[:-1],
            y=unumpy.nominal_values(spectrum.hist),
            yerr=unumpy.std_devs(spectrum.hist),
            drawstyle='steps-post',
            elinewidth=0.6,
        )
        ax.set_title(title)
        if logx:
            ax.set_xscale('log')
        if logy:
            ax.set_yscale('log')
        if hasattr(spectrum.bin_edges, 'units'):
            ax.set_xlabel(f'Bin [{spectrum.bin_edges.units}]')
        if hasattr(spectrum.hist, 'units'):
            ax.set_ylabel(f"Value [{spectrum.hist.units}]")
        """
        #limit to at most N decades...
        maxrange = 100000
        ymin, ymax = plt.ylim()
        ymax = 10**ceil(log10(ymax))
        ymin = max(ymin, ymax/maxrange)
        plt.ylim(ymin, ymax)
        plt.tick_params(which='major',length=6, width=1)
        plt.tick_params(which='minor',length=4,width=1)
        iplt.gcf().set_size_inches(9,6)
        plt.gca().set_position((0.08,0.1,0.7,0.8))
        """
        log.debug("Rendering...")
        out = BytesIO()
        fig.savefig(out, format='png')
        log.debug("Done generating image")
        size = out.tell()
        out.seek(0)
        res = Response(
            out.getvalue(),
            content_type='image/png',
            headers={
                'Content-Length': size,
                'Content-Disposition': 'inline',
            },
        )
        return res

    #need to pass simsdb because it goes out of context
    def streamdatatable(self, model, simsdbview=None):
        """Stream exported data table so it doesn't all go into mem at once
        """
        log.debug(f"Generating data table for model {model.id}")
        #can't evaluate values if we don't have a simsdb
        if simsdbview is None:
            simsdbview = utils.get_simsdbview(model=model) or SimsDbView()
        simsdb = simsdbview.simsdb
        valitems = list(simsdbview.values.values())
        matches = model.simdata.values()
        #send the header
        valheads = [
            'V_' + v + (' [%s]' % simsdbview.values_units[v]
                        if v in simsdbview.values_units else '')
            for v in simsdbview.values
        ]
        yield ('\t'.join(
            chain(['ID'],
                  ('G_' + g for g in simsdbview.groups), valheads)) + '\n')
        #loop through matches
        for match in matches:
            evals = []
            if valitems:
                evals = simsdb.evaluate(valitems, match)
                for index, vlabel in enumerate(simsdbview.values):
                    # convert to unit if provided
                    unit = simsdbview.values_units.get(vlabel, None)
                    if unit:
                        try:
                            evals[index] = evals[index].to(unit).m
                        except AttributeError:  #not a Quantity...
                            pass
                        except units.errors.DimensionalityError as e:
                            if evals[index] != 0:
                                log.warning(e)
                            evals[index] = getattr(evals[index], 'm', 0)
                    # convert to string
                    evals[index] = "{:.3g}".format(evals[index])
                    if match.spec.islimit:
                        evals[index] = '<' + evals[index]

            groupvals = (g(match) for g in simsdbview.groups.values())
            groupvals = (simsdbview.groupjoinkey.join(g) if isinstance(
                g, (list, tuple)) else g for g in groupvals)
            yield (
                '\t'.join(chain([match.id],
                                (str(g) for g in groupvals), evals)) + '\n')
            #sleep(0.2) # needed to release the GIL
        log.debug(f"Finished generating data table for model {model.id}")

    @staticmethod
    def datatablekey(model):
        return "datatable:" + make_etag(model)

    def build_datatable(self, model):
        """Generate a gzipped datatable and cache it
        Args:
            model: a BgModel

        Returns:
            None if no cacher is defined
            0 if the result is already cached
            Thread created to generate the cache otherwise
        """
        #don't bother to call if we don't have a cache
        if not self._cacher:
            return None

        #TODO: self._threads and self._Cacher should probably be mutexed
        #see if there's already a worker
        key = self.datatablekey(model)
        if key in self._threads:
            return self._threads[key]
        #see if it's already cached
        if self._cacher.test(key):
            return 0

        #if we get here, we need to generate it
        def cachedatatable(dbview):
            compressor = zlib.compressobj()
            res = b''.join(
                compressor.compress(s.encode('utf-8'))
                for s in self.streamdatatable(model, dbview))
            res += compressor.flush()
            self._cacher.store(key, res)
            self._threads.pop(key)  #is this a bad idea???

        dbview = utils.get_simsdbview(model=model)
        thread = threading.Thread(target=cachedatatable,
                                  name=key,
                                  args=(dbview, ))
        self._threads[key] = thread
        thread.start()
        return thread

    def get_datatable(self, model):
        """Return a Result object with the encoded or streamed datatable"""
        key = self.datatablekey(model)
        if not self._cacher:  # or self.modeldb.is_model_temp(model.id):
            #no cache, so stream it directly, don't bother to zip it
            #should really be text/csv, but then browsersr won't let you see it
            return Response(self.streamdatatable(model), mimetype='text/plain')

        if not self._cacher.test(key):
            thread = self.build_datatable(model)
            if thread:
                thread.join()  #wait until it's done
        res = self._cacher.get(key)
        if not res:
            abort(500, "Unable to generate datatable")
        return Response(res,
                        headers={
                            'Content-Type': 'text/plain;charset=utf-8',
                            'Content-Encoding': 'deflate',
                        })

    def get_componentsort(self, component, includeself=True):
        """Return an array component names in assembly order to be passed
        to the javascript analyzer for sorting component names
        """
        #TODO: cache this
        result = [component.name] if includeself else []
        for child in component.getcomponents(merge=False):
            branches = self.get_componentsort(child)
            if includeself:
                branches = [
                    self.joinkey.join((component.name, s)) for s in branches
                ]
            result.extend(branches)
        return result

    def get_groupsort(self):
        res = dict(**g.simsdbview.groupsort)
        #todo: set up provided lists
        if 'Component' not in res:
            res['Component'] = self.get_componentsort(g.model.assemblyroot,
                                                      False)
        return res

    def eval_matches(self, matches, dovals=True, dospectra=False):
        """ Evaluate `matches` for all registered values and specs
        Args:
            matches: list of SimDataMatch objects to evaluate
            dovals (bool): include entries from `self.values` ?
            dospectra (bool): include entries from `self.spectra` ?
        Returns:
            values (dict): dictionary mapping of keys in `self.values` and
                           `self.spectra` to evaluated results. If a key in
                           `spectra` conflicts with one in values, it will be
                           renamed to "spectrum_<key>"
        """
        # this no longer works, but wasn't used. Keep around for now...
        raise NotImplementedError()

        vals = dict(**self.values) if dovals else {}
        if dospectra:
            for key, spectrum in self.spectra.items():
                if key in vals:
                    key = f'spectrum_{key}'
                vals[key] = spectrum
        result = dict(
            zip(vals.keys(), self.simsdb.evaluate(vals.values(), matches)))
        if dovals:
            for key, unit in self.values_units.items():
                try:
                    result[key].ito(unit)
                except AttributeError:
                    pass
        if dospectra:
            for key, unit in self.spectra_units.items():
                if dovals and key in self.values:
                    key = f'spectrum_{key}'
                try:
                    result[key].ito(unit)
                except AttributeError:
                    pass
        return result
Ejemplo n.º 9
0
    if posts:
        #post_counts = len([post for post in posts if post.draft==False])
        global_data['postCounts'] = posts

    shuos = Shuoshuo.query.order_by(Shuoshuo.timestamp.desc()).all()
    if shuos:
        global_data['newShuo'] = shuos[0].body_to_html

    guestbook = Page.query.filter_by(url_name='guestbook').first()
    if guestbook:
        guestbook_counts = guestbook.comments.count()
        global_data['guestbookCounts'] = guestbook_counts

    all_boxes = SideBox.query.order_by(SideBox.id.desc()).all()
    if all_boxes:
        adv_boxes = [
            box for box in all_boxes
            if box.unable is False and box.is_advertising is True
        ]
        global_data['ads_boxes'] = adv_boxes
        my_boxes = [
            box for box in all_boxes
            if box.unable is False and box.is_advertising is False
        ]
        global_data['my_boxes'] = my_boxes

    return global_data


main.add_app_template_global(global_datas, 'global_datas')
Ejemplo n.º 10
0
# Author: jianglin
# Email: [email protected]
# Created: 2017-03-17 13:49:48 (CST)
# Last Update:星期日 2017-8-27 22:58:3 (CST)
#          By:
# Description:
# **************************************************************************
from flask import Blueprint
from .views import (BlogListView, BlogView, RssView, ArchiveView)
from .filters import (safe_markdown, random_fortune, tag_archives,
                      category_archives, time_archives, orgmode)

site = Blueprint('blog', __name__)
bloglist_view = BlogListView.as_view('bloglist')
site.add_url_rule('', view_func=bloglist_view)
site.add_url_rule('/', view_func=bloglist_view)
site.add_url_rule('/<int:blogId>', view_func=BlogView.as_view('blog'))
site.add_url_rule('/archives', view_func=ArchiveView.as_view('archive'))
site.add_url_rule('/rss', view_func=RssView.as_view('rss'))

site.add_app_template_global(random_fortune)
site.add_app_template_global(tag_archives)
site.add_app_template_global(category_archives)
site.add_app_template_global(time_archives)
site.add_app_template_filter(safe_markdown)
site.add_app_template_filter(orgmode)


def init_app(app):
    app.register_blueprint(site, url_prefix='/blog')
Ejemplo n.º 11
0
from .forms import DataJointFormFactory

PER_PAGE = 20
ENABLE_EDIT=True


djpage = Blueprint('djpage', __name__,
                        template_folder='templates',
                        static_folder='static',
                        static_url_path='/%s' % __name__
                    )


form_factory = DataJointFormFactory()
_registered_relations = {}

from .display_tools import display
from .edit import enter


def register(for_form=False, **kwargs):
    for name, rel in kwargs.items():
        assert isinstance(rel, dj.BaseRelation), "rel must be a subclass of dj.Relation"
        _registered_relations[name] = rel

    if for_form:
        form_factory.register(**kwargs)


djpage.add_app_template_global(ENABLE_EDIT, 'edit_enabled')
Ejemplo n.º 12
0
    rule = '/viewattrs/' + name + "/"
    route = dict(endpoint=name, view_func=viewattrs(name, obj))
    attrsview.add_url_rule(rule + '<path:keypath>', **route)
    attrsview.add_url_rule(rule, **route)


@contextfunction
def pancontext(context, keypath=""):
    obj = dict(context.items())
    view_func = viewattrs('context', obj)
    return view_func(keypath)


attrsview = Blueprint('attrsview', __name__)
attrsview_routes('current_app', current_app)
attrsview.add_app_template_global(pancontext)


@attrsview.route('/viewattrs/context/')
@attrsview.route('/viewattrs/context/<path:keypath>')
def viewcontext(keypath=""):
    context = 'pancontext(keypath="{}")|safe'.format(keypath)
    return render_template_string('{{ ' + context + '}}')


def create_attrsview_app():
    """app factory"""
    from basics import basics
    from templateview import templateview
    app = Flask(__name__)
    app.config['TEMPLATES_AUTO_RELOAD'] = True
Ejemplo n.º 13
0
# -*- coding: utf-8 -*-
__author__ = 'wushuyi'
from flask import current_app, abort
from flask import Blueprint, render_template, redirect, url_for
from model import db
from model.blog import BlogPost, BlogClassify
import math
import view.blog as blog

blog_page = Blueprint(
    'blog_page ',
    __name__,
    template_folder='templates'
)

blog_page.add_app_template_global(blog.get_public, name='blog_public')
blog_page.add_app_template_global(blog.get_classify_list, name='blog_get_classify_list')

blog_page.add_url_rule('/favicon.ico', endpoint='page', view_func=blog.favicon)
blog_page.add_url_rule('/list/<int:page>', endpoint='post_list', view_func=blog.post_list)
blog_page.add_url_rule('/', endpoint='home', view_func=blog.post_list)

blog_page.add_url_rule('/tag/<string:query_classify>/<int:page>', endpoint='tag_list', view_func=blog.tag_list)
blog_page.add_url_rule('/tag/<string:query_classify>', endpoint='tag', view_func=blog.tag_list)

blog_page.add_url_rule('/article/<string:query_path>', endpoint='posts', view_func=blog.posts)

blog_page.add_url_rule('/search', endpoint='search', view_func=blog.search)
blog_page.add_url_rule('/search/<int:page>', endpoint='search_list', view_func=blog.search)

Ejemplo n.º 14
0
def link_to_file(filepath, filename):
    if os.path.isfile(os.path.join(filepath, filename)):
        item = db.File.objects(filepath=filepath, filename=filename).first()
        if item is not None:
            linkURL = url_for('mongomanager.showfile', id=str(item.id))
            link = '<a href="' + linkURL + '">' + str(item.filename) + '</a>'
        else:
            link = str(filename) + ' [Not indexed]'
    else:
        linkURL = url_for('mongomanager.render_directory',
                          path=os.path.join(filepath, filename))
        link = "<a href='" + linkURL + "'>" + str(filename) + "</a>"
    return link


mongomanager.add_app_template_global(link_to_file)


# Construct a link to the parent directory
@requires_perm('admin')
def link_to_parent_dir(path):
    parentpath = os.path.abspath(os.path.join(path, '..'))
    link = ("<a href='" +
            url_for('mongomanager.render_directory', path=parentpath) +
            "'>../</a>")
    return link


mongomanager.add_app_template_global(link_to_parent_dir)

Ejemplo n.º 15
0
from flask import Blueprint, render_template, redirect, url_for, flash

from model.NewPost import NewPost
from model.NewThread import NewThread
from model.Post import Post, render_for_threads
from model.PostRemoval import PostRemoval
from model.PostReplyPattern import url_for_post
from model.Poster import Poster
from model.Slip import get_slip
from model.SubmissionError import SubmissionError
from model.Thread import Thread
from model.ThreadPosts import ThreadPosts
from shared import db

threads_blueprint = Blueprint('threads', __name__, template_folder='template')
threads_blueprint.add_app_template_global(url_for_post)


@threads_blueprint.route("/new/<int:board_id>")
def new(board_id):
    return render_template("new-thread.html", board_id=board_id)


@threads_blueprint.route("/new", methods=["POST"])
def submit():
    try:
        thread = NewThread().post_impl()
        return redirect(url_for("threads.view", thread_id=thread.id))
    except SubmissionError as e:
        flash(str(e.args[0]))
        return redirect(url_for("threads.new", board_id=e.args[1]))
Ejemplo n.º 16
0
    SearchDeleteForm

from .importing import start_import_thread, threads
from .search import Searcher
from .widgets import \
    EditBatchItemFormWidget, \
    FormRenderer, \
    FormWidget, \
    LibraryRenderer, \
    SearchFormWidget, \
    SavedSearchFormWidget, WidgetRenderer
from . import csrf

libraries = Blueprint('libraries', __name__)

libraries.add_app_template_global(lambda: str(uuid.uuid1()), name='uuid')
libraries.add_app_template_global(User.current_uid, name='user_current_uid')
libraries.add_app_template_global(Folder.from_path, name='folder_from_path')
libraries.add_app_template_global(Library.enumerate_all,
                                  name='library_enumerate_all')
libraries.add_app_template_global(Tag.enumerate_roots,
                                  name='tag_enumerate_roots')
libraries.add_app_template_global(SavedSearch.enumerate_user,
                                  name='saved_search_enumerate_user')


def url_self(**args):
    return url_for(request.endpoint, **dict(request.view_args, **args))


current_app.jinja_env.globals.update(url_self=url_self)
Ejemplo n.º 17
0
from flask import Blueprint, request, render_template, redirect, url_for, session, flash
from werkzeug.security import check_password_hash

from model.Session import Session
from model.Slip import Slip, gen_slip, make_session, get_slip, slip_from_id
from shared import db


slip_blueprint = Blueprint('slip', __name__, template_folder='template')
slip_blueprint.add_app_template_global(get_slip)
slip_blueprint.add_app_template_global(slip_from_id)


@slip_blueprint.route("/")
def landing():
    return render_template("slip.html")


@slip_blueprint.route("/register", methods=["POST"])
def register():
    name = request.form["name"]
    password = request.form["password"]
    slip = gen_slip(name, password)
    db.session.flush()
    make_session(slip)
    db.session.commit()
    return redirect(url_for("slip.landing"))


@slip_blueprint.route("/login", methods=["POST"])
def login():
Ejemplo n.º 18
0
from model.Board import Board
from model.BoardList import BoardList
from model.BoardListCatalog import BoardCatalog
from model.Post import render_for_catalog
from model.Slip import get_slip
from model.Tag import Tag
from shared import db


def style_for_tag(tag_name):
    tag = db.session.query(Tag).filter(Tag.name == tag_name).one()
    return {"bg_style": tag.bg_style, "text_style": tag.text_style}


boards_blueprint = Blueprint('boards', __name__, template_folder='template')
boards_blueprint.add_app_template_global(style_for_tag)


@boards_blueprint.route("/")
def list():
    return render_template("board-index.html", boards=BoardList().get())


@boards_blueprint.route("/<int:board_id>")
def catalog(board_id):
    threads = BoardCatalog().retrieve(board_id)
    board_name = db.session.query(Board).filter(Board.id == board_id).one().name
    render_for_catalog(threads)
    return render_template("catalog.html", threads=threads, board_id=board_id, board_name=board_name)

Ejemplo n.º 19
0
class SimsViewer(object):
    """Blueprint for searching and inspecting simulation data
    Args:
        app: the bgexplorer Flask object
        url_prefix (str): Where to mount this blueprint relative to root
        detailtemplate: path to template file for detailed simulation view
        enableupload (bool): if True, allow uploading new entries
        uploadsummary (func): generate a summary projection from uploaded
                              (json-generated) documents
    """
    def __init__(self,
                 app=None,
                 url_prefix='/simulations',
                 detailtemplate=None,
                 enableupload=True,
                 uploadsummary=None):
        self.app = app
        self.enable_upload = enableupload
        self.uploadsummary = uploadsummary

        self.bp = Blueprint('simsviewer',
                            __name__,
                            static_folder='static',
                            template_folder='templates')
        self.bp.add_app_template_global(lambda: self, 'getsimsviewer')
        self.bp.add_app_template_global(findsimmatches, 'findsimmatches')
        self.bp.add_app_template_global(json.dumps, 'json_dumps')

        #handle 'query' requests for non strings
        @self.bp.url_defaults
        def url_defaults(endpoint, values):
            query = values.get('query', None)
            if query and not isinstance(query, str):
                values['query'] = json.dumps(query)

        @self.bp.before_request
        def preprocess():
            if 'query' in request.args:
                try:
                    args = request.args.copy()
                    args['query'] = json.loads(args['query'])
                    request.args = args
                except (KeyError, json._json.JSONDecodeError):
                    pass

        self.register_endpoints()
        if self.app:
            self.init_app(app, url_prefix)

    def init_app(self, app, url_prefix=''):
        """Register ourselves with the app"""
        app.register_blueprint(self.bp, url_prefix=url_prefix)
        app.extensions['SimulationsViewer'] = self
        key = "ENABLE_SIMULATION_UPLOADS"
        self.enable_upload = app.config.setdefault(key, self.enable_upload)

    @property
    def simsdb(self):
        return g.simsdbview.simsdb

    def getcolnames(self, sims):
        """ Get the column names to display in summary table """
        columns = []
        try:
            columns = g.simsdbview.summarycolumns
        except AttributeError:
            pass
        if sims and not columns:
            #non-underscore keys with string or number values
            for key, val in sims[0].items():
                if (not key.startswith('_') and key != 'id'
                        and isinstance(val, (str, int, float))):
                    columns.append(key)
        return columns

    def register_endpoints(self):
        """Attach the model if requested"""
        @self.bp.url_value_preprocessor
        def find_model(endpoint, values):
            if 'modelid' in request.args:
                g.model = utils.getmodelordie(request.args['modelid'])
                values.setdefault('dbname', g.model.simsdb)
            if 'dbname' in values:
                g.dbname = values.pop('dbname')
                g.simsdbview = utils.get_simsdbview(name=g.dbname)

        """ make sure we have a simsdb """

        @self.bp.url_defaults
        def addsimsdbview(endpoint, values):
            model = values.pop('model', None) or g.get('model', None)
            if model:
                #values['modelid'] = model.id
                dbname = model.simsdb
                if not dbname:
                    dbname = current_app.getdefaultsimviewname()
                values.setdefault('dbname', dbname)

            simsdbview = values.pop('simsdbview', None) or g.get(
                'simsdbview', None)
            if simsdbview and 'dbname' not in values:
                values['dbname'] = current_app.getsimviewname(simsdbview)

        """Define the view functions here"""

        @self.bp.route('/')
        def index():
            dbnames = list(current_app.simviews.keys())
            if len(dbnames) == 1:
                return redirect(url_for('.overview', dbname=dbnames[0]))
            return render_template('listdbs.html', dbnames=dbnames)

        @self.bp.route('/<dbname>/')
        def overview():
            query = request.args.get('query', None)
            try:
                projection = g.simsdbview.summarypro
                sims = list(self.simsdb.runquery(query, projection=projection))
            except Exception as e:
                abort(400, "Invalid query specifier")
            columns = self.getcolnames(sims)
            return render_template('simoverview.html',
                                   sims=sims,
                                   query=query,
                                   colnames=columns)

        @self.bp.route('/<dbname>/dataset/<dataset>')
        def detailview(dataset):
            detail = self.simsdb.getdatasetdetails(dataset)
            matches = findsimmatches(dataset)
            return render_template('datasetview.html',
                                   dataset=dataset,
                                   detail=detail)

        @self.bp.route('/<dbname>/dataset/<dataset>/raw')
        def rawview(dataset):
            """Export the dataset as raw JSON"""
            detail = self.simsdb.getdatasetdetails(dataset)
            return json.jsonify(detail)

        if not self.enable_upload:
            return

        @self.bp.route('/<dbname>/api/upload', methods=('POST', ))
        def api_upload():
            """ Upload files to be inserted, return JSON response """
            files = request.files.getlist('fupload')
            if request.is_json:
                print(request.data, request.json)
                fakefile = io.BytesIO(request.data)
                fakefile.filename = 'JSON'
                files = [fakefile]
            try:
                result = g.simsdbview.handle_uploads(files)
            except NotImplementedError:
                abort(501, "Uploads are not implemented for this database")
            except BaseException as e:
                err = f"{type(e).__name__}: {str(e)}"
                result = dict(entries={}, errors={None: err})
            return result

        @self.bp.route('/<dbname>/upload', methods=('GET', 'POST'))
        def upload():
            """ Upload new JSON-formatted entries """
            result = None
            if request.method == 'POST':
                result = api_upload()
            return render_template('uploadsimdata.html', result=result)
Ejemplo n.º 20
0
    """
    flask_app.register_blueprint(admin, url_prefix="/admin/")
    login_manager.init_app(flask_app)


@login_manager.unauthorized_handler
def unauthorized_request() -> Response:
    """This function is called if a unauthorized user requests a route which is
    protected.
    """
    logger.warning('User tried to access restricted page without password',
                   requested_url=request.url)
    return redirect(url_for('.login', next_url=request.url))


admin.add_app_template_global(lambda: current_user, 'current_user')


@admin.add_app_template_global
def utcnow() -> DatetimeWithTimezone:
    """Get current date.
    """
    return DatetimeWithTimezone.utcnow()


@admin.app_template_filter('datetime')
def _format_datetime(date: datetime.datetime) -> str:
    return date.strftime('%Y-%m-%d %T')


@admin.app_template_filter('nested_get')
Ejemplo n.º 21
0
from .models import Currency, Dispatcher, \
    Order, OrderLine, Product, Store
from . import utilities
from .forms import StoreRegisterForm, ProductForm
from flw_module.forms import AccountDetailForm
from flw_module.models import AccountDetail
from flw_module.utilities import flw_subaccount
from factory import db
from users_module.forms import ProfileForm
from .utilities import can_edit_product, currency_options, latest_stores

# ---------- Declaring the blueprint ----------
shop = Blueprint('shop', __name__, template_folder='templates')

# Template accessible variables
shop.add_app_template_global(can_edit_product)
shop.add_app_template_global(currency_options)
shop.add_app_template_global(latest_stores)


@shop.before_request
def before_request():
    ''' Make sure that the currency is always known '''
    if not (request.cookies.get('iso_code')):
        response = make_response(redirect(request.path))
        if (current_app.config['PRODUCT_PRICING'].split('-')[0]
                not in ['localize', 'localize_market']):
            code = current_app.config['PRODUCT_PRICING']
        else:
            try:
                code = get('https://ipapi.co/currency/').text