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)
Example #6
0
    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)