示例#1
0
def session():
    # Remove previous db
    if URI != ':memory:' and os.path.exists(URI):
        os.unlink(URI)

    with connect(URI, init=True):
        VersionCube.load(DATA)
        yield 'session'
示例#2
0
def register_app(app):
    app.register_blueprint(menger_app)
    # Force a non-readonly query to let table creation proceed
    with connect(app.config['MENGER_DATABASE'], init=True):
        pass
示例#3
0
def mng(method, ext):
    get_permission = current_app.config.get('MENGER_FILTER')
    filters = []
    msr_perm = {}
    if get_permission:
        perms = get_permission()
        filters = perms.get('drill', [])
        msr_perm = perms.get('measure', {})

    if method == 'info':
        spaces = []
        for space in iter_spaces():
            if space._name in msr_perm:
                mp = msr_perm[space._name]
                msr_info = [{
                    'name': m.name,
                    'label': m.label,
                } for m in space._measures if m.name in mp]
            else:
                msr_info = [{
                    'name': m.name,
                    'label': m.label,
                } for m in space._measures]
            space_info = {
                'name':
                space._name,
                'measures':
                msr_info,
                'dimensions': [{
                    'name': d.name,
                    'label': d.label,
                    'levels': [l.label for l in d.levels.values()],
                } for d in space._dimensions],
                'label':
                space._label,
            }
            spaces.append(space_info)

        return json.jsonify(spaces=spaces)

    query = expand_query(method)
    spc_name = query.get('space')

    # Not cached to avoid trashing other queries
    if method == 'search':
        with connect(current_app.config['MENGER_DATABASE']):
            spc = get_space(spc_name)
            if not spc:
                return ('space "%s" not found' % spc_name, 404)

            name = query.get('dimension')
            if not hasattr(spc, name):
                return ('space "%s" has not dimension %s' % (spc_name, name),
                        404)
            dim = getattr(spc, name)
            res = list(dim.search(query['value'], int(query['max_depth'])))
            return json.jsonify(data=res)

    # Build unique id for query
    query_string = json.dumps(sorted(query.items()))
    h = md5(json.dumps(query_string).encode() + ext.encode())
    if filters:
        filters_str = str(sorted(filters)).encode()
        h.update(filters_str)
    qid = h.hexdigest()

    # Return cached value if any
    cached_value = fs_cache.get(qid)
    if cached_value is not None:
        resp = current_app.response_class(mimetype='application/json', )
        accept_encoding = request.headers.get('Accept-Encoding', '')
        if 'gzip' not in accept_encoding.lower():
            resp.set_data(gzip.decompress(cached_value))
        else:
            resp.headers['Content-Encoding'] = 'gzip'
            resp.set_data(cached_value)
        return resp

    res = {}
    if method == 'drill':
        with connect(current_app.config['MENGER_DATABASE']):
            spc = get_space(spc_name)
            if not spc:
                return ('space "%s" not found' % spc_name, 404)

            name = query.get('dimension')
            if not hasattr(spc, name):
                return ('space "%s" has not dimension %s' % (spc_name, name),
                        404)
            dim = getattr(spc, name)
            value = tuple(query.get('value', []))
            data = list(dim.drill(value))
            data.extend(dim.aliases(value))
            offset = len(value)
            mk_label = lambda x: dim.format(
                value + (x, ), fmt_type='txt', offset=offset)
            res['data'] = [(d, mk_label(d)) for d in data]

    elif method == 'dice':
        with connect(current_app.config['MENGER_DATABASE']):
            # Add user filters to the permission one
            query_filters = query.get('filters', [])
            measures = query['measures']
            spc_name = measures[0].split('.')[0]
            spc = get_space(spc_name)
            for dim_name, filter_val, depth in query_filters:
                dim = getattr(spc, dim_name)
                coord = (None, ) * (depth - 1) + (filter_val, )
                filters.append((dim_name, list(dim.glob(coord))))
            try:
                res = do_dice(query, filters, ext)
            except LimitException as e:
                return json.jsonify(error='Request too big (%s)' % str(e))

            if ext == 'xlsx':
                output_file = build_xlsx(res)
                attachment_filename = compute_filename(
                    current_app.config.get('MENGER_EXPORT_PATTERN', '%Y-%m%d'))
                return send_file(output_file,
                                 as_attachment=True,
                                 attachment_filename=attachment_filename)

    else:
        return ('Unknown method "%s"' % method, 404)

    if ext not in ('json', 'txt'):
        return 'Unknown extension "%s"' % ext, 404

    # Cache result
    json_res = json.dumps(res)
    zipped_res = gzip.compress(json_res.encode())
    fs_cache.set(qid, zipped_res)

    # Return response
    resp = current_app.response_class(mimetype='application/json', )
    accept_encoding = request.headers.get('Accept-Encoding', '')
    if 'gzip' not in accept_encoding.lower():
        resp.set_data(json_res)
    else:
        resp.headers['Content-Encoding'] = 'gzip'
        resp.set_data(zipped_res)
    return resp
示例#4
0
            'date': [2012, 7, 26],
            'author': ['John'],
            'words': 148,
            'signs': 743
        },
        {
            'date': [2012, 8, 7],
            'author': ['John'],
            'words': 34,
            'signs': 145
        },
        {
            'date': [2012, 8, 9],
            'author': ['Bill'],
            'words': 523,
            'signs': 2622
        },
    ])
    print('Top-level dice')
    pprint(list(Post.dice()))

    print('Per Month dice')
    pprint(list(Post.dice([Post.date['Month'], Post.average])))

    print('Date drill')
    pprint(list(Post.date.drill((2012, 8))))


with connect(':memory:'):
    run()