Example #1
0
def _parse_canonical_datetime(doc, json_options):
    """Decode a JSON datetime to python datetime.datetime."""
    dtm = doc["$date"]
    if len(doc) != 1:
        raise TypeError('Bad $date, extra field(s): %s' % (doc,))
    # mongoexport 2.6 and newer
    if isinstance(dtm, string_type):
        # Parse offset
        if dtm[-1] == 'Z':
            dt = dtm[:-1]
            offset = 'Z'
        elif dtm[-6] in ('+', '-') and dtm[-3] == ':':
            # (+|-)HH:MM
            dt = dtm[:-6]
            offset = dtm[-6:]
        elif dtm[-5] in ('+', '-'):
            # (+|-)HHMM
            dt = dtm[:-5]
            offset = dtm[-5:]
        elif dtm[-3] in ('+', '-'):
            # (+|-)HH
            dt = dtm[:-3]
            offset = dtm[-3:]
        else:
            dt = dtm
            offset = ''

        # Parse the optional factional seconds portion.
        dot_index = dt.rfind('.')
        microsecond = 0
        if dot_index != -1:
            microsecond = int(float(dt[dot_index:]) * 1000000)
            dt = dt[:dot_index]

        aware = datetime.datetime.strptime(
            dt, "%Y-%m-%dT%H:%M:%S").replace(microsecond=microsecond,
                                             tzinfo=utc)

        if offset and offset != 'Z':
            if len(offset) == 6:
                hours, minutes = offset[1:].split(':')
                secs = (int(hours) * 3600 + int(minutes) * 60)
            elif len(offset) == 5:
                secs = (int(offset[1:3]) * 3600 + int(offset[3:]) * 60)
            elif len(offset) == 3:
                secs = int(offset[1:3]) * 3600
            if offset[0] == "-":
                secs *= -1
            aware = aware - datetime.timedelta(seconds=secs)

        if json_options.tz_aware:
            if json_options.tzinfo:
                aware = aware.astimezone(json_options.tzinfo)
            return aware
        else:
            return aware.replace(tzinfo=None)
    return bson._millis_to_datetime(int(dtm), json_options)
def _parse_canonical_datetime(doc, json_options):
    """Decode a JSON datetime to python datetime.datetime."""
    dtm = doc["$date"]
    if len(doc) != 1:
        raise TypeError('Bad $date, extra field(s): %s' % (doc,))
    # mongoexport 2.6 and newer
    if isinstance(dtm, string_type):
        # Parse offset
        if dtm[-1] == 'Z':
            dt = dtm[:-1]
            offset = 'Z'
        elif dtm[-3] == ':':
            # (+|-)HH:MM
            dt = dtm[:-6]
            offset = dtm[-6:]
        elif dtm[-5] in ('+', '-'):
            # (+|-)HHMM
            dt = dtm[:-5]
            offset = dtm[-5:]
        elif dtm[-3] in ('+', '-'):
            # (+|-)HH
            dt = dtm[:-3]
            offset = dtm[-3:]
        else:
            dt = dtm
            offset = ''

        # Parse the optional factional seconds portion.
        dot_index = dt.rfind('.')
        microsecond = 0
        if dot_index != -1:
            microsecond = int(float(dt[dot_index:]) * 1000000)
            dt = dt[:dot_index]

        aware = datetime.datetime.strptime(
            dt, "%Y-%m-%dT%H:%M:%S").replace(microsecond=microsecond,
                                             tzinfo=utc)

        if offset and offset != 'Z':
            if len(offset) == 6:
                hours, minutes = offset[1:].split(':')
                secs = (int(hours) * 3600 + int(minutes) * 60)
            elif len(offset) == 5:
                secs = (int(offset[1:3]) * 3600 + int(offset[3:]) * 60)
            elif len(offset) == 3:
                secs = int(offset[1:3]) * 3600
            if offset[0] == "-":
                secs *= -1
            aware = aware - datetime.timedelta(seconds=secs)

        if json_options.tz_aware:
            if json_options.tzinfo:
                aware = aware.astimezone(json_options.tzinfo)
            return aware
        else:
            return aware.replace(tzinfo=None)
    return bson._millis_to_datetime(int(dtm), json_options)
Example #3
0
def model_object_hook(dic):
    """
    外键的格式化,统一解析成string
    :param dic:
    :return:
    """
    if dic.get('$oid'):
        return dic['$oid']
    elif dic.get('$date'):
        return _millis_to_datetime(
            dic['$date'], DEFAULT_CODEC_OPTIONS).strftime(settings.TIME_FORMAT)
    return dic
