示例#1
0
文件: __init__.py 项目: embr/nonce
    def _get_record(self, ipnum):
        """
        Populate location dict for converted IP.

        @param ipnum: Converted IP address
        @type ipnum: int
        @return: dict with country_code, country_code3, country_name,
            region, city, postal_code, latitude, longitude,
            dma_code, metro_code, area_code, region_name, time_zone
        @rtype: dict
        """
        seek_country = self._seek_country(ipnum)
        if seek_country == self._databaseSegments:
            return None

        read_length = (2 * self._recordLength - 1) * self._databaseSegments
        self._lock.acquire()
        self._filehandle.seek(seek_country + read_length, os.SEEK_SET)
        buf = self._filehandle.read(const.FULL_RECORD_LENGTH)
        self._lock.release()

        if PY3 and type(buf) is bytes:
            buf = buf.decode(ENCODING)

        record = {
            'dma_code': 0,
            'area_code': 0,
            'metro_code': '',
            'postal_code': ''
        }

        latitude = 0
        longitude = 0
        buf_pos = 0

        # Get country
        char = ord(buf[buf_pos])
        record['country_code'] = const.COUNTRY_CODES[char]
        record['country_code3'] = const.COUNTRY_CODES3[char]
        record['country_name'] = const.COUNTRY_NAMES[char]
        buf_pos += 1

        def get_data(buf, buf_pos):
            offset = buf_pos
            char = ord(buf[offset])
            while (char != 0):
                offset += 1
                char = ord(buf[offset])
            if offset > buf_pos:
                return (offset, buf[buf_pos:offset])
            return (offset, '')

        offset, record['region_name'] = get_data(buf, buf_pos)
        offset, record['city'] = get_data(buf, offset + 1)
        offset, record['postal_code'] = get_data(buf, offset + 1)
        buf_pos = offset + 1

        for j in range(3):
            char = ord(buf[buf_pos])
            buf_pos += 1
            latitude += (char << (j * 8))

        for j in range(3):
            char = ord(buf[buf_pos])
            buf_pos += 1
            longitude += (char << (j * 8))

        record['latitude'] = (latitude / 10000.0) - 180.0
        record['longitude'] = (longitude / 10000.0) - 180.0

        if self._databaseType == const.CITY_EDITION_REV1:
            dmaarea_combo = 0
            if record['country_code'] == 'US':
                for j in range(3):
                    char = ord(buf[buf_pos])
                    dmaarea_combo += (char << (j * 8))
                    buf_pos += 1

                record['dma_code'] = int(math.floor(dmaarea_combo / 1000))
                record['area_code'] = dmaarea_combo % 1000

        if record['dma_code'] in const.DMA_MAP:
            record['metro_code'] = const.DMA_MAP[record['dma_code']]

        params = (record['country_code'], record['region_name'])
        record['time_zone'] = time_zone_by_country_and_region(*params)

        return record
    def _get_record(self, ipnum):
        """
        Populate location dict for converted IP.

        @param ipnum: converted IP address
        @type ipnum: int
        @return: dict with country_code, country_code3, country_name,
            region, city, postal_code, latitude, longitude,
            dma_code, metro_code, area_code, region_name, time_zone
        @rtype: dict
        """
        seek_country = self._seek_country(ipnum)
        if seek_country == self._databaseSegments:
            return None

        record_pointer = seek_country + (2 * self._recordLength - 1) * self._databaseSegments

        self._filehandle.seek(record_pointer, os.SEEK_SET)
        record_buf = self._filehandle.read(const.FULL_RECORD_LENGTH)

        record = {}

        record_buf_pos = 0
        char = ord(record_buf[record_buf_pos])
        record['country_code'] = const.COUNTRY_CODES[char]
        record['country_code3'] = const.COUNTRY_CODES3[char]
        record['country_name'] = const.COUNTRY_NAMES[char]
        record_buf_pos += 1
        str_length = 0

        # get region
        char = ord(record_buf[record_buf_pos + str_length])
        while (char != 0):
            str_length += 1
            char = ord(record_buf[record_buf_pos + str_length])

        if str_length > 0:
            record['region_name'] = record_buf[record_buf_pos:record_buf_pos + str_length]

        record_buf_pos += str_length + 1
        str_length = 0

        # get city
        char = ord(record_buf[record_buf_pos + str_length])
        while (char != 0):
            str_length += 1
            char = ord(record_buf[record_buf_pos + str_length])

        if str_length > 0:
            record['city'] = record_buf[record_buf_pos:record_buf_pos + str_length]
        else:
            record['city'] = ''

        record_buf_pos += str_length + 1
        str_length = 0

        # get the postal code
        char = ord(record_buf[record_buf_pos + str_length])
        while (char != 0):
            str_length += 1
            char = ord(record_buf[record_buf_pos + str_length])

        if str_length > 0:
            record['postal_code'] = record_buf[record_buf_pos:record_buf_pos + str_length]
        else:
            record['postal_code'] = None

        record_buf_pos += str_length + 1
        str_length = 0

        latitude = 0
        longitude = 0
        for j in range(3):
            char = ord(record_buf[record_buf_pos])
            record_buf_pos += 1
            latitude += (char << (j * 8))

        record['latitude'] = (latitude / 10000.0) - 180.0

        for j in range(3):
            char = ord(record_buf[record_buf_pos])
            record_buf_pos += 1
            longitude += (char << (j * 8))

        record['longitude'] = (longitude / 10000.0) - 180.0

        if self._databaseType == const.CITY_EDITION_REV1:
            dmaarea_combo = 0
            if record['country_code'] == 'US':
                for j in range(3):
                    char = ord(record_buf[record_buf_pos])
                    record_buf_pos += 1
                    dmaarea_combo += (char << (j * 8))

                record['dma_code'] = int(math.floor(dmaarea_combo / 1000))
                record['area_code'] = dmaarea_combo % 1000
        else:
            record['dma_code'] = 0
            record['area_code'] = 0

        if 'dma_code' in record and record['dma_code'] in const.DMA_MAP:
            record['metro_code'] = const.DMA_MAP[record['dma_code']]
        else:
            record['metro_code'] = ''

        if 'country_code' in record:
            record['time_zone'] = time_zone_by_country_and_region(
                record['country_code'], record.get('region_name')) or ''
        else:
            record['time_zone'] = ''

        return record