def testDecodeDateTime(self): """Test that a RFC 3339 datetime string is decoded properly.""" for datetime_string, datetime_vals in ( ('2012-09-30T15:31:50.262', (2012, 9, 30, 15, 31, 50, 262000)), ('2012-09-30T15:31:50', (2012, 9, 30, 15, 31, 50, 0))): decoded = util.decode_datetime(datetime_string) expected = datetime.datetime(*datetime_vals) self.assertEquals(expected, decoded)
def decode_field(self, field, value): """Decode a JSON value to a python value. Args: field: A ProtoRPC field instance. value: A serialized JSON value. Return: A Python value compatible with field. """ if isinstance(field, messages.EnumField): try: return field.type(value) except TypeError: raise messages.DecodeError( 'Invalid enum value "%s"' % (value or '')) elif isinstance(field, messages.BytesField): try: return base64.b64decode(value) except (binascii.Error, TypeError) as err: raise messages.DecodeError('Base64 decoding error: %s' % err) elif isinstance(field, message_types.DateTimeField): try: return util.decode_datetime(value) except ValueError as err: raise messages.DecodeError(err) elif (isinstance(field, messages.MessageField) and issubclass(field.type, messages.Message)): return self.__decode_dictionary(field.type, value) elif (isinstance(field, messages.FloatField) and isinstance(value, (six.integer_types, six.string_types))): try: return float(value) except: # pylint:disable=bare-except pass elif (isinstance(field, messages.IntegerField) and isinstance(value, six.string_types)): try: return int(value) except: # pylint:disable=bare-except pass return value
def decode_field(self, field, value): """Decode a JSON value to a python value. Args: field: A ProtoRPC field instance. value: A serialized JSON value. Return: A Python value compatible with field. """ if isinstance(field, messages.EnumField): try: return field.type(value) except TypeError: raise messages.DecodeError('Invalid enum value "%s"' % (value or '')) elif isinstance(field, messages.BytesField): try: return base64.b64decode(value) except (binascii.Error, TypeError) as err: raise messages.DecodeError('Base64 decoding error: %s' % err) elif isinstance(field, message_types.DateTimeField): try: return util.decode_datetime(value) except ValueError as err: raise messages.DecodeError(err) elif (isinstance(field, messages.MessageField) and issubclass(field.type, messages.Message)): return self.__decode_dictionary(field.type, value) elif (isinstance(field, messages.FloatField) and isinstance(value, (six.integer_types, six.string_types))): try: return float(value) except: # pylint:disable=bare-except pass elif (isinstance(field, messages.IntegerField) and isinstance(value, six.string_types)): try: return int(value) except: # pylint:disable=bare-except pass return value
def testDateTimeTimeZones(self): """Test that a datetime string with a timezone is decoded correctly.""" tests = ( ('2012-09-30T15:31:50.262-06:00', (2012, 9, 30, 15, 31, 50, 262000, util.TimeZoneOffset(-360))), ('2012-09-30T15:31:50.262+01:30', (2012, 9, 30, 15, 31, 50, 262000, util.TimeZoneOffset(90))), ('2012-09-30T15:31:50+00:05', (2012, 9, 30, 15, 31, 50, 0, util.TimeZoneOffset(5))), ('2012-09-30T15:31:50+00:00', (2012, 9, 30, 15, 31, 50, 0, util.TimeZoneOffset(0))), ('2012-09-30t15:31:50-00:00', (2012, 9, 30, 15, 31, 50, 0, util.TimeZoneOffset(0))), ('2012-09-30t15:31:50z', (2012, 9, 30, 15, 31, 50, 0, util.TimeZoneOffset(0))), ('2012-09-30T15:31:50-23:00', (2012, 9, 30, 15, 31, 50, 0, util.TimeZoneOffset(-1380)))) for datetime_string, datetime_vals in tests: decoded = util.decode_datetime(datetime_string) expected = datetime.datetime(*datetime_vals) self.assertEquals(expected, decoded)
def testDecodeDateTimeWithTruncateTime(self): """Test that nanosec time is truncated with truncate_time flag.""" decoded = util.decode_datetime('2012-09-30T15:31:50.262343123', truncate_time=True) expected = datetime.datetime(2012, 9, 30, 15, 31, 50, 262343) self.assertEquals(expected, decoded)
def ObjectMetadataFromHeaders(headers): """Creates object metadata according to the provided headers. gsutil -h allows specifiying various headers (originally intended to be passed to boto in gsutil v3). For the JSON API to be compatible with this option, we need to parse these headers into gsutil_api Object fields. Args: headers: Dict of headers passed via gsutil -h Raises: ArgumentException if an invalid header is encountered. Returns: apitools Object with relevant fields populated from headers. """ obj_metadata = apitools_messages.Object() for header, value in headers.items(): if CACHE_CONTROL_REGEX.match(header): obj_metadata.cacheControl = value.strip() elif CONTENT_DISPOSITION_REGEX.match(header): obj_metadata.contentDisposition = value.strip() elif CONTENT_ENCODING_REGEX.match(header): obj_metadata.contentEncoding = value.strip() elif CONTENT_MD5_REGEX.match(header): obj_metadata.md5Hash = value.strip() elif CONTENT_LANGUAGE_REGEX.match(header): obj_metadata.contentLanguage = value.strip() elif CONTENT_TYPE_REGEX.match(header): if not value: obj_metadata.contentType = DEFAULT_CONTENT_TYPE else: obj_metadata.contentType = value.strip() elif CUSTOM_TIME_REGEX.match(header): obj_metadata.customTime = decode_datetime(value.strip()) elif GOOG_API_VERSION_REGEX.match(header): # API version is only relevant for XML, ignore and rely on the XML API # to add the appropriate version. continue elif GOOG_GENERATION_MATCH_REGEX.match(header): # Preconditions are handled elsewhere, but allow these headers through. continue elif GOOG_METAGENERATION_MATCH_REGEX.match(header): # Preconditions are handled elsewhere, but allow these headers through. continue else: custom_goog_metadata_match = CUSTOM_GOOG_METADATA_REGEX.match( header) custom_amz_metadata_match = CUSTOM_AMZ_METADATA_REGEX.match(header) custom_amz_header_match = CUSTOM_AMZ_HEADER_REGEX.match(header) header_key = None if custom_goog_metadata_match: header_key = custom_goog_metadata_match.group('header_key') elif custom_amz_metadata_match: header_key = custom_amz_metadata_match.group('header_key') elif custom_amz_header_match: # If we got here we are guaranteed by the prior statement that this is # not an x-amz-meta- header. header_key = (S3_HEADER_PREFIX + custom_amz_header_match.group('header_key')) if header_key: if header_key.lower() == 'x-goog-content-language': # Work around content-language being inserted into custom metadata. continue if not obj_metadata.metadata: obj_metadata.metadata = apitools_messages.Object.MetadataValue( ) if not obj_metadata.metadata.additionalProperties: obj_metadata.metadata.additionalProperties = [] obj_metadata.metadata.additionalProperties.append( apitools_messages.Object.MetadataValue.AdditionalProperty( key=header_key, value=value)) else: raise ArgumentException('Invalid header specified: %s:%s' % (header, value)) return obj_metadata