PyXR

c:\projects\bitpim\src \ comm_notify.py



0001 ### BITPIM
0002 ###
0003 ### Copyright (C) 2006 Joe Pham <djpham@bitpim.org>
0004 ###
0005 ### This program is free software; you can redistribute it and/or modify
0006 ### it under the terms of the BitPim license as detailed in the LICENSE file.
0007 ###
0008 ### $Id: comm_notify.py 4219 2007-05-09 02:15:50Z djpham $
0009 
0010 """Handle notification of comm ports availability using DNOTIFY"""
0011 
0012 import fcntl
0013 import os
0014 import signal
0015 import sys
0016 
0017 import wx
0018 
0019 bpCOMM_NOTIFICATION_EVENT = wx.NewEventType()
0020 COMM_NOTIFICATION_EVENT = wx.PyEventBinder(bpCOMM_NOTIFICATION_EVENT, 0)
0021 default_port=5002
0022 
0023 class CommNotificationEvent(wx.PyEvent):
0024     add=0
0025     remove=1
0026     def __init__(self):
0027         super(CommNotificationEvent, self).__init__()
0028         self.SetEventType=bpCOMM_NOTIFICATION_EVENT
0029         self.type=None
0030         self.comm=None
0031 
0032 class CommNotification(object):
0033     def __init__(self, mainwindow):
0034         self.mw=mainwindow
0035         self.evt=CommNotificationEvent()
0036 
0037     def add(self, comm):
0038         # a new comm has just been added
0039         self.evt.type=CommNotificationEvent.add
0040         if comm.startswith('/proc/bus/usb/') or \
0041            comm.startswith('/dev/bus/usb/'):
0042             # this is a Linux hotplug USB port, which may have many interfaces.
0043             # can't figure which one so scan for all ports.
0044             self.evt.comm=None
0045         else:
0046             self.evt.comm=comm
0047         self.mw.OnCommNotification(self.evt)
0048         return True
0049 
0050     def remove(self, comm):
0051         # a new comm has just been deleted
0052         if comm.startswith('/proc/bus/usb/') or \
0053            comm.startswith('/dev/bus/usb/'):
0054             # This is a Linux hotplug USB port, just ignore it
0055             return False
0056         self.evt.type=CommNotificationEvent.remove
0057         self.evt.comm=comm
0058         self.mw.OnCommNotification(self.evt)
0059         return True
0060 
0061 NotificationPath='/var/bitpim'
0062 NotificationFile='/var/bitpim/dnotify.log'
0063 
0064 def _process_notification(commobj):
0065     # read the log file & process its content
0066     # expecting a line: add|del <port>
0067     global NotificationFile
0068     try:
0069         _s=file(NotificationFile, 'rt').read()
0070         _tkns=_s.split(' ')
0071         if len(_tkns)==2:
0072             if _tkns[0]=='add':
0073                 commobj.add(_tkns[1])
0074             else:
0075                 commobj.remove(_tkns[1])
0076     except:
0077         if __debug__:
0078             raise
0079 
0080 _global_fd=None
0081 _global_obj=None
0082 
0083 def _sigio_handler(*args, **kwargs):
0084     global _global_obj
0085     if _global_obj:
0086         wx.CallAfter(_process_notification, _global_obj)
0087 
0088 def run_server(mainwindow):
0089     global NotificationPath, _global_fd, _global_obj
0090     _global_obj=CommNotification(mainwindow)
0091     try:
0092         _global_fd=os.open(NotificationPath, os.O_RDONLY)
0093     except OSError:
0094         # Something's wrong with the dir, bail
0095         mainwindow.log('Failed to open dir '+NotificationPath)
0096         return False
0097     except:
0098         if __debug__:
0099             raise
0100         return False
0101     fcntl.fcntl(_global_fd, fcntl.F_NOTIFY,
0102                 fcntl.DN_MODIFY|fcntl.DN_CREATE|fcntl.DN_MULTISHOT)
0103     mainwindow.log('USB Comm Watch started')
0104     return True
0105 
0106 def start_server(mainwindow):
0107     signal.signal(signal.SIGIO, _sigio_handler)
0108     return run_server(mainwindow)
0109 

Generated by PyXR 0.9.4