def marsloader_func(request, *args, **kwargs): """MARS_loader (Modifying Arguments for the Result Set) adds arguments specifically meant to modify the result set (eg. limit, offset and order_by) """ check_safety() STATUS = 'status' # This should be abstracted # StatusName 'active' should always be available arg_list = [('limit', 100), ('offset', 0), ('order_by', '-created_at'), (STATUS, models.StatusName.objects.get(name='active'))] new_args = copy.copy(kwargs) rsm_arg_list = {} for arg in arg_list: rsm_arg_list[arg[0]] = arg[1] # All paths that end in a slash and have an HTTP method of GET will return a result set rsm_cand = request.method == 'GET' and request.META['PATH_INFO'][ -1] == '/' if rsm_cand: for rsm_arg, qdefault in rsm_arg_list.items(): if request.GET.has_key(rsm_arg): if rsm_arg == STATUS: try: new_args[rsm_arg] = models.StatusName.objects.get( name=request.GET[rsm_arg]) except models.StatusName.DoesNotExist: raise Http404 new_args[rsm_arg] = qdefault else: try: new_args[rsm_arg] = int(request.GET[rsm_arg]) except: new_args[rsm_arg] = request.GET[rsm_arg] else: new_args[rsm_arg] = qdefault # Check that the new arguments are all in func() if len(inspect.getargspec(func)) > 0: for new_arg in new_args.keys(): if new_arg not in inspect.getargspec(func)[0]: raise Exception("Missing arg " + new_arg + " in " + func.func_name) return func(request, **new_args)
def marsloader_func(request, *args, **kwargs): """MARS_loader (Modifying Arguments for the Result Set) adds arguments specifically meant to modify the result set (eg. limit, offset and order_by) """ check_safety() STATUS = 'status' # This should be abstracted # StatusName 'active' should always be available arg_list = [ ('limit', 100), ('offset', 0), ('order_by', '-created_at'), (STATUS, models.StatusName.objects.get(name='active'))] new_args = copy.copy(kwargs) rsm_arg_list = {} for arg in arg_list: rsm_arg_list[arg[0]] = arg[1] # All paths that end in a slash and have an HTTP method of GET will return a result set rsm_cand = request.method == 'GET' and request.META['PATH_INFO'][-1] == '/' if rsm_cand: for rsm_arg, qdefault in rsm_arg_list.items(): if request.GET.has_key(rsm_arg): if rsm_arg == STATUS: try: new_args[rsm_arg] = models.StatusName.objects.get(name=request.GET[rsm_arg]) except models.StatusName.DoesNotExist: raise Http404 new_args[rsm_arg] = qdefault else: try: new_args[rsm_arg] = int(request.GET[rsm_arg]) except: new_args[rsm_arg] = request.GET[rsm_arg] else: new_args[rsm_arg] = qdefault # Check that the new arguments are all in func() if len(inspect.getargspec(func)) > 0: for new_arg in new_args.keys(): if new_arg not in inspect.getargspec(func)[0]: raise Exception("Missing arg " + new_arg + " in " + func.func_name) return func(request, **new_args)
def paramloaded_func(request, **kwargs): """ A decorator for automatically loading URL-based parameters that are in standard form. """ DOCBOX = 'docbox' # SZ: Add pha docbox_list = ('carenet', 'record') # Init check_safety() new_args = copy.copy(kwargs) # immediately remove the double-underscore parameters for arg_name in new_args.keys(): if arg_name[:2] == "__": del new_args[arg_name] req_path = request.path_info.split('/') params_intersect = _get_params_intersection(new_args) docbox_obj, insert_docbox = _init_docbox(params) for qparam, qparam_rel in params_intersect.items(): # If the argument given is None then keep it as None if new_args[qparam] is None: new_args[qparam_rel[0]] = None del new_args[qparam] else: try: query_kwargs = {qparam_rel[2] : new_args[qparam]} res_obj = qparam_rel[1].objects.get(**query_kwargs) if qparam_rel[0] in docbox_list and insert_docbox: new_args[DOCBOX] = docbox_obj.set(res_obj) else: new_args[qparam_rel[0]] = res_obj del new_args[qparam] except Exception, e: raise Http404
def marsloader_func(request, *args, **kwargs): """MARS_loader (Modifying Arguments for the Result Set) adds arguments specifically meant to modify the result set (eg. limit, offset and order_by) 04-05-2011: Modified to Handle the New Query Interface New arguments are: group_by, aggregate_by, date_group, date_range, generic report_specific_filters. Also: No longer checks that the URL ends in a '/'. We assume that if you didn't want to call this function, you wouldn't have decorated the view with it. """ def parse_string(value): return value def parse_int(value): return int(value) def parse_status(value): return models.StatusName.objects.get(name=value) def parse_aggregate_by(value): operator, field = value.split('*') field = None if field == '' else field return {'operator': operator, 'field': field} def parse_date_range(value): field, start_date, end_date = value.split('*') start_date = None if start_date == '' else iso8601.parse_utc_date( start_date) end_date = None if end_date == '' else iso8601.parse_utc_date( end_date) return { 'field': field, 'start_date': start_date, 'end_date': end_date } def parse_date_group(value): field, time_incr = value.split('*') return {'field': field, 'time_incr': time_incr} check_safety() parse_map = { 'limit': parse_int, 'offset': parse_int, 'order_by': parse_string, 'status': parse_status, 'group_by': parse_string, 'aggregate_by': parse_aggregate_by, 'date_range': parse_date_range, 'date_group': parse_date_group, } ignore_map = {'response_format': True} # This should be abstracted # StatusName 'active' should always be available arg_defaults = { 'limit': 100, 'offset': 0, 'order_by': '-%s' % (DEFAULT_ORDERBY) if not request.GET.has_key('aggregate_by') or not query_api_support else None, 'status': models.StatusName.objects.get(name='active'), } query_api_defaults = { 'group_by': None, 'aggregate_by': None, 'date_range': None, 'date_group': None, } base_options = {} report_specific_filters = {} # set defaults base_options.update(arg_defaults) if query_api_support: base_options.update(query_api_defaults) base_options['filters'] = report_specific_filters for _arg, value in request.GET.iteritems(): arg = str(_arg) try: if parse_map.has_key(arg): base_options[arg] = parse_map[arg](value) elif ignore_map.has_key(arg): pass else: # might be field-specific query parameter, allow individual reports to type-check report_specific_filters[arg] = value except models.StatusName.DoesNotExist: raise Http404 except ValueError: return HttpResponseBadRequest( 'Argument %s must be formatted according to the Indivo Query API' % (arg)) # Check that the new query_options argument is in func() if len(inspect.getargspec(func)) > 0: if QUERY_OPTIONS_ARG not in inspect.getargspec(func)[0]: raise Exception("Missing arg " + QUERY_OPTIONS_ARG + " in " + func.func_name) # update args kwargs[QUERY_OPTIONS_ARG] = base_options # call the view return func(request, **kwargs)
def marsloader_func(request, *args, **kwargs): """MARS_loader (Modifying Arguments for the Result Set) adds arguments specifically meant to modify the result set (eg. limit, offset and order_by) 04-05-2011: Modified to Handle the New Query Interface New arguments are: group_by, aggregate_by, date_group, date_range, generic report_specific_filters. Also: No longer checks that the URL ends in a '/'. We assume that if you didn't want to call this function, you wouldn't have decorated the view with it. """ def parse_string(value): return value def parse_int(value): return int(value) def parse_status(value): return models.StatusName.objects.get(name=value) def parse_aggregate_by(value): operator, field = value.split('*') field = None if field == '' else field return {'operator':operator, 'field':field} def parse_date_range(value): field, start_date, end_date = value.split('*') start_date = None if start_date == '' else iso8601.parse_utc_date(start_date) end_date = None if end_date == '' else iso8601.parse_utc_date(end_date) return {'field':field, 'start_date':start_date, 'end_date':end_date} def parse_date_group(value): field, time_incr = value.split('*') return {'field':field, 'time_incr':time_incr} check_safety() parse_map = { 'limit': parse_int, 'offset': parse_int, 'order_by': parse_string, 'status': parse_status, 'group_by': parse_string, 'aggregate_by': parse_aggregate_by, 'date_range': parse_date_range, 'date_group': parse_date_group, } ignore_map = { 'response_format': True } # This should be abstracted # StatusName 'active' should always be available arg_defaults = { 'limit': 100, 'offset': 0, 'order_by': '-%s'%(DEFAULT_ORDERBY) if not request.GET.has_key('aggregate_by') or not query_api_support else None, 'status': models.StatusName.objects.get(name='active'), } query_api_defaults = { 'group_by': None, 'aggregate_by': None, 'date_range': None, 'date_group': None, } base_options = {} report_specific_filters = {} # set defaults base_options.update(arg_defaults) if query_api_support: base_options.update(query_api_defaults) base_options['filters'] = report_specific_filters for _arg, value in request.GET.iteritems(): arg = str(_arg) try: if parse_map.has_key(arg): base_options[arg] = parse_map[arg](value) elif ignore_map.has_key(arg): pass else: # might be field-specific query parameter, allow individual reports to type-check report_specific_filters[arg] = value except models.StatusName.DoesNotExist: raise Http404 except ValueError: return HttpResponseBadRequest('Argument %s must be formatted according to the Indivo Query API'%(arg)) # Check that the new query_options argument is in func() if len(inspect.getargspec(func)) > 0: if QUERY_OPTIONS_ARG not in inspect.getargspec(func)[0]: raise Exception("Missing arg " + QUERY_OPTIONS_ARG + " in " + func.func_name) # update args kwargs[QUERY_OPTIONS_ARG] = base_options # call the view return func(request, **kwargs)
def marsloader_func(request, *args, **kwargs): """MARS_loader (Modifying Arguments for the Result Set) adds arguments specifically meant to modify the result set (eg. limit, offset and order_by) 04-05-2011: Modified to Handle the New Query Interface New arguments are: group_by, aggregate_by, date_group, date_range, generic filters. Also: No longer checks that the URL ends in a '/'. We assume that if you didn't want to call this function, you wouldn't have decorated the view with it. """ check_safety() # This should be abstracted # StatusName 'active' should always be available arg_defaults = { 'limit': 100, 'offset': 0, 'order_by': '-%s'%(DEFAULT_ORDERBY) if not request.GET.has_key('aggregate_by') or not query_api_support else None, 'status': models.StatusName.objects.get(name='active'), } query_api_defaults = { 'group_by': None, 'aggregate_by': None, 'date_range': None, 'date_group': None, } # Every get paramater should be useful: otherwise we have to treat it as # an invalid filter new_args = copy.copy(kwargs) filters = {} for _arg, value in request.GET.iteritems(): arg = str(_arg) try: if arg == 'limit': new_args[arg] = int(value) elif arg == 'offset': new_args[arg] = int(value) elif arg == 'order_by': new_args[arg] = value elif arg == 'status': new_args[arg] = models.StatusName.objects.get(name=value) elif arg == 'group_by' and query_api_support: new_args[arg] = value elif arg == 'aggregate_by' and query_api_support: operator, field = value.split('*') field = None if field == '' else field new_args[arg] = {'operator':operator, 'field':field} elif arg == 'date_range' and query_api_support: field, start_date, end_date = value.split('*') start_date = None if start_date == '' else iso8601.parse_utc_date(start_date) end_date = None if end_date == '' else iso8601.parse_utc_date(end_date) new_args[arg] = {'field':field, 'start_date':start_date, 'end_date':end_date} elif arg == 'date_group' and query_api_support: field, time_incr = value.split('*') new_args[arg] = {'field':field, 'time_incr':time_incr} # We assume that all remaining parameters are field-specific query parameters # (i.e. 'lab_type=hematology') if this is a query_api call else: if query_api_support: # Don't do type-checking here: the individual report defines the types of filters filters[arg] = value except models.StatusName.DoesNotExist: raise Http404 except ValueError: return HttpResponseBadRequest('Argument %s must be formatted according to the Indivo Query API'%(arg)) if query_api_support: new_args['filters'] = filters # Add defaults for missing params for arg, default in arg_defaults.iteritems(): if not new_args.has_key(arg): new_args[arg] = default if query_api_support: for arg, default in query_api_defaults.iteritems(): if not new_args.has_key(arg): new_args[arg] = default # Check that the new arguments are all in func() if len(inspect.getargspec(func)) > 0: for new_arg in new_args.keys(): if new_arg not in inspect.getargspec(func)[0]: raise Exception("Missing arg " + new_arg + " in " + func.func_name) # call the view return func(request, **new_args)