def parse_selection(cond, dataset): """ Convert a URL selection to 3 tokens. """ id_, op, other = re.split("(<=|>=|!=|=~|>|<|=)", cond) op = { "<=": operator.le, ">=": operator.ge, "!=": operator.ne, "=": operator.eq, ">": operator.gt, "<": operator.lt, }[op] try: names = [dataset] + id_.split(".") id_ = reduce(operator.getitem, names) except: id_ = expr_eval(id_) try: names = [dataset] + other.split(".") other = reduce(operator.getitem, names) except: other = expr_eval(other) return id_, op, other
def parse_selection(cond, dataset): """ Convert a URL selection to 3 tokens. """ id_, op, other = re.split('(<=|>=|!=|=~|>|<|=)', cond) op = { '<=': operator.le, '>=': operator.ge, '!=': operator.ne, '=': operator.eq, '>': operator.gt, '<': operator.lt }[op] try: names = [dataset] + id_.split('.') id_ = reduce(operator.getitem, names) except: id_ = expr_eval(id_) try: names = [dataset] + other.split('.') other = reduce(operator.getitem, names) except: other = expr_eval(other) return id_, op, other
def _attribute(self): type_ = self.consume('\w+') name = self.consume('[^\s]+') values = [] # One attribute for MLS data needs special handling since it breaks the # parser (doesn't meet the DAP 2.0 standard): if type_.lower() in ['string'] and name == 'PCF1': endstrindx = self.buffer.index('";') value = self.buffer[1:endstrindx] self.buffer = self.buffer[endstrindx+1:] self.consume(';') return name, value while not self.peek(';'): value = self.consume( r''' "" # empty attribute | # or ".*?[^\\]" # from quote up to an unquoted quote | # or [^;,]+ # up to semicolon or comma ''' ) if type_.lower() in ['string', 'url']: value = expr_eval(repr(value)) value = value.strip('"') elif type_.lower() == 'alias': # Support for Alias is not documented in the DAP spec. I based # this on the Java documentation from the OPeNDAP website at: # http://www.opendap.org/api/javaDocs/dods/dap/Alias.html # Check if we should start from the root dataset or from # the current item. if value.startswith('.'): tokens = value[1:].split('.') target = self.dataset else: tokens = value.split('.') target = self._target # Run over tokens to get the value. for token in tokens: if (isinstance(target, StructureType) and token in target): value = target = target[token] else: value = target = target.attributes.get(token) else: if value.lower() in ['nan', 'nan.']: value = numpy.NaN else: # Convert to proper type. This is specially important for floats, # since this preserves the resolution even though Python has no # difference between float 32 vs. 64. dtype = {'float64': 'd', 'float32': 'f', 'int32' : 'l', 'int16' : 'h', 'uint32' : 'L', 'uint16' : 'H', 'byte' : 'B'}[type_.lower()] if dtype in ['d', 'f']: value = array.array(dtype, [float(value)])[0] else: value = expr_eval(value) try: value = int(value) except OverflowError: value = long(value) values.append(value) if self.peek(','): self.consume(',') self.consume(';') if len(values) == 1: values = values[0] return name, values
def _attribute(self): type_ = self.consume('\w+') name = self.consume('[^\s]+') values = [] # One attribute for MLS data needs special handling since it breaks the # parser (doesn't meet the DAP 2.0 standard): if type_.lower() in ['string'] and name == 'PCF1': endstrindx = self.buffer.index('";') value = self.buffer[1:endstrindx] self.buffer = self.buffer[endstrindx + 1:] self.consume(';') return name, value while not self.peek(';'): value = self.consume(r''' "" # empty attribute | # or ".*?[^\\]" # from quote up to an unquoted quote | # or [^;,]+ # up to semicolon or comma ''') if type_.lower() in ['string', 'url']: value = expr_eval(repr(value)) value = value.strip('"') elif type_.lower() == 'alias': # Support for Alias is not documented in the DAP spec. I based # this on the Java documentation from the OPeNDAP website at: # http://www.opendap.org/api/javaDocs/dods/dap/Alias.html # Check if we should start from the root dataset or from # the current item. if value.startswith('.'): tokens = value[1:].split('.') target = self.dataset else: tokens = value.split('.') target = self._target # Run over tokens to get the value. for token in tokens: if (isinstance(target, StructureType) and token in target): value = target = target[token] else: value = target = target.attributes.get(token) else: if value.lower() in ['nan', 'nan.']: value = numpy.NaN else: # Convert to proper type. This is specially important for floats, # since this preserves the resolution even though Python has no # difference between float 32 vs. 64. dtype = { 'float64': 'd', 'float32': 'f', 'int32': 'l', 'int16': 'h', 'uint32': 'L', 'uint16': 'H', 'byte': 'B' }[type_.lower()] if dtype in ['d', 'f']: value = array.array(dtype, [float(value)])[0] else: value = expr_eval(value) try: value = int(value) except OverflowError: value = long(value) values.append(value) if self.peek(','): self.consume(',') self.consume(';') if len(values) == 1: values = values[0] return name, values