class _ISkypeAPI(_ISkypeAPIBase): def __init__(self, handler, opts): _ISkypeAPIBase.__init__(self, opts) self.RegisterHandler(handler) self.skype_in = self.skype_out = self.dbus_name_owner_watch = None self.bus = opts.pop('Bus', None) try: mainloop = opts.pop('MainLoop') if self.bus is not None: raise TypeError( 'Bus and MainLoop cannot be used at the same time!') except KeyError: if self.bus is None: import dbus.mainloop.glib import gobject gobject.threads_init() dbus.mainloop.glib.threads_init() mainloop = dbus.mainloop.glib.DBusGMainLoop() self.mainloop = gobject.MainLoop() if self.bus is None: from dbus import SessionBus self.bus = SessionBus(private=True, mainloop=mainloop) if opts: raise TypeError('Unexpected parameter(s): %s' % ', '.join(opts.keys())) def run(self): self.DebugPrint('thread started') if hasattr(self, 'mainloop'): self.mainloop.run() self.DebugPrint('thread finished') def Close(self): if hasattr(self, 'mainloop'): self.mainloop.quit() self.skype_in = self.skype_out = None if self.dbus_name_owner_watch is not None: self.bus.remove_signal_receiver(self.dbus_name_owner_watch) self.dbus_name_owner_watch = None self.DebugPrint('closed') def SetFriendlyName(self, FriendlyName): self.FriendlyName = FriendlyName if self.skype_out: self.SendCommand(ICommand(-1, 'NAME %s' % FriendlyName)) def StartWatcher(self): self.dbus_name_owner_watch = self.bus.add_signal_receiver( self.dbus_name_owner_changed, 'NameOwnerChanged', 'org.freedesktop.DBus', 'org.freedesktop.DBus', '/org/freedesktop/DBus', arg0='com.Skype.API') def __Attach_ftimeout(self): self.wait = False def Attach(self, Timeout=30000, Wait=True): try: if not self.isAlive(): self.StartWatcher() self.start() except AssertionError: pass try: self.wait = True t = threading.Timer(Timeout / 1000.0, self.__Attach_ftimeout) if Wait: t.start() while self.wait: if not Wait: self.wait = False try: if not self.skype_out: self.skype_out = self.bus.get_object( 'com.Skype.API', '/com/Skype') if not self.skype_in: self.skype_in = _SkypeNotifyCallback( self.bus, self.notify) except dbus.DBusException: if not Wait: break time.sleep(1.0) else: break else: raise ISkypeAPIError('Skype attach timeout') finally: t.cancel() c = ICommand(-1, 'NAME %s' % self.FriendlyName, '', True, Timeout) if self.skype_out: self.SendCommand(c) if c.Reply != 'OK': self.skype_out = None self.SetAttachmentStatus(apiAttachRefused) return self.SendCommand(ICommand(-1, 'PROTOCOL %s' % self.Protocol)) self.SetAttachmentStatus(apiAttachSuccess) def IsRunning(self): try: self.bus.get_object('com.Skype.API', '/com/Skype') return True except dbus.DBusException: return False def Start(self, Minimized=False, Nosplash=False): # options are not supported as of Skype 1.4 Beta for Linux if not self.IsRunning(): import os if os.fork() == 0: # we're child os.setsid() os.execlp('skype') def Shutdown(self): import os from signal import SIGINT fh = os.popen('ps -o %p --no-heading -C skype') pid = fh.readline().strip() fh.close() if pid: os.kill(int(pid), SIGINT) self.skype_in = self.skype_out = None def SendCommand(self, Command): if not self.skype_out: self.Attach(Command.Timeout) self.CommandsStackPush(Command) self.CallHandler('send', Command) com = u'#%d %s' % (Command.Id, Command.Command) self.DebugPrint('->', repr(com)) if Command.Blocking: Command._event = event = threading.Event() else: Command._timer = timer = threading.Timer(Command.Timeout / 1000.0, self.CommandsStackPop, (Command.Id, )) try: result = self.skype_out.Invoke(com) except dbus.DBusException, err: raise ISkypeAPIError(str(err)) if result.startswith(u'#%d ' % Command.Id): self.notify(result) if Command.Blocking: event.wait(Command.Timeout / 1000.0) if not event.isSet(): raise ISkypeAPIError('Skype command timeout') else: timer.start()
class _ISkypeAPI(_ISkypeAPIBase): def __init__(self, handler, opts): _ISkypeAPIBase.__init__(self, opts) self.RegisterHandler(handler) self.skype_in = self.skype_out = self.dbus_name_owner_watch = None self.bus = opts.pop('Bus', None) try: mainloop = opts.pop('MainLoop') if self.bus is not None: raise TypeError('Bus and MainLoop cannot be used at the same time!') except KeyError: if self.bus is None: import dbus.mainloop.glib import gobject gobject.threads_init() dbus.mainloop.glib.threads_init() mainloop = dbus.mainloop.glib.DBusGMainLoop() self.mainloop = gobject.MainLoop() if self.bus is None: from dbus import SessionBus self.bus = SessionBus(private=True, mainloop=mainloop) if opts: raise TypeError('Unexpected parameter(s): %s' % ', '.join(opts.keys())) def run(self): self.DebugPrint('thread started') if hasattr(self, 'mainloop'): self.mainloop.run() self.DebugPrint('thread finished') def Close(self): if hasattr(self, 'mainloop'): self.mainloop.quit() self.skype_in = self.skype_out = None if self.dbus_name_owner_watch is not None: self.bus.remove_signal_receiver(self.dbus_name_owner_watch) self.dbus_name_owner_watch = None self.DebugPrint('closed') def SetFriendlyName(self, FriendlyName): self.FriendlyName = FriendlyName if self.skype_out: self.SendCommand(ICommand(-1, 'NAME %s' % FriendlyName)) def StartWatcher(self): self.dbus_name_owner_watch = self.bus.add_signal_receiver(self.dbus_name_owner_changed, 'NameOwnerChanged', 'org.freedesktop.DBus', 'org.freedesktop.DBus', '/org/freedesktop/DBus', arg0='com.Skype.API') def __Attach_ftimeout(self): self.wait = False def Attach(self, Timeout=30000, Wait=True): try: if not self.isAlive(): self.StartWatcher() self.start() except AssertionError: pass try: self.wait = True t = threading.Timer(Timeout / 1000.0, self.__Attach_ftimeout) if Wait: t.start() while self.wait: if not Wait: self.wait = False try: if not self.skype_out: self.skype_out = self.bus.get_object('com.Skype.API', '/com/Skype') if not self.skype_in: self.skype_in = _SkypeNotifyCallback(self.bus, self.notify) except dbus.DBusException: if not Wait: break time.sleep(1.0) else: break else: raise ISkypeAPIError('Skype attach timeout') finally: t.cancel() c = ICommand(-1, 'NAME %s' % self.FriendlyName, '', True, Timeout) if self.skype_out: self.SendCommand(c) if c.Reply != 'OK': self.skype_out = None self.SetAttachmentStatus(apiAttachRefused) return self.SendCommand(ICommand(-1, 'PROTOCOL %s' % self.Protocol)) self.SetAttachmentStatus(apiAttachSuccess) def IsRunning(self): try: self.bus.get_object('com.Skype.API', '/com/Skype') return True except dbus.DBusException: return False def Start(self, Minimized=False, Nosplash=False): # options are not supported as of Skype 1.4 Beta for Linux if not self.IsRunning(): import os if os.fork() == 0: # we're child os.setsid() os.execlp('skype') def Shutdown(self): import os from signal import SIGINT fh = os.popen('ps -o %p --no-heading -C skype') pid = fh.readline().strip() fh.close() if pid: os.kill(int(pid), SIGINT) self.skype_in = self.skype_out = None def SendCommand(self, Command): if not self.skype_out: self.Attach(Command.Timeout) self.CommandsStackPush(Command) self.CallHandler('send', Command) com = u'#%d %s' % (Command.Id, Command.Command) self.DebugPrint('->', repr(com)) if Command.Blocking: Command._event = event = threading.Event() else: Command._timer = timer = threading.Timer(Command.Timeout / 1000.0, self.CommandsStackPop, (Command.Id,)) try: result = self.skype_out.Invoke(com) except dbus.DBusException, err: raise ISkypeAPIError(str(err)) if result.startswith(u'#%d ' % Command.Id): self.notify(result) if Command.Blocking: event.wait(Command.Timeout / 1000.0) if not event.isSet(): raise ISkypeAPIError('Skype command timeout') else: timer.start()