def _get_date(doc, json_options):
    dtm = doc["$date"]
    # mongoexport 2.6 and newer
    if isinstance(dtm, string_type):
        # Parse offset
        if dtm[-1] == 'Z':
            dt = dtm[:-1]
            offset = 'Z'
        elif dtm[-3] == ':':
            # (+|-)HH:MM
            dt = dtm[:-6]
            offset = dtm[-6:]
        elif dtm[-5] in ('+', '-'):
            # (+|-)HHMM
            dt = dtm[:-5]
            offset = dtm[-5:]
        elif dtm[-3] in ('+', '-'):
            # (+|-)HH
            dt = dtm[:-3]
            offset = dtm[-3:]
        else:
            dt = dtm
            offset = ''

        aware = datetime.datetime.strptime(
            dt, "%Y-%m-%dT%H:%M:%S.%f").replace(tzinfo=utc)

        if offset and offset != 'Z':
            if len(offset) == 6:
                hours, minutes = offset[1:].split(':')
                secs = (int(hours) * 3600 + int(minutes) * 60)
            elif len(offset) == 5:
                secs = (int(offset[1:3]) * 3600 + int(offset[3:]) * 60)
            elif len(offset) == 3:
                secs = int(offset[1:3]) * 3600
            if offset[0] == "-":
                secs *= -1
            aware = aware - datetime.timedelta(seconds=secs)

        if json_options.tz_aware:
            if json_options.tzinfo:
                aware = aware.astimezone(json_options.tzinfo)
            return aware
        else:
            return aware.replace(tzinfo=None)
    # mongoexport 2.6 and newer, time before the epoch (SERVER-15275)
    elif isinstance(dtm, collections.Mapping):
        millis = int(dtm["$numberLong"])
    # mongoexport before 2.6
    else:
        millis = int(dtm)
    return bson._millis_to_datetime(millis, json_options)
def object_hook(dct, json_options=DEFAULT_JSON_OPTIONS):
    if "$oid" in dct:
        return ObjectId(str(dct["$oid"]))
    if "$ref" in dct:
        return DBRef(dct["$ref"], dct["$id"], dct.get("$db", None))
    if "$date" in dct:
        dtm = dct["$date"]
        # mongoexport 2.6 and newer
        if isinstance(dtm, string_type):
            # Parse offset
            if dtm[-1] == 'Z':
                dt = dtm[:-1]
                offset = 'Z'
            elif dtm[-3] == ':':
                # (+|-)HH:MM
                dt = dtm[:-6]
                offset = dtm[-6:]
            elif dtm[-5] in ('+', '-'):
                # (+|-)HHMM
                dt = dtm[:-5]
                offset = dtm[-5:]
            elif dtm[-3] in ('+', '-'):
                # (+|-)HH
                dt = dtm[:-3]
                offset = dtm[-3:]
            else:
                dt = dtm
                offset = ''

            aware = datetime.datetime.strptime(
                dt, "%Y-%m-%dT%H:%M:%S.%f").replace(tzinfo=utc)

            if offset and offset != 'Z':
                if len(offset) == 6:
                    hours, minutes = offset[1:].split(':')
                    secs = (int(hours) * 3600 + int(minutes) * 60)
                elif len(offset) == 5:
                    secs = (int(offset[1:3]) * 3600 + int(offset[3:]) * 60)
                elif len(offset) == 3:
                    secs = int(offset[1:3]) * 3600
                if offset[0] == "-":
                    secs *= -1
                aware = aware - datetime.timedelta(seconds=secs)

            if json_options.tz_aware:
                if json_options.tzinfo:
                    aware = aware.astimezone(json_options.tzinfo)
                return aware
            else:
                return aware.replace(tzinfo=None)
        # mongoexport 2.6 and newer, time before the epoch (SERVER-15275)
        elif isinstance(dtm, collections.Mapping):
            millis = int(dtm["$numberLong"])
        # mongoexport before 2.6
        else:
            millis = int(dtm)
        return bson._millis_to_datetime(millis, json_options)
    if "$regex" in dct:
        flags = 0
        # PyMongo always adds $options but some other tools may not.
        for opt in dct.get("$options", ""):
            flags |= _RE_OPT_TABLE.get(opt, 0)
        return Regex(dct["$regex"], flags)
    if "$minKey" in dct:
        return MinKey()
    if "$maxKey" in dct:
        return MaxKey()
    if "$binary" in dct:
        if isinstance(dct["$type"], int):
            dct["$type"] = "%02x" % dct["$type"]
        subtype = int(dct["$type"], 16)
        if subtype >= 0xffffff80:  # Handle mongoexport values
            subtype = int(dct["$type"][6:], 16)
        data = base64.b64decode(dct["$binary"].encode())
        # special handling for UUID
        if subtype == OLD_UUID_SUBTYPE:
            if json_options.uuid_representation == CSHARP_LEGACY:
                return uuid.UUID(bytes_le=data)
            if json_options.uuid_representation == JAVA_LEGACY:
                data = data[7::-1] + data[:7:-1]
            return uuid.UUID(bytes=data)
        if subtype == UUID_SUBTYPE:
            return uuid.UUID(bytes=data)
        return Binary(data, subtype)
    if "$code" in dct:
        return Code(dct["$code"], dct.get("$scope"))
    if "$uuid" in dct:
        return uuid.UUID(dct["$uuid"])
    if "$undefined" in dct:
        return None
    if "$numberLong" in dct:
        return Int64(dct["$numberLong"])
    if "$timestamp" in dct:
        tsp = dct["$timestamp"]
        return Timestamp(tsp["t"], tsp["i"])
    if "$numberDecimal" in dct:
        return Decimal128(dct["$numberDecimal"])
    return dct
