Translation update done using Pootle.
[wammu.git] / Wammu / PhoneSearch.py
blob5a642fbff1d390b55e108ef48358500f2899cf53
1 # -*- coding: UTF-8 -*-
2 # vim: expandtab sw=4 ts=4 sts=4:
3 '''
4 Wammu - Phone manager
5 Searching for phone
6 '''
7 __author__ = 'Michal Čihař'
8 __email__ = 'michal@cihar.com'
9 __license__ = '''
10 Copyright © 2003 - 2010 Michal Čihař
12 This program is free software; you can redistribute it and/or modify it
13 under the terms of the GNU General Public License version 2 as published by
14 the Free Software Foundation.
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 more details.
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 '''
26 import wx
27 import threading
28 import sys
29 import Wammu
30 if Wammu.gammu_error == None:
31 import gammu
32 import Wammu.Data
33 import Wammu.Events
34 import wx.lib.layoutf
35 from Wammu.Locales import StrConv
36 import Wammu.Utils
38 try:
39 import bluetooth
40 import Wammu.BluezDiscovery
41 BLUETOOTH = 'bluez'
42 except ImportError:
43 BLUETOOTH = None
45 class AllSearchThread(threading.Thread):
46 '''
47 Root thread for phone searching. It spawns other threads for testing each
48 device.
49 '''
50 def __init__(self,
51 lock = False,
52 level = 'nothing',
53 msgcallback = None,
54 callback = None,
55 win = None,
56 noticecallback = None,
57 limit = None):
58 threading.Thread.__init__(self)
59 self.lock = lock
60 self.list = []
61 self.win = win
62 self.listlock = threading.Lock()
63 self.level = level
64 self.threads = []
65 self.callback = callback
66 self.msgcallback = msgcallback
67 self.noticecallback = noticecallback
68 self.limit = limit
70 def create_search_thread(self, device, connections, name):
71 '''
72 Creates single thread for searching phone on device using listed
73 connections. Name is just text which will be shown to user.
74 '''
75 newthread = SearchThread(
76 device,
77 connections,
78 self.list,
79 self.listlock,
80 self.lock,
81 self.level)
82 newthread.setName(name)
83 if self.msgcallback != None:
84 self.msgcallback(
85 _('Checking %s') %
86 StrConv(name)
88 self.threads.append(newthread)
89 newthread.start()
91 def search_bt_device(self, address, name):
92 '''
93 Searches single Bluetooth device.
94 '''
95 connections = Wammu.Data.Conn_Bluetooth_All
96 vendorguess = _('Could not guess vendor')
97 # Use better connection list for some known manufacturers
98 for vendor in Wammu.Data.MAC_Prefixes.keys():
99 if address[:8].upper() in Wammu.Data.MAC_Prefixes[vendor]:
100 connections = Wammu.Data.Conn_Bluetooth[vendor]
101 vendorguess = _('Guessed as %s') % vendor
103 self.create_search_thread(
104 address,
105 connections,
106 '%s (%s) - %s - %s' % (
107 address,
108 name,
109 vendorguess,
110 str(connections)))
112 def check_device(self, curdev):
114 Checks whether it makes sense to perform searching on this device and
115 possibly warns user about misconfigurations.
117 res = Wammu.Utils.CheckDeviceNode(curdev)
119 if res[0] == 0:
120 return True
121 if res[0] == -1:
122 return False
123 if res[1] != '' and self.msgcallback != None:
124 self.msgcallback(res[1])
125 if res[2] != '' and self.noticecallback != None:
126 self.noticecallback(res[2], res[3])
127 return False
129 def search_device(self, curdev, dev):
131 Performs search on one real device.
133 if len(curdev) > 0 and curdev[0] == '/':
134 if not self.check_device(curdev):
135 return
137 self.create_search_thread(
138 curdev,
139 dev[0],
140 '%s - %s' % (curdev, str(dev[0])))
142 def listed_device_search(self):
144 Initiates searching of devices defined in Wammu.Data.AllDevices.
146 for dev in Wammu.Data.AllDevices:
147 if not (self.limit == 'all' or self.limit in dev[3]):
148 continue
149 if dev[1].find('%d') >= 0:
150 for i in range(*dev[2]):
151 curdev = dev[1] % i
152 self.search_device(curdev, dev)
153 else:
154 self.search_device(dev[1], dev)
156 def bluetooth_device_search_bluez(self):
158 Initiates searching for Bluetooth devices using PyBluez stack.
160 # read devices list
161 if self.msgcallback != None:
162 self.msgcallback(_('Scanning for Bluetooth devices using %s') %
163 'PyBluez')
165 try:
166 discovery = Wammu.BluezDiscovery.Discovery(self)
167 discovery.find_devices()
168 discovery.process_inquiry()
169 if len(discovery.names_found) == 0 and self.msgcallback != None:
170 self.msgcallback(_('No Bluetooth device found'))
171 if self.msgcallback != None:
172 self.msgcallback(_('Bluetooth device scan completed'))
173 except bluetooth.BluetoothError, txt:
174 if self.msgcallback != None:
175 self.msgcallback(
176 _('Could not access Bluetooth subsystem (%s)') %
177 StrConv(txt))
179 def bluetooth_device_search(self):
181 Initiates searching for Bluetooth devices.
183 if not self.limit in ['all', 'bluetooth']:
184 return
185 if BLUETOOTH == 'bluez':
186 self.bluetooth_device_search_bluez()
187 else:
188 if self.msgcallback != None:
189 self.msgcallback(_('PyBluez not found, it is not possible to scan for Bluetooth devices.'))
190 if self.noticecallback != None:
191 self.noticecallback(
192 _('No Bluetooth searching'),
193 _('PyBluez not found, it is not possible to scan for Bluetooth devices.'))
195 def run(self):
196 try:
197 self.listed_device_search()
198 self.bluetooth_device_search()
200 i = 0
201 while len(self.threads) > 0:
202 if self.threads[i].isAlive():
203 i += 1
204 else:
205 if self.msgcallback != None:
206 self.msgcallback(_('Finished %s') %
207 StrConv(self.threads[i].getName()))
208 del self.threads[i]
209 if i >= len(self.threads):
210 i = 0
211 if self.msgcallback != None:
212 self.msgcallback(_('All finished, found %d phones') %
213 len(self.list))
214 if self.callback != None:
215 self.callback(self.list)
216 except:
217 evt = Wammu.Events.ExceptionEvent(data = sys.exc_info())
218 wx.PostEvent(self.win, evt)
220 class SearchThread(threading.Thread):
221 def __init__(self,
222 device,
223 connections,
224 lst,
225 listlock,
226 lock = False,
227 level = 'nothing',
228 win = None):
229 threading.Thread.__init__(self)
230 self.device = device
231 self.connections = connections
232 self.lock = lock
233 self.win = win
234 self.level = level
235 self.list = lst
236 self.listlock = listlock
238 def try_connection(self, connection):
240 Performs test on single connection.
242 gsm = gammu.StateMachine()
243 cfg = {
244 'StartInfo': False,
245 'UseGlobalDebugFile': True,
246 'DebugFile': '',
247 'SyncTime': False,
248 'Connection': connection,
249 'LockDevice': self.lock,
250 'DebugLevel': self.level,
251 'Device': self.device,
252 'Model': ''
255 # Compatibility with old Gammu versions
256 cfg = Wammu.Utils.CompatConfig(cfg)
258 gsm.SetConfig(0, cfg)
260 # Compatibility with old Gammu versions
261 cfg = Wammu.Utils.CompatConfig(cfg)
263 try:
264 if self.level == 'textall':
265 print 'Trying at %s using %s' % (self.device, connection)
266 gsm.Init()
267 self.listlock.acquire()
268 self.list.append((
269 self.device,
270 connection,
271 gsm.GetModel(),
272 gsm.GetManufacturer()
274 self.listlock.release()
275 if self.level != 'nothing':
276 print '!!Found model %s at %s using %s' % (
277 gsm.GetModel(),
278 self.device,
279 connection)
280 return
281 except gammu.GSMError:
282 if self.level == 'textall':
283 print 'Failed at %s using %s' % (self.device, connection)
285 def run(self):
287 Tests all listed connections.
289 try:
290 for conn in self.connections:
291 self.try_connection(conn)
292 except:
293 evt = Wammu.Events.ExceptionEvent(data = sys.exc_info())
294 wx.PostEvent(self.win, evt)
296 class PhoneInfoThread(threading.Thread):
297 def __init__(self, win, device, connection):
298 threading.Thread.__init__(self)
299 self.device = device
300 self.connection = connection
301 self.result = None
302 self.win = win
304 def run(self):
305 if self.connection.lower().find('blue') == -1 and self.connection.lower().find('irda') == -1:
306 res = Wammu.Utils.CheckDeviceNode(self.device)
307 if res[0] != 0:
308 evt = Wammu.Events.DataEvent(
309 data = None,
310 error = (res[2], res[3]))
311 wx.PostEvent(self.win, evt)
312 return
313 try:
314 sm = gammu.StateMachine()
315 cfg = {
316 'StartInfo': False,
317 'UseGlobalDebugFile': True,
318 'DebugFile': '',
319 'SyncTime': False,
320 'Connection': self.connection,
321 'LockDevice': 'no',
322 'DebugLevel': 'nothing',
323 'Device': self.device,
324 'Model': '',
327 # Compatibility with old Gammu versions
328 cfg = Wammu.Utils.CompatConfig(cfg)
330 sm.SetConfig(0, cfg)
331 sm.Init()
332 self.result = {
333 'Model': sm.GetModel(),
334 'Manufacturer': sm.GetManufacturer(),
336 evt = Wammu.Events.DataEvent(data = self.result)
337 wx.PostEvent(self.win, evt)
338 except gammu.GSMError, val:
339 info = val[0]
340 evt = Wammu.Events.DataEvent(
341 data = None,
342 error = (_('Failed to connect to phone'),
343 Wammu.Utils.FormatError('', info)
345 wx.PostEvent(self.win, evt)