<s> from flask import Blueprint , Response , request , g , current_app , url_for , safe_join , make_response <EOL> from flask import render_template , redirect <EOL> from jinja2 import Template <EOL> import json , re <EOL> from functools import wraps <EOL> import sys <EOL> import traceback <EOL> from . . workspace import Workspace , SLICER_INFO_KEYS <EOL> from . . cells import Cell , cut_from_dict <EOL> from . . browser import SPLIT_DIMENSION_NAME <EOL> from . . errors import * <EOL> from . . formatters import JSONLinesGenerator , csv_generator <EOL> from . . import ext <EOL> from . logging import configured_request_log_handlers , RequestLogger <EOL> from . logging import AsyncRequestLogger <EOL> from . utils import * <EOL> from . errors import * <EOL> from . decorators import * <EOL> from . local import * <EOL> from . auth import NotAuthenticated <EOL> from collections import OrderedDict <EOL> from cubes import __version__ <EOL> try : <EOL> import cubes_search <EOL> except ImportError : <EOL> cubes_search = None <EOL> __all__ = ( <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" <EOL> ) <EOL> API_VERSION = <NUM_LIT:2> <EOL> CORS_MAX_AGE = <NUM_LIT> <EOL> slicer = Blueprint ( "<STR_LIT>" , __name__ , template_folder = "<STR_LIT>" , static_folder = "<STR_LIT>" ) <EOL> def _store_option ( config , option , default , type_ = None , allowed = None , <EOL> section = "<STR_LIT>" ) : <EOL> """<STR_LIT>""" <EOL> if config . has_option ( section , option ) : <EOL> if type_ == "<STR_LIT:bool>" : <EOL> value = config . getboolean ( section , option ) <EOL> elif type_ == "<STR_LIT:int>" : <EOL> value = config . getint ( section , option ) <EOL> else : <EOL> value = config . get ( section , option ) <EOL> else : <EOL> value = default <EOL> if allowed and value not in allowed : <EOL> raise ConfigurationError ( "<STR_LIT>" <EOL> % ( value , option ) ) <EOL> setattr ( current_app . slicer , option , value ) <EOL> @ slicer . record_once <EOL> def initialize_slicer ( state ) : <EOL> """<STR_LIT>""" <EOL> with state . app . app_context ( ) : <EOL> config = state . options [ "<STR_LIT>" ] <EOL> config = read_server_config ( config ) <EOL> params = CustomDict ( ) <EOL> current_app . slicer = params <EOL> current_app . slicer . config = config <EOL> if "<STR_LIT>" in state . options : <EOL> _options = { "<STR_LIT>" : state . options [ "<STR_LIT>" ] } <EOL> else : <EOL> _options = { } <EOL> if not hasattr ( current_app , '<STR_LIT>' ) : <EOL> current_app . cubes_workspace = Workspace ( config , ** _options ) <EOL> _store_option ( config , "<STR_LIT>" , False , "<STR_LIT:bool>" ) <EOL> _store_option ( config , "<STR_LIT>" , <NUM_LIT:1000> , "<STR_LIT:int>" ) <EOL> _store_option ( config , "<STR_LIT>" , False , "<STR_LIT:bool>" ) <EOL> _store_option ( config , "<STR_LIT>" , None , "<STR_LIT:str>" ) <EOL> _store_option ( config , "<STR_LIT>" , None , "<STR_LIT:str>" ) <EOL> _store_option ( config , "<STR_LIT>" , "<STR_LIT:none>" ) <EOL> method = current_app . slicer . authentication <EOL> if method is None or method == "<STR_LIT:none>" : <EOL> current_app . slicer . authenticator = None <EOL> else : <EOL> if config . has_section ( "<STR_LIT>" ) : <EOL> options = dict ( config . items ( "<STR_LIT>" ) ) <EOL> else : <EOL> options = { } <EOL> current_app . slicer . authenticator = ext . authenticator ( method , <EOL> ** options ) <EOL> logger . debug ( "<STR_LIT>" % ( method or "<STR_LIT:none>" ) ) <EOL> if not current_app . slicer . authenticator and workspace . authorizer : <EOL> logger . warn ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> handlers = configured_request_log_handlers ( config ) <EOL> if config . has_option ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> async_logging = config . getboolean ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> else : <EOL> async_logging = False <EOL> if async_logging : <EOL> current_app . slicer . request_logger = AsyncRequestLogger ( handlers ) <EOL> else : <EOL> current_app . slicer . request_logger = RequestLogger ( handlers ) <EOL> @ slicer . before_request <EOL> def process_common_parameters ( ) : <EOL> g . json_record_limit = current_app . slicer . json_record_limit <EOL> if "<STR_LIT>" in request . args : <EOL> g . prettyprint = str_to_bool ( request . args . get ( "<STR_LIT>" ) ) <EOL> else : <EOL> g . prettyprint = current_app . slicer . prettyprint <EOL> @ slicer . before_request <EOL> def prepare_authorization ( ) : <EOL> if current_app . slicer . authenticator : <EOL> try : <EOL> identity = current_app . slicer . authenticator . authenticate ( request ) <EOL> except NotAuthenticated as e : <EOL> raise NotAuthenticatedError <EOL> else : <EOL> identity = None <EOL> g . auth_identity = identity <EOL> @ slicer . errorhandler ( UserError ) <EOL> def user_error_handler ( e ) : <EOL> error_type = e . __class__ . error_type <EOL> error = OrderedDict ( ) <EOL> error [ "<STR_LIT:error>" ] = error_type <EOL> error [ "<STR_LIT:message>" ] = str ( e ) <EOL> if hasattr ( e , "<STR_LIT>" ) and e . hint : <EOL> error [ "<STR_LIT>" ] = e . hint <EOL> if hasattr ( e , "<STR_LIT>" ) : <EOL> error . update ( e . to_dict ( ) ) <EOL> code = server_error_codes . get ( error_type , <NUM_LIT> ) <EOL> return jsonify ( error ) , code <EOL> @ slicer . errorhandler ( <NUM_LIT> ) <EOL> def page_not_found ( e ) : <EOL> error = { <EOL> "<STR_LIT:error>" : "<STR_LIT>" , <EOL> "<STR_LIT:message>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> } <EOL> return jsonify ( error ) , <NUM_LIT> <EOL> @ slicer . errorhandler ( InternalError ) <EOL> def server_error ( e ) : <EOL> ( exc_type , exc_value , exc_traceback ) = sys . exc_info ( ) <EOL> exc_name = exc_type . __name__ <EOL> logger . error ( "<STR_LIT>" . format ( exc_name , exc_value ) ) <EOL> tb = traceback . format_exception ( exc_type , exc_value , <EOL> exc_traceback ) <EOL> logger . debug ( "<STR_LIT>" . format ( "<STR_LIT>" . join ( tb ) ) ) <EOL> error = { <EOL> "<STR_LIT:error>" : "<STR_LIT>" , <EOL> "<STR_LIT:message>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> } <EOL> return jsonify ( error ) , <NUM_LIT> <EOL> @ slicer . route ( "<STR_LIT:/>" ) <EOL> def show_index ( ) : <EOL> info = get_info ( ) <EOL> has_about = any ( key in info for key in SLICER_INFO_KEYS ) <EOL> return render_template ( "<STR_LIT>" , <EOL> has_about = has_about , <EOL> ** info ) <EOL> @ slicer . route ( "<STR_LIT>" ) <EOL> def show_version ( ) : <EOL> info = { <EOL> "<STR_LIT:version>" : __version__ , <EOL> "<STR_LIT>" : __version__ , <EOL> "<STR_LIT>" : API_VERSION <EOL> } <EOL> return jsonify ( info ) <EOL> def get_info ( ) : <EOL> if workspace . info : <EOL> info = OrderedDict ( workspace . info ) <EOL> else : <EOL> info = OrderedDict ( ) <EOL> info [ "<STR_LIT>" ] = current_app . slicer . json_record_limit <EOL> info [ "<STR_LIT>" ] = __version__ <EOL> info [ "<STR_LIT>" ] = workspace . calendar . timezone_name <EOL> info [ "<STR_LIT>" ] = workspace . calendar . first_weekday <EOL> info [ "<STR_LIT>" ] = API_VERSION <EOL> authinfo = { } <EOL> authinfo [ "<STR_LIT:type>" ] = ( current_app . slicer . authentication or "<STR_LIT:none>" ) <EOL> if g . auth_identity : <EOL> authinfo [ '<STR_LIT>' ] = g . auth_identity <EOL> if current_app . slicer . authenticator : <EOL> ainfo = current_app . slicer . authenticator . info_dict ( request ) <EOL> authinfo . update ( ainfo ) <EOL> info [ '<STR_LIT>' ] = authinfo <EOL> return info <EOL> @ slicer . route ( "<STR_LIT>" ) <EOL> def show_info ( ) : <EOL> return jsonify ( get_info ( ) ) <EOL> @ slicer . route ( "<STR_LIT>" ) <EOL> def list_cubes ( ) : <EOL> cube_list = workspace . list_cubes ( g . auth_identity ) <EOL> return jsonify ( cube_list ) <EOL> @ slicer . route ( "<STR_LIT>" ) <EOL> @ requires_cube <EOL> def cube_model ( cube_name ) : <EOL> if workspace . authorizer : <EOL> hier_limits = workspace . authorizer . hierarchy_limits ( g . auth_identity , <EOL> cube_name ) <EOL> else : <EOL> hier_limits = None <EOL> response = g . cube . to_dict ( expand_dimensions = True , <EOL> with_mappings = False , <EOL> full_attribute_names = True , <EOL> create_label = True , <EOL> hierarchy_limits = hier_limits ) <EOL> response [ "<STR_LIT>" ] = workspace . cube_features ( g . cube ) <EOL> return jsonify ( response ) <EOL> @ slicer . route ( "<STR_LIT>" ) <EOL> @ requires_browser <EOL> @ log_request ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> def aggregate ( cube_name ) : <EOL> cube = g . cube <EOL> output_format = validated_parameter ( request . args , "<STR_LIT>" , <EOL> values = [ "<STR_LIT>" , "<STR_LIT>" ] , <EOL> default = "<STR_LIT>" ) <EOL> header_type = validated_parameter ( request . args , "<STR_LIT>" , <EOL> values = [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT:none>" ] , <EOL> default = "<STR_LIT>" ) <EOL> fields_str = request . args . get ( "<STR_LIT>" ) <EOL> if fields_str : <EOL> fields = fields_str . lower ( ) . split ( '<STR_LIT:U+002C>' ) <EOL> else : <EOL> fields = None <EOL> aggregates = [ ] <EOL> for agg in request . args . getlist ( "<STR_LIT>" ) or [ ] : <EOL> aggregates += agg . split ( "<STR_LIT:|>" ) <EOL> drilldown = [ ] <EOL> ddlist = request . args . getlist ( "<STR_LIT>" ) <EOL> if ddlist : <EOL> for ddstring in ddlist : <EOL> drilldown += ddstring . split ( "<STR_LIT:|>" ) <EOL> prepare_cell ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> result = g . browser . aggregate ( g . cell , <EOL> aggregates = aggregates , <EOL> drilldown = drilldown , <EOL> split = g . split , <EOL> page = g . page , <EOL> page_size = g . page_size , <EOL> order = g . order ) <EOL> if current_app . slicer . hide_private_cuts : <EOL> result . cell = result . cell . public_cell ( ) <EOL> if output_format == "<STR_LIT>" : <EOL> return jsonify ( result ) <EOL> elif output_format != "<STR_LIT>" : <EOL> raise RequestError ( "<STR_LIT>" % output_format ) <EOL> if header_type == "<STR_LIT>" : <EOL> header = result . labels <EOL> elif header_type == "<STR_LIT>" : <EOL> header = [ ] <EOL> for l in result . labels : <EOL> if l == SPLIT_DIMENSION_NAME : <EOL> header . append ( '<STR_LIT>' ) <EOL> else : <EOL> header += [ attr . label or attr . name for attr in cube . get_attributes ( [ l ] , aggregated = True ) ] <EOL> else : <EOL> header = None <EOL> fields = result . labels <EOL> generator = csv_generator ( result , <EOL> fields , <EOL> include_header = bool ( header ) , <EOL> header = header ) <EOL> headers = { "<STR_LIT>" : '<STR_LIT>' } <EOL> return Response ( generator , <EOL> mimetype = '<STR_LIT>' , <EOL> headers = headers ) <EOL> @ slicer . route ( "<STR_LIT>" ) <EOL> @ requires_browser <EOL> @ log_request ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> def cube_facts ( cube_name ) : <EOL> fields_str = request . args . get ( "<STR_LIT>" ) <EOL> if fields_str : <EOL> fields = fields_str . split ( '<STR_LIT:U+002C>' ) <EOL> else : <EOL> fields = None <EOL> if fields : <EOL> attributes = g . cube . get_attributes ( fields ) <EOL> else : <EOL> attributes = g . cube . all_fact_attributes <EOL> fields = [ attr . ref for attr in attributes ] <EOL> facts = g . browser . facts ( g . cell , <EOL> fields = fields , <EOL> order = g . order , <EOL> page = g . page , <EOL> page_size = g . page_size ) <EOL> fields . insert ( <NUM_LIT:0> , g . cube . key or "<STR_LIT:id>" ) <EOL> labels = [ attr . label or attr . name for attr in attributes ] <EOL> labels . insert ( <NUM_LIT:0> , g . cube . key or "<STR_LIT:id>" ) <EOL> return formatted_response ( facts , fields , labels ) <EOL> @ slicer . route ( "<STR_LIT>" ) <EOL> @ requires_browser <EOL> def cube_fact ( cube_name , fact_id ) : <EOL> fact = g . browser . fact ( fact_id ) <EOL> if fact : <EOL> return jsonify ( fact ) <EOL> else : <EOL> raise NotFoundError ( fact_id , "<STR_LIT>" , <EOL> message = "<STR_LIT>" % fact_id ) <EOL> @ slicer . route ( "<STR_LIT>" ) <EOL> @ requires_browser <EOL> @ log_request ( "<STR_LIT>" ) <EOL> def cube_members ( cube_name , dimension_name ) : <EOL> depth = request . args . get ( "<STR_LIT>" ) <EOL> level = request . args . get ( "<STR_LIT>" ) <EOL> if depth and level : <EOL> raise RequestError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> if depth : <EOL> try : <EOL> depth = int ( depth ) <EOL> except ValueError : <EOL> raise RequestError ( "<STR_LIT>" ) <EOL> try : <EOL> dimension = g . cube . dimension ( dimension_name ) <EOL> except KeyError : <EOL> raise NotFoundError ( dimension_name , "<STR_LIT>" , <EOL> message = "<STR_LIT>" % dimension_name ) <EOL> hier_name = request . args . get ( "<STR_LIT>" ) <EOL> hierarchy = dimension . hierarchy ( hier_name ) <EOL> if not depth and not level : <EOL> depth = len ( hierarchy ) <EOL> elif level : <EOL> depth = hierarchy . level_index ( level ) + <NUM_LIT:1> <EOL> values = g . browser . members ( g . cell , <EOL> dimension , <EOL> depth = depth , <EOL> hierarchy = hierarchy , <EOL> page = g . page , <EOL> page_size = g . page_size ) <EOL> result = { <EOL> "<STR_LIT>" : dimension . name , <EOL> "<STR_LIT>" : hierarchy . name , <EOL> "<STR_LIT>" : len ( hierarchy ) if depth is None else depth , <EOL> "<STR_LIT:data>" : values <EOL> } <EOL> attributes = [ ] <EOL> for level in hierarchy . levels_for_depth ( depth ) : <EOL> attributes += level . attributes <EOL> fields = [ attr . ref for attr in attributes ] <EOL> labels = [ attr . label or attr . name for attr in attributes ] <EOL> return formatted_response ( result , fields , labels , iterable = values ) <EOL> @ slicer . route ( "<STR_LIT>" ) <EOL> @ requires_browser <EOL> def cube_cell ( cube_name ) : <EOL> details = g . browser . cell_details ( g . cell ) <EOL> if not g . cell : <EOL> g . cell = Cell ( g . cube ) <EOL> cell_dict = g . cell . to_dict ( ) <EOL> for cut , detail in zip ( cell_dict [ "<STR_LIT>" ] , details ) : <EOL> cut [ "<STR_LIT>" ] = detail <EOL> return jsonify ( cell_dict ) <EOL> @ slicer . route ( "<STR_LIT>" , methods = [ "<STR_LIT:GET>" , "<STR_LIT:POST>" ] ) <EOL> @ requires_browser <EOL> def cube_report ( cube_name ) : <EOL> report_request = json . loads ( request . data ) <EOL> try : <EOL> queries = report_request [ "<STR_LIT>" ] <EOL> except KeyError : <EOL> raise RequestError ( "<STR_LIT>" ) <EOL> cell_cuts = report_request . get ( "<STR_LIT>" ) <EOL> if cell_cuts : <EOL> cuts = [ cut_from_dict ( cut ) for cut in cell_cuts ] <EOL> cell = Cell ( g . cube , cuts ) <EOL> logger . info ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> if workspace . authorizer : <EOL> cell = workspace . authorizer . restricted_cell ( g . auth_identity , <EOL> cube = g . cube , <EOL> cell = cell ) <EOL> else : <EOL> if not g . cell : <EOL> cell = Cell ( g . cube ) <EOL> else : <EOL> cell = g . cell <EOL> result = g . browser . report ( cell , queries ) <EOL> return jsonify ( result ) <EOL> @ slicer . route ( "<STR_LIT>" ) <EOL> def cube_search ( cube_name ) : <EOL> config = current_app . config <EOL> if config . has_section ( "<STR_LIT>" ) : <EOL> options = dict ( config . items ( "<STR_LIT>" ) ) <EOL> engine_name = options . pop ( "<STR_LIT>" ) <EOL> else : <EOL> raise ConfigurationError ( "<STR_LIT>" ) <EOL> logger . debug ( "<STR_LIT>" % engine_name ) <EOL> search_engine = cubes_search . create_searcher ( engine_name , <EOL> browser = g . browser , <EOL> locales = g . locales , <EOL> ** options ) <EOL> dimension = request . args . get ( "<STR_LIT>" ) <EOL> if not dimension : <EOL> raise RequestError ( "<STR_LIT>" ) <EOL> query = request . args . get ( "<STR_LIT>" ) <EOL> if not query : <EOL> raise RequestError ( "<STR_LIT>" ) <EOL> locale = g . locale or g . locales [ <NUM_LIT:0> ] <EOL> logger . debug ( "<STR_LIT>" <EOL> % ( query , dimension , locale ) ) <EOL> search_result = search_engine . search ( query , dimension , locale = locale ) <EOL> result = { <EOL> "<STR_LIT>" : search_result . dimension_matches ( dimension ) , <EOL> "<STR_LIT>" : dimension , <EOL> "<STR_LIT>" : search_result . total_found , <EOL> "<STR_LIT>" : locale <EOL> } <EOL> if search_result . error : <EOL> result [ "<STR_LIT:error>" ] = search_result . error <EOL> if search_result . warning : <EOL> result [ "<STR_LIT>" ] = search_result . warning <EOL> return jsonify ( result ) <EOL> @ slicer . route ( "<STR_LIT>" ) <EOL> def logout ( ) : <EOL> if current_app . slicer . authenticator : <EOL> return current_app . slicer . authenticator . logout ( request , g . auth_identity ) <EOL> else : <EOL> return "<STR_LIT>" <EOL> _VIS_CONFIG_PATTERN = re . compile ( r"<STR_LIT>" ) <EOL> _VIS_CONFIG_SCRIPT_TEMPLATE = Template ( u"""<STR_LIT>""" ) <EOL> @ slicer . route ( "<STR_LIT>" ) <EOL> @ slicer . route ( "<STR_LIT>" ) <EOL> def get_visualizer ( ) : <EOL> viz = current_app . slicer . visualizer <EOL> if viz == "<STR_LIT:default>" : <EOL> with open ( safe_join ( slicer . static_folder , '<STR_LIT>' ) , '<STR_LIT:rb>' ) as indexfd : <EOL> index_contents = indexfd . read ( ) . decode ( '<STR_LIT:utf8>' ) <EOL> index_contents = _VIS_CONFIG_PATTERN . sub ( _VIS_CONFIG_SCRIPT_TEMPLATE . render ( serverUrl = url_for ( '<STR_LIT>' , _external = True ) ) , index_contents ) <EOL> return make_response ( index_contents ) <EOL> elif viz : <EOL> return redirect ( viz ) <EOL> else : <EOL> raise PageNotFoundError ( "<STR_LIT>" ) <EOL> @ slicer . after_request <EOL> def add_cors_headers ( response ) : <EOL> """<STR_LIT>""" <EOL> origin = current_app . slicer . allow_cors_origin <EOL> if origin and len ( origin ) : <EOL> if request . method == '<STR_LIT>' : <EOL> response . headers [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> if origin == '<STR_LIT:*>' : <EOL> response . headers [ '<STR_LIT>' ] = request . headers . get ( '<STR_LIT>' , origin ) <EOL> else : <EOL> response . headers [ '<STR_LIT>' ] = origin <EOL> response . headers [ '<STR_LIT>' ] = '<STR_LIT:true>' <EOL> response . headers [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> response . headers [ '<STR_LIT>' ] = CORS_MAX_AGE <EOL> return response </s>
