<s> from PySide import QtCore , QtGui <EOL> from neoman . device import open_all_devices , ResetStateException <EOL> from neoman . storage import settings <EOL> from functools import wraps <EOL> DEFAULT_KEY = "<STR_LIT>" <EOL> def with_mutex ( mutex , func ) : <EOL> @ wraps ( func ) <EOL> def inner ( * args , ** kwargs ) : <EOL> try : <EOL> mutex . lock ( ) <EOL> return func ( * args , ** kwargs ) <EOL> finally : <EOL> mutex . unlock ( ) <EOL> return inner <EOL> class YubiKeyNeo ( QtCore . QObject ) : <EOL> removed = QtCore . Signal ( ) <EOL> def __init__ ( self , device ) : <EOL> super ( YubiKeyNeo , self ) . __init__ ( ) <EOL> self . _mutex = QtCore . QMutex ( QtCore . QMutex . Recursive ) <EOL> self . _serial = device . serial <EOL> self . _version = device . version <EOL> self . _apps = None <EOL> self . _group = self . _serial if self . _serial else "<STR_LIT>" <EOL> self . _set_device ( device ) <EOL> def _set_device ( self , device ) : <EOL> if self . serial != device . serial or self . version != device . version : <EOL> print self . serial , self . version , device . serial , device . version <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> self . _dev = device <EOL> self . _mode = device . mode <EOL> self . _default_name = device . default_name <EOL> if device . has_ccid : <EOL> device . key = self . key . decode ( '<STR_LIT>' ) <EOL> def __setitem__ ( self , key , value ) : <EOL> settings . setValue ( '<STR_LIT>' % ( self . _group , key ) , value ) <EOL> def __delitem__ ( self , key ) : <EOL> settings . remove ( '<STR_LIT>' % ( self . _group , key ) ) <EOL> def __getitem__ ( self , key ) : <EOL> return self . get ( key ) <EOL> def __nonzero__ ( self ) : <EOL> return True <EOL> def __len__ ( self ) : <EOL> try : <EOL> settings . beginGroup ( '<STR_LIT:%s>' % self . _group ) <EOL> return len ( settings . allKeys ( ) ) <EOL> finally : <EOL> settings . endGroup ( ) <EOL> def __getattr__ ( self , name ) : <EOL> try : <EOL> self . _mutex . lock ( ) <EOL> if not self . _dev : <EOL> raise AttributeError ( name ) <EOL> attr = getattr ( self . _dev , name ) <EOL> if hasattr ( attr , '<STR_LIT>' ) : <EOL> attr = with_mutex ( self . _mutex , attr ) <EOL> return attr <EOL> finally : <EOL> self . _mutex . unlock ( ) <EOL> def __delattr__ ( self , key ) : <EOL> del self [ key ] <EOL> def get ( self , key , default = None ) : <EOL> return settings . value ( '<STR_LIT>' % ( self . _group , key ) , default ) <EOL> @ property <EOL> def name ( self ) : <EOL> return self . get ( '<STR_LIT:name>' , self . _default_name ) <EOL> @ name . setter <EOL> def name ( self , new_name ) : <EOL> self [ '<STR_LIT:name>' ] = new_name <EOL> @ property <EOL> def key ( self ) : <EOL> return self . get ( '<STR_LIT:key>' , DEFAULT_KEY ) <EOL> @ key . setter <EOL> def key ( self , new_key ) : <EOL> self [ '<STR_LIT:key>' ] = new_key <EOL> try : <EOL> self . _mutex . lock ( ) <EOL> self . _dev . key = new_key . decode ( '<STR_LIT>' ) <EOL> finally : <EOL> self . _mutex . unlock ( ) <EOL> def set_key ( self , new_key ) : <EOL> try : <EOL> self . _mutex . lock ( ) <EOL> print "<STR_LIT>" <EOL> finally : <EOL> self . _mutex . unlock ( ) <EOL> @ property <EOL> def has_ccid ( self ) : <EOL> try : <EOL> self . _mutex . lock ( ) <EOL> return self . _dev and self . _dev . has_ccid <EOL> finally : <EOL> self . _mutex . unlock ( ) <EOL> @ property <EOL> def mode ( self ) : <EOL> return self . _mode <EOL> @ property <EOL> def serial ( self ) : <EOL> return self . _serial <EOL> @ property <EOL> def version ( self ) : <EOL> return self . _version <EOL> def __str__ ( self ) : <EOL> return self . name <EOL> def list_apps ( self ) : <EOL> try : <EOL> self . _mutex . lock ( ) <EOL> if self . device_type != '<STR_LIT>' : <EOL> return [ ] <EOL> if self . _apps is None : <EOL> apps = [ ] <EOL> appletmanager = QtCore . QCoreApplication . instance ( ) . appletmanager <EOL> for applet in appletmanager . get_applets ( ) : <EOL> installed , version = applet . get_status ( self ) <EOL> if installed : <EOL> apps . append ( applet . aid ) <EOL> self . _apps = apps <EOL> return self . _apps <EOL> finally : <EOL> self . _mutex . unlock ( ) <EOL> class AvailableNeos ( QtCore . QThread ) : <EOL> changed = QtCore . Signal ( list ) <EOL> def __init__ ( self ) : <EOL> super ( AvailableNeos , self ) . __init__ ( ) <EOL> self . _mutex = QtCore . QMutex ( ) <EOL> self . _neos = [ ] <EOL> self . _running = True <EOL> self . _sleep = <NUM_LIT:1000> <EOL> def stop ( self ) : <EOL> self . _running = False <EOL> self . wait ( ) <EOL> def get ( self ) : <EOL> try : <EOL> self . _mutex . lock ( ) <EOL> return self . _neos [ : ] <EOL> finally : <EOL> self . _mutex . unlock ( ) <EOL> def run ( self ) : <EOL> self . discover_devices ( ) <EOL> while self . _running : <EOL> if QtGui . QApplication . activeWindow ( ) : <EOL> self . discover_devices ( ) <EOL> self . msleep ( self . _sleep ) <EOL> def discover_devices ( self ) : <EOL> neos = self . get ( ) <EOL> existing_devs = [ ] <EOL> for neo in neos : <EOL> if neo . _dev : <EOL> neo . _mutex . lock ( ) <EOL> existing_devs . append ( neo . _dev ) <EOL> neo . _dev = None <EOL> new_neos = [ ] <EOL> dead_neos = neos [ : ] <EOL> state_reset = False <EOL> try : <EOL> discovered = open_all_devices ( existing_devs ) <EOL> if self . _sleep > <NUM_LIT:1000> : <EOL> self . _sleep = <NUM_LIT:1000> <EOL> state_reset = True <EOL> except ResetStateException as e : <EOL> discovered = e . devices <EOL> self . _sleep = <NUM_LIT> <EOL> for dev in discovered : <EOL> for neo in dead_neos [ : ] : <EOL> if dev . serial == neo . serial and dev . version == neo . version and dev . device_type == dev . device_type : <EOL> neo . _set_device ( dev ) <EOL> neo . _mutex . unlock ( ) <EOL> dead_neos . remove ( neo ) <EOL> break <EOL> else : <EOL> new_neos . append ( YubiKeyNeo ( dev ) ) <EOL> for neo in dead_neos : <EOL> neos . remove ( neo ) <EOL> neo . removed . emit ( ) <EOL> neo . _mutex . unlock ( ) <EOL> if new_neos or dead_neos or state_reset : <EOL> self . _mutex . lock ( ) <EOL> self . _neos = neos + new_neos <EOL> neos_copy = self . _neos [ : ] <EOL> self . _mutex . unlock ( ) <EOL> self . changed . emit ( neos_copy ) </s>
