source: src/django_gheat/gheat/management/commands/import_kismet.py@ 9557

Last change on this file since 9557 was 9552, checked in by rick, 13 years ago

Some awefull hacks to allow data to be imported.

  • Property svn:executable set to *
File size: 4.9 KB
Line 
1#!/usr/bin/env python
2#
3# Script for importing .gpsxml and .netxml files (Kismet output)
4#
5
6from django.core.management.base import BaseCommand,CommandError
7from django.db.utils import IntegrityError
8from optparse import OptionParser, make_option
9from gheat.models import *
10from lxml import etree
11import datetime
12import gzip
13import os
14import sys
15import logging
16
17def import_file(gpsxml_file, netxml_file, meetrondje, kaart, gebruiker, email):
18 # TODO: Source source is variable entitity, based on mesurement
19 kaart = 'deadcode'
20 gebruiker, created = Gebruiker.objects.get_or_create(naam=gebruiker , email=email)
21 apparatuur, created = Apparatuur.objects.get_or_create(kaart=kaart)
22 # TODO: Date is set to import date, but should pick the date from the netxml file
23 mr = MeetRondje.objects.create(datum=None,
24 naam=meetrondje , gebruiker=gebruiker , apparatuur=apparatuur)
25 if not created:
26 logging.error("Meetrondje '%s' already imported" % mr)
27 sys.exit(1)
28
29 open_file = lambda file: gzip.open(file,'rb') if file.endswith('.gz') else open(file,'rb')
30 gpsxml_doc = etree.parse(open_file(gpsxml_file))
31 netxml_doc = etree.parse(open_file(netxml_file))
32
33 points = gpsxml_doc.findall('gps-point')
34 wnetworks = netxml_doc.findall('wireless-network')
35
36 # Create all accesspoints and for caching validation purposes store them
37 # locally as well
38 ap_cache = {}
39 ap_ignore = []
40 print "#INFO: Going to import %s accesspoints" % len(wnetworks)
41 for wnetwork in wnetworks:
42 bssid = wnetwork.find('BSSID').text
43 # Only store access points
44 if wnetwork.attrib['type'] != "infrastructure":
45 ap_ignore.append(bssid)
46 continue
47
48 enc = (wnetwork.find('SSID/encryption') != None)
49 ssid_node = wnetwork.find('SSID/essid[@cloaked="false"]')
50 ssid = ssid_node.text if ssid_node != None else 'hidden'
51
52 ap, created = Accespoint.objects.get_or_create(mac=bssid, ssid=ssid, encryptie=enc)
53 ap_cache[bssid] = ap
54
55 count = 0
56 #XXX: This is not effient at all, try to wrap it into a a bulk insert would
57 # be much more effient as for example: http://djangosnippets.org/snippets/2362/
58 print "#INFO: Going to import %s points" % len(points)
59 for point in points:
60 #XXX: This needs to be either the 'bssid' or the 'source', accesspoint from or too data.
61 bssid = point.attrib['bssid']
62 # XXX: Filter this in the beginning with XPath, but etree does not support that (yet).
63 if bssid in ['GP:SD:TR:AC:KL:OG','00:00:00:00:00:00']:
64 continue
65 elif bssid in ap_ignore:
66 continue
67 elif not ap_cache.has_key(bssid):
68 try:
69 ap = Accespoint.objects.get(mac=bssid)
70 ap_cache[bssid] = ap
71 except Accespoint.DoesNotExist:
72 print "#ERROR: Cannot found SSID for BSSID '%s'" % bssid
73 continue
74
75 # XXX: Signal need properly be a relation of signal_dbm and noice_dbm
76 try:
77 signaal = 100 + int(point.attrib['signal_dbm'])
78 except KeyError:
79 print "#ERROR: Point '%s' does not have signal strengh" % point
80
81 # TODO: This also saves semi-duplicates; multiple entries with the same values, except
82 # the signal strength is different. Should get an AVG or something.
83 try:
84 meting= Meting.objects.create(meetrondje=mr, accespoint=ap_cache[bssid],
85 latitude=point.attrib['lat'], longitude=point.attrib['lon'],
86 signaal=signaal)
87 except IntegrityError, e:
88 continue
89 # Give some feedback to the user
90 count += 1
91 if (count % 1000) == 0:
92 sys.stdout.write(str(count))
93 elif (count % 100) == 0:
94 sys.stdout.write(".")
95 sys.stdout.flush()
96
97 sys.stdout.write("%s\n" % count)
98 print "#INFO: All done, goodbye"
99
100
101class Command(BaseCommand):
102 args = '<gpsxml>[.gz] [<netxml>[.gz]]'
103 option_list = BaseCommand.option_list + (
104 make_option('-m', '--meetrondje', dest='meetrondje', default='rondje',help='Naam van het meetrondje'),
105 make_option('-k', '--kaart', dest='kaart', default='onbekend', help="Kaart gebruikt"),
106 make_option('-g', '--gebruiker', dest='gebruiker', default='username',help='Naam van de persoon die de meting uitgevoerd heeft'),
107 make_option('-e', '--email', dest='email', default='foo@bar.org',help='Email van de persoon die de meting uitgevoerd heeft'),
108 )
109
110 def handle(self, *args, **options):
111 try:
112 if len(args) == 2:
113 (gpsxml_file, netxml_file) = args
114 elif len(args) == 1:
115 (gpsxml_file,) = args
116 netxml_file = gpsxml_file.replace('.gpsxml','.netxml')
117 else:
118 raise ValueError
119 except ValueError:
120 self.print_help(sys.argv[0],sys.argv[1])
121 raise CommandError("Not all arguments are provided")
122 if not os.path.isfile(gpsxml_file):
123 raise CommandError("gpsxml file '%s' does not exists" % gpsxml_file)
124 if not os.path.isfile(netxml_file):
125 raise CommandError("netxml file '%s' does not exists" % netxml_file)
126
127 import_file(gpsxml_file, netxml_file ,options['meetrondje'], options['kaart'],options['gebruiker'],options['email'])
Note: See TracBrowser for help on using the repository browser.