Ignore:
Timestamp:
Aug 25, 2011, 12:31:50 PM (13 years ago)
Author:
rick
Message:

gwSplit netxml and gpsxml into to different calls, as you first like to import
_all_ netxml before importing _all_ gpsxml, as the gps probes might reference a
unknown accesspoint.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/django_gheat/gheat/management/commands/import_kismet.py

    r9560 r9561  
    2424logger.setLevel(logging.INFO)
    2525
    26 def import_kismet(gpsxml_file, netxml_file, meetrondje):
     26# Open files for reading
     27def open_file(file):
     28 if file.endswith('.gz'):
     29   return gzip.open(file,'rb')
     30 else:
     31  return open(file,'rb')
    2732
    28   # Open files for reading
    29   def open_file(file):
    30    if file.endswith('.gz'):
    31      return gzip.open(file,'rb')
    32    else:
    33     return open(file,'rb')
    34   gpsxml_doc = etree.parse(open_file(gpsxml_file))
     33
     34
     35def import_kismet_netxml(netxml_file):
    3536  netxml_doc = etree.parse(open_file(netxml_file))
    3637
     38  counters = { 'ap_added' : 0, 'ap_total' : 0, 'ap_failed' : 0, 'ap_ignored' : 0}
     39
     40  # Prepare new accespoints and measurements
     41  wnetworks = netxml_doc.findall('wireless-network')
     42
     43  # Temponary holders
     44  ap_pool = {}
     45
     46  # Create all accesspoints and for caching validation purposes store them
     47  # locally as well
     48  for wnetwork in wnetworks:
     49    counters['ap_total'] += 1
     50    bssid = wnetwork.find('BSSID').text
     51    # Only store access points
     52    ap_type = wnetwork.attrib['type']
     53    if ap_type in ['infrastructure', 'data']:
     54      encryption = (wnetwork.find('SSID/encryption') != None)
     55      ssid_node = wnetwork.find('SSID/essid[@cloaked="false"]')
     56      ssid = ssid_node.text if ssid_node != None else 'hidden'
     57
     58      ap_pool[bssid] = (ssid, encryption)
     59    elif ap_type in ['probe', 'ad-hoc']:
     60      counters['ap_ignored'] += 1
     61      continue
     62    else:
     63      logger.error('Unknown type %s - %s',bssid, wnetwork.attrib['type'])
     64
     65
     66  # Determine which entries we need to add
     67  bssid_list_present = Accespoint.objects.filter(mac__in=ap_pool.keys()).values_list('mac', flat=True)
     68  bssid_list_insert = set(ap_pool.keys()) - set(bssid_list_present)
     69
     70  # Create a bulk import list and import
     71  if bssid_list_insert:
     72    sql_values = []
     73    for bssid in bssid_list_insert:
     74      ssid, encryption = ap_pool[bssid]
     75      # Special trick in SSID ts avoid escaping in later stage
     76      item = str((bssid,ssid.replace('%','%%'),encryption))
     77      sql_values.append(item)
     78    counters['ap_added'] = bulk_sql('gheat_accespoint (`mac`, `ssid`, `encryptie`)',sql_values)
     79
     80  return counters
     81
     82
     83
     84def import_kismet_gpsxml(gpsxml_file, meetrondje):
     85  gpsxml_doc = etree.parse(open_file(gpsxml_file))
     86
    3787  #Various statistics
    38   counters = {'meting_added' : 0, 'meting_total' : 0, 'meting_failed' : 0,
    39               'ap_added' : 0, 'ap_total' : 0, 'ap_failed' : 0}
     88  counters = {'meting_added' : 0, 'meting_total' : 0, 'meting_failed' : 0, 'meting_ignored' :0}
    4089
    4190  bssid_failed = defaultdict(int)
    4291
    4392  # Prepare new accespoints and measurements
    44   wnetworks = netxml_doc.findall('wireless-network')
    4593  points = gpsxml_doc.findall('gps-point')
    4694
    4795  # Temponary holders
    4896  meting_pool = defaultdict(list)
    49   ap_pool = {}
    50 
    51   # Create all accesspoints and for caching validation purposes store them
    52   # locally as well
    53   ap_ignore = []
    54   for wnetwork in wnetworks:
    55     bssid = wnetwork.find('BSSID').text
    56     # Only store access points
    57     if wnetwork.attrib['type'] != "infrastructure":
    58       ap_ignore.append(bssid)
    59       continue
    60 
    61     encryption = (wnetwork.find('SSID/encryption') != None)
    62     ssid_node = wnetwork.find('SSID/essid[@cloaked="false"]')
    63     ssid = ssid_node.text if ssid_node != None else 'hidden'
    64 
    65     counters['meting_total'] += 1
    66     ap_pool[bssid] = (ssid, encryption)
    67 
    6897
    6998  for point in points:
     99    counters['meting_total'] += 1
    70100    #XXX: This needs to be either the 'bssid' or the 'source',
    71101    #XXX: accesspoint from or too data.
     
    74104    # that (yet).
    75105    if bssid in ['GP:SD:TR:AC:KL:OG','00:00:00:00:00:00']:
    76       continue
    77     elif bssid in ap_ignore:
     106      counters['meting_ignored'] =+ 1
    78107      continue
    79108    # XXX: Signal need properly be a relation of signal_dbm and noice_dbm
     
    88117    signaal=100 + int(level)
    89118    meting_pool[key].append(signaal)
    90 
    91 
    92   # Determine which entries we need to add
    93   counters['ap_total'] = len(ap_pool)
    94   bssid_list_present = Accespoint.objects.filter(mac__in=ap_pool.keys()).values_list('mac', flat=True)
    95   bssid_list_insert = set(ap_pool.keys()) - set(bssid_list_present)
    96 
    97   # Create a bulk import list and import
    98   if bssid_list_insert:
    99     sql_values = []
    100     for bssid in bssid_list_insert:
    101       ssid, encryption = ap_pool[bssid]
    102       # Special trick in SSID ts avoid escaping in later stage
    103       item = str((bssid,ssid.replace('%','%%'),encryption))
    104       sql_values.append(item)
    105     counters['ap_added'] = bulk_sql('gheat_accespoint (`mac`, `ssid`, `encryptie`)',sql_values)
    106119
    107120  # Build mapping for meting import
     
    123136    logger.debug("Missing BSSID %s found %3s times", bssid, count)
    124137
    125 
    126138  if sql_values:
    127139    counters['meting_added'] = bulk_sql('gheat_meting (`meetrondje_id`, `accespoint_id`, `lat`, `lng`, `signaal`)',sql_values)
     
    130142
    131143class Command(BaseCommand):
    132   args = '<gpsxml>[.gz] [gpsxml2[.gz]  gpsxml3[.gz] ...]'
     144  args = '<gpsxml|netxml>[.gz] [gpsxml2[.gz]  gpsxml3[.gz] ...]'
    133145  option_list = BaseCommand.option_list + (
    134146    make_option('-k', '--kaart', dest='kaart', default='onbekend', help="Kaart gebruikt"),
     
    146158      raise CommandError("Not all arguments are provided")
    147159
    148     for gpsxml_file in args:
    149       if not os.path.isfile(gpsxml_file):
    150         raise CommandError("gpsxml file '%s' does not exists" % gpsxml_file)
     160    for xml_file in args:
     161      if not os.path.isfile(xml_file):
     162        raise CommandError("xml file '%s' does not exists" % xml_file)
    151163
    152       netxml_file = gpsxml_file.replace('.gpsxml','.netxml')
    153       if not os.path.isfile(netxml_file):
    154         raise CommandError("correlated netxml file '%s' does not exists" % netxml_file)
    155164
    156       logger.info("Processing '%s'" % gpsxml_file)
    157       if options['datum'] == None:
    158          datum = os.path.basename(gpsxml_file).lstrip('Kismet-').rstrip('.gpsxml.gz')
     165    for xml_file in args:
     166      logger.info("Processing '%s'" % xml_file)
     167      if 'netxml' in xml_file:
     168        counters = import_kismet_netxml(xml_file)
     169        logger.info("summary accespoints: total:%(ap_total)-6s added:%(ap_added)-6s failed:%(ap_failed)-6s ignored:%(ap_ignored)-6s" % counters)
     170      elif 'gpsxml' in xml_file:
     171        if options['datum'] == None:
     172           datum = os.path.basename(xml_file).lstrip('Kismet-').rstrip('.gz').rstrip('.gpsxml').rstrip('.netxml')
     173        else:
     174           datum = options['datum']
     175        try:
     176           # Kismet-20110805-15-37-30-1
     177           datum = datetime.datetime.strptime(datum,'%Y%m%d-%H-%M-%S-1')
     178        except ValueError:
     179          raise CommandError("Invalid date '%s'" % options['datum'])
     180
     181        # Meetrondje from filename if needed
     182        if options['meetrondje'] == None:
     183          meetrondje = os.path.basename(xml_file).rstrip('.gz').rstrip('.gpsxml')
     184        else:
     185          meetrondje = options['meetrondje']
     186
     187        # Create meetrondje object
     188        g, created = Gebruiker.objects.get_or_create(naam=options['gebruiker'] , email=options['email'])
     189        a, created = Apparatuur.objects.get_or_create(kaart=options['kaart'])
     190        mr, created = MeetRondje.objects.get_or_create(datum=datum , naam=meetrondje , gebruiker=g , apparatuur=a)
     191        logger.info('Meetrondje: %s @ %s' % (meetrondje, datum))
     192        if not created:
     193          logger.error("Meetrondje '%s' already imported" % mr)
     194          sys.exit(1)
     195        counters = import_kismet_gpsxml(xml_file, mr)
     196        logger.info("summary metingen   : total:%(meting_total)-6s added:%(meting_added)-6s failed:%(meting_failed)-6s ignored:%(meting_ignored)-6s" % counters)
    159197      else:
    160          datum = options['datum']
    161       try:
    162          # Kismet-20110805-15-37-30-1
    163          datum = datetime.datetime.strptime(datum,'%Y%m%d-%H-%M-%S-1')
    164       except ValueError:
    165         raise CommandError("Invalid date '%s'" % options['datum'])
    166 
    167       # Meetrondje from filename if needed
    168       if options['meetrondje'] == None:
    169         meetrondje = os.path.basename(gpsxml_file).rstrip('.gz').rstrip('.gpsxml')
    170       else:
    171         meetrondje = options['meetrondje']
    172 
    173       # Create meetrondje object
    174       g, created = Gebruiker.objects.get_or_create(naam=options['gebruiker'] , email=options['email'])
    175       a, created = Apparatuur.objects.get_or_create(kaart=options['kaart'])
    176       mr, created = MeetRondje.objects.get_or_create(datum=datum , naam=meetrondje , gebruiker=g , apparatuur=a)
    177       logger.info('Meetrondje: %s @ %s' % (meetrondje, datum))
    178       if not created:
    179         logger.error("Meetrondje '%s' already imported" % mr)
    180         sys.exit(1)
    181       counters = import_kismet(gpsxml_file, netxml_file, mr)
    182       logger.info("summary accespoints: total:%(ap_total)-6s added:%(ap_added)-6s failed:%(ap_failed)-6s" % counters)
    183       logger.info("summary metingen   : total:%(meting_total)-6s added:%(meting_added)-6s failed:%(meting_failed)-6s" % counters)
     198        raise CommandError("xml file '%s' format not recognized" % xml_file)
Note: See TracChangeset for help on using the changeset viewer.