def object_hook(dct, json_options=DEFAULT_JSON_OPTIONS):
    if "$oid" in dct:
        return ObjectId(str(dct["$oid"]))
    if "$ref" in dct:
        return DBRef(dct["$ref"], dct["$id"], dct.get("$db", None))
    if "$date" in dct:
        dtm = dct["$date"]
        # mongoexport 2.6 and newer
        if isinstance(dtm, string_type):
            # Parse offset
            if dtm[-1] == 'Z':
                dt = dtm[:-1]
                offset = 'Z'
            elif dtm[-3] == ':':
                # (+|-)HH:MM
                dt = dtm[:-6]
                offset = dtm[-6:]
            elif dtm[-5] in ('+', '-'):
                # (+|-)HHMM
                dt = dtm[:-5]
                offset = dtm[-5:]
            elif dtm[-3] in ('+', '-'):
                # (+|-)HH
                dt = dtm[:-3]
                offset = dtm[-3:]
            else:
                dt = dtm
                offset = ''

            aware = datetime.datetime.strptime(
                dt, "%Y-%m-%dT%H:%M:%S.%f").replace(tzinfo=utc)

            if offset and offset != 'Z':
                if len(offset) == 6:
                    hours, minutes = offset[1:].split(':')
                    secs = (int(hours) * 3600 + int(minutes) * 60)
                elif len(offset) == 5:
                    secs = (int(offset[1:3]) * 3600 + int(offset[3:]) * 60)
                elif len(offset) == 3:
                    secs = int(offset[1:3]) * 3600
                if offset[0] == "-":
                    secs *= -1
                aware = aware - datetime.timedelta(seconds=secs)

            if json_options.tz_aware:
                if json_options.tzinfo:
                    aware = aware.astimezone(json_options.tzinfo)
                return aware
            else:
                return aware.replace(tzinfo=None)
        # mongoexport 2.6 and newer, time before the epoch (SERVER-15275)
        elif isinstance(dtm, collections.Mapping):
            millis = int(dtm["$numberLong"])
        # mongoexport before 2.6
        else:
            millis = int(dtm)
        return bson._millis_to_datetime(millis, json_options)
    if "$regex" in dct:
        flags = 0
        # PyMongo always adds $options but some other tools may not.
        for opt in dct.get("$options", ""):
            flags |= _RE_OPT_TABLE.get(opt, 0)
        return Regex(dct["$regex"], flags)
    if "$minKey" in dct:
        return MinKey()
    if "$maxKey" in dct:
        return MaxKey()
    if "$binary" in dct:
        if isinstance(dct["$type"], int):
            dct["$type"] = "%02x" % dct["$type"]
        subtype = int(dct["$type"], 16)
        if subtype >= 0xffffff80:  # Handle mongoexport values
            subtype = int(dct["$type"][6:], 16)
        data = base64.b64decode(dct["$binary"].encode())
        # special handling for UUID
        if subtype == OLD_UUID_SUBTYPE:
            if json_options.uuid_representation == CSHARP_LEGACY:
                return uuid.UUID(bytes_le=data)
            if json_options.uuid_representation == JAVA_LEGACY:
                data = data[7::-1] + data[:7:-1]
            return uuid.UUID(bytes=data)
        if subtype == UUID_SUBTYPE:
            return uuid.UUID(bytes=data)
        return Binary(data, subtype)
    if "$code" in dct:
        return Code(dct["$code"], dct.get("$scope"))
    if "$uuid" in dct:
        return uuid.UUID(dct["$uuid"])
    if "$undefined" in dct:
        return None
    if "$numberLong" in dct:
        return Int64(dct["$numberLong"])
    if "$timestamp" in dct:
        tsp = dct["$timestamp"]
        return Timestamp(tsp["t"], tsp["i"])
    return dct