#!/usr/bin/python

from commands import getoutput as run
from sys import argv
from sys import exit as sysexit
from os import system
from operator import itemgetter

def badend(txt):
    print(txt)
    sysexit(1)

def verbose(txt):
    if vvv:
        print txt

def printout(wscan, clr = True):
    if clr:
        system('clear')
    else:
        print 80 * '_'
    channels = []
    for cell in wscan:
        if cell['cell'] != ' ':
            channels.append([int(cell['channel']), int(cell['quality']), cell['cell']])
    channels.sort()
    channel = 0
    chprint = ''
    prevqual = 0
    for item in channels:
        if channel != item[0]:
            channel = item[0]
            chprint = '%s\n%s%i %s%s' % (chprint, (3-len(str(item[0]))) * ' ', item[0], (item[1] - 2) * '-', item[2])
        else:
            chprint = '%s%s%s' % (chprint, (item[1] - prevqual - 2) * '-', item[2])
        prevqual = item[1]

    print 'Wlan scanner, created by Michal Budinsky'
    print '\n ch quality'
    print chprint[1:]
    print '\nid  ch freq   q lvl mlvl encryption essid'
    for cell in wscan:
        print '%s %s %s %s %s %s %s %s' % ((2 - len(cell['cell'])) * ' ' + cell['cell'], (3 - len(cell['channel'])) * ' ' + cell['channel'], cell['frequency'] + (5 - len(cell['frequency'])) * ' ', (2 - len(cell['quality'])) * ' ' + cell['quality'], (3 - len(cell['signal'])) * ' ' + cell['signal'], (4 - len(cell['maxsignal'])) * ' ' + cell['maxsignal'], (10 - len(cell['encryption'])) * ' ' + cell['encryption'], cell['essid'])

def appendcell(wscan, cell):
    if cell != {}:
        if not cell.has_key('id'):
            cell['id'] = '%s%s%s' % ((3 - len(cell['channel'])) * ' ' + cell['channel'], cell['essid'], cell['encryption'])
            cell['maxsignal'] = cell['signal']
        verbose('NEW CELL: %s' % cell)
        ins = -1
        for i in range(len(wscan)):
            if wscan[i]['id'] == cell['id']:
                verbose('OLD CELL: %s' % wscan[i])
                verbose('COMPARE %s AND %s' % (cell['maxsignal'], wscan[i]['maxsignal']))
                if int(wscan[i]['maxsignal']) > int(cell['maxsignal']):
                    cell['maxsignal'] = wscan[i]['maxsignal']
                wscan.pop(i)
                break
        for i in range(len(wscan)):
            if ins < 0 and wscan[i]['cell'] == ' ':
                ins = i
        #wscan.insert(ins, cell)
        wscan.append(cell)
    return wscan

#cell:{address, channel, frequency, quality, signal, maxsignal, encryption, essid}
def getscan(wscan):
    rules = [['cell', 'Cell ', ' '],
             ['address', 'Address: ', ' '],
             ['channel', 'Channel:', ' '],
             ['frequency', 'Frequency:', ' '],
             ['quality', 'Quality=', '/'],
             ['signal', 'Signal level=', ' '],
             ['encryption', 'Encryption key:', ' '],
             ['essid', 'ESSID:"', '"']]
    gcs = ['WEP', 'WPA2', 'WPA']

    for cell in wscan:
        if cell.has_key('cell') and not cell['cell'].startswith('*'):
            cell['cell'] = ' '
            cell['quality'] = ' '
            cell['signal'] = ' '
    cell = {}
    for line in run('iwlist %s scanning' % interface).split('\n'):
        verbose('LINE: %s' % line)
        if 'Cell ' in line:
            verbose('FINAL CELL: %s' % cell)
            wscan = appendcell(wscan, cell)
            cell = {}

        if cell.has_key('encryption'):
            if cell['encryption'] == 'on' or cell['encryption'].startswith('W'):
                verbose('LOOKING FOR GROUP CYPHER')
                for gc in gcs:
                    if gc in line:
                        verbose('GROUP CYPHER: %s' % gc)
                        if cell['encryption'] == 'on':
                            cell['encryption'] = gc
                        else:
                            cell['encryption'] = cell['encryption'] + '+' + gc
                        verbose('CELL: %s' % cell)
                        break
        for rule in rules:
            if rule[1] in line:

                cell[rule[0]] = line.split(rule[1])[1].split(rule[2])[0]
                verbose('RULE: %s' % rule)
                verbose('CELL: %s' % cell)
    wscan = appendcell(wscan, cell)
    verbose('BEFORE CLEANING: %s' % wscan)
    while wscan.count({}) > 0:
        wscan.remove({})
    verbose('AFTER CLEANING: %s' % wscan)
    return sorted(wscan, key=itemgetter('id'))

vvv = True if '-vvv' in argv else False
verbose('Running in verbose mode.')

if '-i' in argv:
    interface = argv[argv.index('-i') + 1]
else:
    badend('No interface specified.')
wscan_data = []
try:
    while True:
        wscan_data = getscan(wscan_data)
        if vvv:
            verbose(wscan_data)
            printout(wscan_data, False)
            #badend('Ending becouse of verbose mode.')
        else:
            printout(wscan_data)
except KeyboardInterrupt: # Interrupting by <ctrl+c>
    verbose('Interupted by user.')

