Source code for upoints.cellid

#
# coding=utf-8
"""cellid - Imports OpenCellID data files"""
# Copyright © 2007-2014  James Rowe <jnrowe@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

import datetime
import logging

from operator import attrgetter

from upoints import (point, utils)


[docs]class Cell(point.Point): """Class for representing a cellular cite from OpenCellID.org_ .. versionadded:: 0.11.0 .. _OpenCellID.org: http://opencellid.org/ """ __slots__ = ('ident', 'mcc', 'mnc', 'lac', 'cellid', 'crange', 'samples', 'created', 'updated') def __init__(self, ident, latitude, longitude, mcc, mnc, lac, cellid, crange, samples, created, updated): """Initialise a new ``Cell`` object. :param int ident: OpenCellID database identifier :param float latitude: Cell's latitude :param float longitude: Cell's longitude :param int mcc: Cell's country code :param int mnc: Cell's network code :param int lac: Cell's local area code :param int cellid: Cell's identifier :param int crange: Cell's range :param int samples: Number of samples for the cell :param datetime.datetime created: Date the cell was first entered :param datetime.datetime updated: Date of the last update """ super(Cell, self).__init__(latitude, longitude) self.ident = ident self.mcc = mcc self.mnc = mnc self.lac = lac self.cellid = cellid self.crange = crange self.samples = samples self.created = created self.updated = updated def __str__(self): """OpenCellID.org-style location string. .. seealso:: :class:`point.Point` :rtype: ``str`` :return: OpenCellID.org-style string representation of ``Cell`` object """ return '%i,%.13f,%.13f,%i,%i,%i,%i,%i,%i,%s,%s' \ % (self.ident, self.latitude, self.longitude, self.mcc, self.mnc, self.lac, self.cellid, self.crange, self.samples, self.created.strftime('%Y-%m-%d %H:%M:%S'), self.updated.strftime('%Y-%m-%d %H:%M:%S'))
[docs]class Cells(point.KeyedPoints): """Class for representing a group of :class:`Cell` objects. .. versionadded:: 0.11.0 """ def __init__(self, cells_file=None): """Initialise a new ``Cells`` object.""" super(Cells, self).__init__() self._cells_file = cells_file if cells_file: self.import_locations(cells_file) def __str__(self): """``Cells`` objects rendered as export from OpenCellID.org. :rtype: ``str`` :return: OpenCellID.org formatted output """ return '\n'.join(map(str, sorted(self.values(), key=attrgetter('ident'))))
[docs] def import_locations(self, cells_file): """Parse OpenCellID.org data files. ``import_locations()`` returns a dictionary with keys containing the OpenCellID.org_ database identifier, and values consisting of a ``Cell`` objects. It expects cell files in the following format:: 22747,52.0438995361328,-0.2246370017529,234,33,2319,647,0,1, 2008-04-05 21:32:40,2008-04-05 21:32:40 22995,52.3305015563965,-0.2255620062351,234,10,20566,4068,0,1, 2008-04-05 21:32:59,2008-04-05 21:32:59 23008,52.3506011962891,-0.2234109938145,234,10,10566,4068,0,1, 2008-04-05 21:32:59,2008-04-05 21:32:59 The above file processed by ``import_locations()`` will return the following ``dict`` object:: {23008: Cell(23008, 52.3506011963, -0.223410993814, 234, 10, 10566, 4068, 0, 1, datetime.datetime(2008, 4, 5, 21, 32, 59), datetime.datetime(2008, 4, 5, 21, 32, 59)), 22747: Cell(22747, 52.0438995361, -0.224637001753, 234, 33, 2319, 647, 0, 1, datetime.datetime(2008, 4, 5, 21, 32, 40), datetime.datetime(2008, 4, 5, 21, 32, 40)), 22995: Cell(22995, 52.3305015564, -0.225562006235, 234, 10, 20566, 4068, 0, 1, datetime.datetime(2008, 4, 5, 21, 32, 59), datetime.datetime(2008, 4, 5, 21, 32, 59))} :type cells_file: ``file``, ``list`` or ``str`` :param cells_file: Cell data to read :rtype: ``dict`` :return: Cell data with their associated database identifier .. _OpenCellID.org: http://opencellid.org/ """ self._cells_file = cells_file field_names = ('ident', 'latitude', 'longitude', 'mcc', 'mnc', 'lac', 'cellid', 'crange', 'samples', 'created', 'updated') parse_date = lambda s: datetime.datetime.strptime(s, '%Y-%m-%d %H:%M:%S') field_parsers = (int, float, float, int, int, int, int, int, int, parse_date, parse_date) data = utils.prepare_csv_read(cells_file, field_names) for row in data: try: cell = dict((n, p(row[n])) for n, p in zip(field_names, field_parsers)) except ValueError: if r"\N" in row.values(): # A few entries are incomplete, and when that occurs the # export includes the string "\N" to denote missing # data. We just ignore them for now logging.debug('Skipping incomplete entry %r' % row) break else: raise utils.FileFormatError('opencellid.org') else: self[row['ident']] = Cell(**cell)