disable logging in scanner
[dumbwifi.git] / ui.py
blobedcd5be390ca57d3d576d71b2e55e437396a6332
1 #!/usr/bin/env python
3 import curses
5 from conf import config
6 import output
7 from output import display, err, err_fg
8 import network
9 import time
10 import util
13 def ip_check():
14 pre = "=> Checking for ip..."
16 display(pre)
17 ips = [(x, y) for (x, y) in
18 [(i.interface, network.has_ip(i.interface))
19 for i in config.interfaces]
20 if y != None] # (iface, ip) pairs where ip is set
21 if ips:
22 display("%s %s" % (pre, reduce(lambda x, y: "%s %s" % (x, y),
23 map(lambda (x, y): "%s (%s)" % (y, x), ips))))
24 return True
25 else:
26 display("%s %s" % (pre, "none"))
29 def choose_medium():
30 pre = "=> Selecting preferred network medium..."
32 display(pre)
33 ifs = util.sort_dictlist(config.interfaces, 'priority')[0]
34 display("%s %s" % (pre, ifs.medium))
35 if ifs.medium == "wired": return True
38 def check_wired_link():
39 pre = "=> Checking for wired link..."
41 display(pre)
42 f = lambda x: x.medium == "wired"
43 ifs = util.sort_dictlist(config.interfaces, 'priority', f=f)
44 cs = [network.wire_connected(i.interface) for i in ifs]
45 if any(cs):
46 display("%s %s" % (pre, reduce(lambda x,y: "%s %s" % (x,y),
47 map(lambda x: "%s" % x, cs))))
48 return True
49 else:
50 display("%s %s" % (pre, "none, use wireless"))
53 def request_ip(iface, net=None, tries=3):
54 n = iface.interface
55 if net:
56 n = "%s (from %s)" % (n, net.essid)
57 if not network.setup_wifi(iface.interface, net):
58 util.err("Failed to associate with access point for network %s"\
59 % net.essid)
60 return
62 attempt = 0
63 while attempt < tries:
64 attempt += 1
65 pre = "=> (%d) Request ip on %s..." % (attempt, n)
67 display(pre)
68 start_time = time.time()
69 ip = network.request_ip(iface.interface)
70 stop_time = time.time()
71 duration = stop_time - start_time
73 if ip:
74 display("%s %s" % (pre, "%s (%ds)" % (ip, duration)))
75 return True
76 else: display("%s %s" % (pre, "failed (%ds)" % duration))
79 def scan_wifi_networks(iface, wardrive=None):
80 pre = "=> Scan for wireless networks..."
82 display(pre)
83 nets = network.read_scan(network.normal_scan(iface.interface))
84 nets = util.mergen(nets, config.networks, 'essid')
85 f = lambda x: x.priority != None and x.signal != None
86 if wardrive:
87 f = lambda x: x.signal != None and x.priority == None\
88 and x.encrypted == None and x.essid != "<hidden>"
89 nets = util.sort_dictlist(nets, 'quality', f=f)
90 if nets:
91 display("%s %s" % (pre, reduce(lambda x,y: "%s %s" % (x,y),
92 map(lambda x: "%s" % x.essid, nets[:3]))))
93 return nets
94 else: display("%s %s" % (pre, "none"))
97 def display_live_networks(nets, field=None, column=None):
98 if not nets:
99 return "No networks detected"
101 keys = ['bssid', 'essid', 'channel', 'bitrate', 'sec', 'signal', 'quality']
102 width = 19; mw = 6; sp = 2 # width: max width mw : min width sp : separate
104 if field:
105 nets = util.sort_dictlist(nets, field)
106 elif column and 0 < column <= len(keys):
107 nets = util.sort_dictlist(nets, keys[column-1])
108 else: nets = util.sort_dictlist(nets, 'quality')
110 # figure out column length to assign to fields based on content length
111 def col_len(dicts, key):
112 l = []
113 for dict in dicts:
114 if key in dict and dict[key]: l.append(len(dict[key])+sp)
115 else: l.append(sp)
116 return l
117 ws = [max(min(max(col_len(nets, k)), width), mw) for k in keys]
119 s = ""
120 for (i, key) in enumerate(keys):
121 s += ("%s" % key[:ws[i]-sp]).ljust(ws[i])
122 s = s[:-sp] + "\n"
123 for net in nets:
124 for (i, key) in enumerate(keys):
125 if key in net: s += (net[key][:ws[i]-sp]).ljust(ws[i])
126 else: s += "".ljust(ws[i])
127 s = s[:-sp] + "\n"
128 return s + "%d network(s) found" % len(nets)
131 def curse(iface, timeout):
132 s = ""
133 output.mute(quiet=True)
135 try:
136 scr = curses.initscr()
137 curses.noecho()
138 curses.cbreak()
139 scr.keypad(1)
140 curses.curs_set(0)
142 t = time.time()+timeout
143 while 1:
144 status = ""
145 if timeout > 0:
146 status = " - scanning for %ds (-%ds)" % (timeout, t-time.time())
147 if t < time.time(): break
149 scan_data = network.single_scan(iface)
150 nets = network.read_scan(scan_data)
151 s = display_live_networks(nets)
152 header = "%s scanning for wireless networks (%s)\n\n" % (config.program_name, iface)
154 if s:
155 ss = s.split("\n")
156 scr.clear()
157 scr.addstr(header)
158 scr.addstr(ss[0]+"\n", curses.A_REVERSE)
159 scr.addstr("\n".join(ss[1:]))
160 scr.addstr(status + "\n\nCtrl+C to exit")
161 scr.refresh()
163 curses.napms(500)
164 except KeyboardInterrupt:
165 print s
166 finally:
167 curses.nocbreak()
168 scr.keypad(0);
169 curses.echo()
170 curses.endwin()
172 output.unmute(quiet=True)
173 print s