1 # -*- coding: utf-8 -*-
3 # __init__.py - main logic for operating WiFi Radar
5 # Part of WiFi Radar: A utility for managing WiFi profiles on GNU/Linux.
7 # Copyright (C) 2004-2005 Ahmad Baitalmal <ahmad@baitalmal.com>
8 # Copyright (C) 2005 Nicolas Brouard <nicolas.brouard@mandrake.org>
9 # Copyright (C) 2005-2009 Brian Elliott Finley <brian@thefinleys.com>
10 # Copyright (C) 2006 David Decotigny <com.d2@free.fr>
11 # Copyright (C) 2006 Simon Gerber <gesimu@gmail.com>
12 # Copyright (C) 2006-2007 Joey Hurst <jhurst@lucubrate.org>
13 # Copyright (C) 2006, 2009 Ante Karamatic <ivoks@ubuntu.com>
14 # Copyright (C) 2009-2010,2014 Sean Robinson <seankrobinson@gmail.com>
15 # Copyright (C) 2010 Prokhor Shuchalov <p@shuchalov.ru>
17 # This program is free software; you can redistribute it and/or modify
18 # it under the terms of the GNU General Public License as published by
19 # the Free Software Foundation; version 2 of the License.
21 # This program is distributed in the hope that it will be useful,
22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 # GNU General Public License in LICENSE.GPL for more details.
26 # You should have received a copy of the GNU General Public License
27 # along with this program; if not, write to the Free Software
28 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 from ConfigParser
import NoOptionError
37 from configparser
import NoOptionError
40 from multiprocessing
import Pipe
, Process
41 from threading
import Thread
43 from wifiradar
.config
import ConfigManager
44 from wifiradar
.connections
import ConnectionManager
, scanner
45 from wifiradar
.pubsub
import Dispatcher
, Message
46 import wifiradar
.misc
as misc
47 import wifiradar
.gui
.g2
as ui
48 import wifiradar
.gui
.g2
.transients
as transients
50 # Set up a logging framework.
51 logger
= logging
.getLogger("wifiradar")
58 logger
.setLevel(logging
.DEBUG
)
60 logger
.setLevel(config
.get_opt_as_int('DEFAULT', 'loglevel'))
62 dispatcher
= Dispatcher()
63 scanner_pipe
= dispatcher
.subscribe(['ALL'])
64 ui_pipe
= dispatcher
.subscribe(['ALL'])
67 fileLogHandler
= logging
.handlers
.RotatingFileHandler(config
.get_opt('DEFAULT', 'logfile'), maxBytes
=64*1024, backupCount
=5)
69 error_pipe
= dispatcher
.subscribe()
70 error_pipe
.send(Message('ERROR',
71 'Cannot open log file for writing: %s.\n\n'.format(e
.strerror
) +
72 'WiFi Radar will work, but a log file will not be recorded.'))
73 dispatcher
.unsubscribe(error_pipe
)
75 fileLogHandler
.setFormatter(generic_formatter
)
76 logger
.addHandler(fileLogHandler
)
78 scanner_thread
= Thread(name
='scanner', target
=scanner
, args
=(config
, scanner_pipe
))
79 scanner_thread
.start()
81 ui_proc
= Process(name
='iu', target
=ui
.RadarWindow
, args
=(ui_pipe
,))
84 msg_pipe
= dispatcher
.subscribe(['ALL'])
86 # This is the first run (or, at least, no config file was present),
87 # so pop up the preferences window
89 if config
.get_opt_as_bool('DEFAULT', 'new_file'):
90 config
.remove_option('DEFAULT', 'new_file')
91 config_copy
= ConfigManager({})
92 msg_pipe
.send(Message('CONFIG-UPDATE', config_copy
))
93 msg_pipe
.send(Message('PREFS-EDIT', ''))
97 # Send a copy of the configuration to other components.
98 config_copy
= ConfigManager(config
.defaults())
99 msg_pipe
.send(Message('CONFIG-UPDATE', config_copy
))
101 # Add our known profiles in order.
102 for profile_name
in config
.auto_profile_order
:
103 profile
= config
.get_profile(profile_name
)
104 msg_pipe
.send(Message('PROFILE-UPDATE', profile
))
109 msg
= msg_pipe
.recv()
110 except (EOFError, IOError) as e
:
111 # This is bad, really bad.
112 logger
.critical('read on closed ' +
113 'Pipe ({}), failing...'.format(msg_pipe
))
114 raise misc
.PipeError(e
)
116 if msg
.topic
== 'EXIT':
119 elif msg
.topic
== 'PROFILE-UPDATE':
120 profile
= msg
.details
121 if profile
['roaming']:
122 apname
= misc
.make_section_name(profile
['essid'], '')
124 apname
= misc
.make_section_name(profile
['essid'], profile
['bssid'])
125 if apname
not in config
.profiles():
126 config
.set_section(apname
, profile
)
127 config
.auto_profile_order
.insert(0, apname
)
128 msg_pipe
.send(Message('PROFILE-UPDATE', profile
))
129 #msg_pipe.send(Message('PROFILE-MOVE', profile, 0))
130 elif msg
.topic
== 'PROFILE-REMOVE':
132 if apname
in config
.profiles():
133 profile
= config
.get_profile(apname
)
134 config
.remove_section(apname
)
135 self
.config
.auto_profile_order
.remove(apname
)
136 msg_pipe
.send(Message('PROFILE-UNLIST', profile
))
138 logger
.warning('unrecognized Message: "{}"'.format(msg
))
140 scanner_thread
.join()