tux-droid-svn Mailing List for Tux Droid CE (Page 19)
Status: Beta
Brought to you by:
ks156
You can subscribe to this list here.
| 2007 |
Jan
|
Feb
(32) |
Mar
(108) |
Apr
(71) |
May
(38) |
Jun
(128) |
Jul
(1) |
Aug
(14) |
Sep
(77) |
Oct
(104) |
Nov
(90) |
Dec
(71) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2008 |
Jan
(81) |
Feb
(18) |
Mar
(40) |
Apr
(102) |
May
(151) |
Jun
(74) |
Jul
(151) |
Aug
(257) |
Sep
(447) |
Oct
(379) |
Nov
(404) |
Dec
(430) |
| 2009 |
Jan
(173) |
Feb
(236) |
Mar
(519) |
Apr
(300) |
May
(112) |
Jun
(232) |
Jul
(314) |
Aug
(58) |
Sep
(203) |
Oct
(293) |
Nov
(26) |
Dec
(109) |
| 2010 |
Jan
(19) |
Feb
(25) |
Mar
(33) |
Apr
(1) |
May
|
Jun
(3) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: jerome <c2m...@c2...> - 2009-10-01 14:32:03
|
Author: jerome
Date: 2009-10-01 14:23:33 +0200 (Thu, 01 Oct 2009)
New Revision: 5578
Added:
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/LICENSE
Modified:
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/__init__.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/application.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/call.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/callchannel.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/chat.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/client.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/conversion.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/enums.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/errors.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/filetransfer.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/profile.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/settings.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/skype.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/sms.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/user.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/utils.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/voicemail.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/plugin-skype.py
Log:
* Implemented Skype4Py 28th September release (1.0.32).
* Updated the way to retrive contacts list ( real time contacts update ).
* Improved Quit gadget function.
* Fixed X11 Transport bug.
* Fixed a bug Quitting Skype application ( gadget remained opened on Linux).
Added: software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/LICENSE
===================================================================
--- software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/LICENSE (rev 0)
+++ software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/LICENSE 2009-10-01 12:23:33 UTC (rev 5578)
@@ -0,0 +1,21 @@
+Copyright (c) 2007-2009, Arkadiusz Wahlig
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the name of Arkadiusz Wahlig nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
Modified: software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/__init__.py
===================================================================
--- software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/__init__.py 2009-10-01 12:21:30 UTC (rev 5577)
+++ software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/__init__.py 2009-10-01 12:23:33 UTC (rev 5578)
@@ -1,64 +1,118 @@
-#
-# Skype4Py
-#
-
-'''
+"""
Skype4Py is a multiplatform Skype API wrapper for Python.
- 1. Usage.
+Usage
+=====
- C{Skype4Py} is the package that you should import in your scripts to be able to access Skype.
- You won't need to import any submodules. Everything you may need will be available at the
- package level. This includes:
+ Everything that you should ever need is available as aliases in the ``Skype4Py`` package.
+ Import it using the standard form of the ``import`` statement:
+
+ .. python::
+
+ import Skype4Py
+
+ Importing the whole package into your script's namespace using ``from Skype4Py import *`` is
+ generally discouraged. You should also not access the modules in the package directly as they
+ are considered an implementation detail and may change in future versions without notice.
+
+ The package provides the following:
- - Classes
- - C{Skype4Py.Skype = L{Skype4Py.skype.ISkype}}
- - C{Skype4Py.CallChannelManager = L{Skype4Py.callchannel.ICallChannelManager}}
- - Constants
- - C{Skype4Py.* = L{Skype4Py.enums}.*}
- - Errors
- - C{Skype4Py.SkypeError = L{Skype4Py.errors.ISkypeError}}
- - C{Skype4Py.SkypeAPIError = L{Skype4Py.errors.ISkypeAPIError}}
+ - Classes
+
+ ``Skype4Py.Skype``, an alias for `Skype4Py.skype.Skype`
+
+ ``Skype4Py.CallChannelManager``, an alias for `Skype4Py.callchannel.CallChannelManager`
+
+ - Constants
+
+ Everything from the `Skype4Py.enums` module.
- The first two are the only classes that you will be instatinating directly. Calling their methods/properties
- will give you the access to instances of all other classes, you won't have to instatinate them yourself.
- The two classes are also the only ones that provide event handlers (see [3]).
+ ``platform``, either ``'windows'``, ``'posix'`` or ``'darwin'`` depending
+ on the current platform (Windows, Linux, Mac OS X).
+
+ - Errors
+
+ ``Skype4Py.SkypeError``, an alias for `Skype4Py.errors.SkypeError`
+
+ ``Skype4Py.SkypeAPIError``, an alias for `Skype4Py.errors.SkypeAPIError`
- Every Skype4Py script instatinates the C{Skype4Py.Skype} class at least once. That's what you want to do
- first in your script. Then follow the L{Skype4Py.skype.ISkype} reference to see where you can get from
- there.
+ The two classes exposed by the ``Skype4Py`` package are the only ones that are to be instantiated
+ directly. They in turn provide means of instantiating the remaining ones. They are also the only
+ classes that provide event handlers (for more information about events and how to use them, see
+ the `EventHandlingBase` class.
+
+ Every Skype4Py script instantiates at least the ``Skype4Py.Skype`` class which gives access to
+ the Skype client running currently in the system. Follow the `Skype4Py.skype.Skype` reference to
+ see what you can do with it.
- 2. Quick example.
+ **Warning!** While reading this documentation, it is important to keep in mind that everything
+ needed is in the top package level because the documentation refers to all objects in the places
+ they actually live.
- This short example connects to Skype client and prints the user's full name and the names of all the
- contacts from the contacts list::
+Quick example
+=============
- import Skype4Py
+ This short example connects to Skype client and prints the user's full name and the names of all the
+ contacts from the contacts list:
- # Create Skype instance
- skype = Skype4Py.Skype()
+ .. python::
- # Connect Skype object to Skype client
- skype.Attach()
+ import Skype4Py
- print 'Your full name:', skype.CurrentUser.FullName
- print 'Your contacts:'
- for user in skype.Friends:
- print ' ', user.FullName
+ # Create an instance of the Skype class.
+ skype = Skype4Py.Skype()
-@author: U{Arkadiusz Wahlig<ya...@no...>}
-@requires: Python 2.4 or newer
-@see: U{The Skype4Py webpage<https://developer.skype.com/wiki/Skype4Py>}
-@license: BSD License (see the accompanying LICENSE file for more information)
-@copyright: S{copy} 2007 Arkadiusz Wahlig
-'''
+ # Connect the Skype object to the Skype client.
+ skype.Attach()
-from skype import ISkype as Skype
-from callchannel import ICallChannelManager as CallChannelManager
-from errors import ISkypeError as SkypeError, ISkypeAPIError as SkypeAPIError
+ # Obtain some information from the client and print it out.
+ print 'Your full name:', skype.CurrentUser.FullName
+ print 'Your contacts:'
+ for user in skype.Friends:
+ print ' ', user.FullName
+
+Note on the naming convention
+=============================
+
+ Skype4Py uses two different naming conventions. The first one applies to interfaces derived from
+ Skype4COM_, a COM library which was an inspiration for Skype4Py. This convention uses the ``CapCase``
+ scheme for class names, properties, methods and their arguments. The constants use the ``mixedCase``
+ scheme.
+
+ The second naming convention is more "Pythonic" and is used by all other parts of the package
+ including internal objects. It uses mostly the same ``CapCase`` scheme for class names (including
+ exception names) with a small difference in abbreviations. Where the first convention would use
+ a ``SkypeApiError`` name, the second one uses ``SkypeAPIError``. Other names including properties,
+ methods, arguments, variables and module names use lowercase letters with underscores.
+
+.. _Skype4COM: https://developer.skype.com/Docs/Skype4COM
+.. |copy| unicode:: U+000A9
+
+:author: Arkadiusz Wahlig <ark...@gm...>
+:requires: Python 2.4 up until but not including 3.0.
+:see: The Skype4Py website: https://developer.skype.com/wiki/Skype4Py
+:license: BSD License (see the accompanying LICENSE file for more information)
+:copyright: |copy| 2007-2009 Arkadiusz Wahlig
+"""
+__docformat__ = 'restructuredtext en'
+
+
+from skype import Skype
+from callchannel import CallChannelManager
+from errors import SkypeError, SkypeAPIError
from enums import *
+from api import platform
+import logging
-__version__ = '1.0.29.0'
-'''The version of Skype4Py.'''
+__version__ = '1.0.32.0'
+"""The version of Skype4Py."""
+
+class NullHandler(logging.Handler):
+ def emit(self, record):
+ pass
+
+
+# Suppress the "No handlers could be found for logger (...)" message.
+logging.getLogger('Skype4Py').addHandler(NullHandler())
Modified: software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/application.py
===================================================================
--- software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/application.py 2009-10-01 12:21:30 UTC (rev 5577)
+++ software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/application.py 2009-10-01 12:23:33 UTC (rev 5578)
@@ -1,236 +1,252 @@
-'''APP2APP protocol.
-'''
+"""APP2APP protocol.
+"""
+__docformat__ = 'restructuredtext en'
+
+import threading
+
from utils import *
from user import *
-import threading
-class IApplication(Cached):
- '''Represents an application in APP2APP protocol. Use L{ISkype.Application<skype.ISkype.Application>} to instatinate.
- '''
+class Application(Cached):
+ """Represents an application in APP2APP protocol. Use `skype.Skype.Application` to instantiate.
+ """
+ _ValidateHandle = staticmethod(tounicode)
def __repr__(self):
- return '<%s with Name=%s>' % (Cached.__repr__(self)[1:-1], repr(self.Name))
+ return Cached.__repr__(self, 'Name')
def _Alter(self, AlterName, Args=None):
- return self._Skype._Alter('APPLICATION', self._Name, AlterName, Args)
+ return self._Owner._Alter('APPLICATION', self.Name, AlterName, Args)
- def _Init(self, Name, Skype):
- self._Name = unicode(Name)
- self._Skype = Skype
+ def _Init(self):
+ self._MakeOwner()
def _Property(self, PropName, Set=None):
- return self._Skype._Property('APPLICATION', self._Name, PropName, Set)
+ return self._Owner._Property('APPLICATION', self.Name, PropName, Set)
+ def _Connect_ApplicationStreams(self, App, Streams):
+ if App == self:
+ s = [x for x in Streams if x.PartnerHandle == self._Connect_Username]
+ if s:
+ self._Connect_Stream[0] = s[0]
+ self._Connect_Event.set()
+
def Connect(self, Username, WaitConnected=False):
- '''Connects application to user.
+ """Connects application to user.
- @param Username: Name of the user to connect to.
- @type Username: unicode
- @param WaitConnected: If True, causes the method to wait untill the connection is established.
- @type WaitConnected: bool
- @return: If C{WaitConnected} is True, returns the stream which can be used to send the data.
- Otherwise returns None.
- @rtype: L{IApplicationStream} or None
- '''
+ :Parameters:
+ Username : str
+ Name of the user to connect to.
+ WaitConnected : bool
+ If True, causes the method to wait until the connection is established.
+
+ :return: If ``WaitConnected`` is True, returns the stream which can be used to send the
+ data. Otherwise returns None.
+ :rtype: `ApplicationStream` or None
+ """
if WaitConnected:
- event = threading.Event()
- stream = [None]
- def app_streams(App, Streams):
- if App == self:
- s = [x for x in Streams if x.PartnerHandle == Username]
- if s:
- stream[0] = s[0]
- event.set()
- app_streams(self, self.Streams)
- self._Skype.RegisterEventHandler('ApplicationStreams', app_streams)
+ self._Connect_Event = threading.Event()
+ self._Connect_Stream = [None]
+ self._Connect_Username = Username
+ self._Connect_ApplicationStreams(self, self.Streams)
+ self._Owner.RegisterEventHandler('ApplicationStreams', self._Connect_ApplicationStreams)
self._Alter('CONNECT', Username)
- event.wait()
- self._Skype.UnregisterEventHandler('ApplicationStreams', app_streams)
- return stream[0]
+ self._Connect_Event.wait()
+ self._Owner.UnregisterEventHandler('ApplicationStreams', self._Connect_ApplicationStreams)
+ try:
+ return self._Connect_Stream[0]
+ finally:
+ del self._Connect_Stream, self._Connect_Event, self._Connect_Username
else:
self._Alter('CONNECT', Username)
def Create(self):
- '''Creates the APP2APP application in Skype client.
- '''
- self._Skype._DoCommand('CREATE APPLICATION %s' % self._Name)
+ """Creates the APP2APP application in Skype client.
+ """
+ self._Owner._DoCommand('CREATE APPLICATION %s' % self.Name)
def Delete(self):
- '''Deletes the APP2APP application in Skype client.
- '''
- self._Skype._DoCommand('DELETE APPLICATION %s' % self._Name)
+ """Deletes the APP2APP application in Skype client.
+ """
+ self._Owner._DoCommand('DELETE APPLICATION %s' % self.Name)
def SendDatagram(self, Text, Streams=None):
- '''Sends datagram to application streams.
+ """Sends datagram to application streams.
- @param Text: Text to send.
- @type Text: unicode
- @param Streams: Streams to send the datagram to or None if all currently connected streams should be used.
- @type Streams: sequence of L{IApplicationStream}
- '''
- if Streams == None:
+ :Parameters:
+ Text : unicode
+ Text to send.
+ Streams : sequence of `ApplicationStream`
+ Streams to send the datagram to or None if all currently connected streams should be
+ used.
+ """
+ if Streams is None:
Streams = self.Streams
for s in Streams:
s.SendDatagram(Text)
def _GetConnectableUsers(self):
- return tuple(IUser(x, self._Skype) for x in esplit(self._Property('CONNECTABLE')))
+ return UserCollection(self._Owner, split(self._Property('CONNECTABLE')))
ConnectableUsers = property(_GetConnectableUsers,
- doc='''All connectable users.
+ doc="""All connectible users.
- @type: tuple of L{IUser}
- ''')
+ :type: `UserCollection`
+ """)
def _GetConnectingUsers(self):
- return tuple(IUser(x, self._Skype) for x in esplit(self._Property('CONNECTING')))
+ return UserCollection(self._Owner, split(self._Property('CONNECTING')))
ConnectingUsers = property(_GetConnectingUsers,
- doc='''All users connecting at the moment.
+ doc="""All users connecting at the moment.
- @type: tuple of L{IUser}
- ''')
+ :type: `UserCollection`
+ """)
def _GetName(self):
- return self._Name
+ return self._Handle
Name = property(_GetName,
- doc='''Name of the application.
+ doc="""Name of the application.
- @type: unicode
- ''')
+ :type: unicode
+ """)
def _GetReceivedStreams(self):
- return tuple(IApplicationStream(x.split('=')[0], self) for x in esplit(self._Property('RECEIVED')))
+ return ApplicationStreamCollection(self, (x.split('=')[0] for x in split(self._Property('RECEIVED'))))
ReceivedStreams = property(_GetReceivedStreams,
- doc='''All streams that received data and can be read.
+ doc="""All streams that received data and can be read.
- @type: tuple of L{IApplicationStream}
- ''')
+ :type: `ApplicationStreamCollection`
+ """)
def _GetSendingStreams(self):
- return tuple(IApplicationStream(x.split('=')[0], self) for x in esplit(self._Property('SENDING')))
+ return ApplicationStreamCollection(self, (x.split('=')[0] for x in split(self._Property('SENDING'))))
SendingStreams = property(_GetSendingStreams,
- doc='''All streams that send data and at the moment.
+ doc="""All streams that send data and at the moment.
- @type: tuple of L{IApplicationStream}
- ''')
+ :type: `ApplicationStreamCollection`
+ """)
def _GetStreams(self):
- return tuple(IApplicationStream(x, self) for x in esplit(self._Property('STREAMS')))
+ return ApplicationStreamCollection(self, split(self._Property('STREAMS')))
Streams = property(_GetStreams,
- doc='''All currently connected application streams.
+ doc="""All currently connected application streams.
- @type: tuple of L{IApplicationStream}
- ''')
+ :type: `ApplicationStreamCollection`
+ """)
-class IApplicationStream(Cached):
- '''Represents an application stream in APP2APP protocol.
- '''
+class ApplicationStream(Cached):
+ """Represents an application stream in APP2APP protocol.
+ """
+ _ValidateHandle = str
def __len__(self):
return self.DataLength
def __repr__(self):
- return '<%s with Handle=%s, Application=%s>' % (Cached.__repr__(self)[1:-1], repr(self.Handle), repr(self.Application))
+ return Cached.__repr__(self, 'Handle')
- def _Init(self, Handle, Application):
- self._Handle = Handle
- self._Application = Application
-
def Disconnect(self):
- '''Disconnects the stream.
- '''
- self._Application._Alter('DISCONNECT', self._Handle)
+ """Disconnects the stream.
+ """
+ self.Application._Alter('DISCONNECT', self.Handle)
close = Disconnect
def Read(self):
- '''Reads data from stream.
+ """Reads data from stream.
- @return: Read data or an empty string if none were available.
- @rtype: unicode
- '''
- return self._Application._Alter('READ', self._Handle)
+ :return: Read data or an empty string if none were available.
+ :rtype: unicode
+ """
+ return self.Application._Alter('READ', self.Handle)
read = Read
def SendDatagram(self, Text):
- '''Sends datagram to stream.
+ """Sends datagram to stream.
- @param Text: Datagram to send.
- @type Text: unicode
- '''
- self._Application._Alter('DATAGRAM', '%s %s' % (self._Handle, Text))
+ :Parameters:
+ Text : unicode
+ Datagram to send.
+ """
+ self.Application._Alter('DATAGRAM', '%s %s' % (self.Handle, tounicode(Text)))
def Write(self, Text):
- '''Writes data to stream.
+ """Writes data to stream.
- @param Text: Data to send.
- @type Text: unicode
- '''
- self._Application._Alter('WRITE', '%s %s' % (self._Handle, Text))
+ :Parameters:
+ Text : unicode
+ Data to send.
+ """
+ self.Application._Alter('WRITE', '%s %s' % (self.Handle, tounicode(Text)))
write = Write
def _GetApplication(self):
- return self._Application
+ return self._Owner
Application = property(_GetApplication,
- doc='''Application this stream belongs to.
+ doc="""Application this stream belongs to.
- @type: L{IApplication}
- ''')
+ :type: `Application`
+ """)
def _GetApplicationName(self):
- return self._Application.Name
+ return self.Application.Name
ApplicationName = property(_GetApplicationName,
- doc='''Name of the application this stream belongs to. Same as C{IApplicationStream.Application.Name}.
+ doc="""Name of the application this stream belongs to. Same as ``ApplicationStream.Application.Name``.
- @type: unicode
- ''')
+ :type: unicode
+ """)
+ def _GetDataLength_GetStreamLength(self, Type):
+ for s in split(self.Application._Property(Type)):
+ h, i = s.split('=')
+ if h == self.Handle:
+ return int(i)
+
def _GetDataLength(self):
- def GetStreamLength(Type):
- for s in esplit(self._Application._Property(Type)):
- h, i = s.split('=')
- if h == self._Handle:
- return int(i)
- i = GetStreamLength('SENDING')
- if i != None:
+ i = self._GetDataLength_GetStreamLength('SENDING')
+ if i is not None:
return i
- i = GetStreamLength('RECEIVED')
- if i != None:
+ i = self._GetDataLength_GetStreamLength('RECEIVED')
+ if i is not None:
return i
return 0
DataLength = property(_GetDataLength,
- doc='''Number of bytes awaiting in the read buffer.
+ doc="""Number of bytes awaiting in the read buffer.
- @type: int
- ''')
+ :type: int
+ """)
def _GetHandle(self):
return self._Handle
Handle = property(_GetHandle,
- doc='''Stream handle in u'<Skypename>:<n>' format.
+ doc="""Stream handle in u'<Skypename>:<n>' format.
- @type: unicode
- ''')
+ :type: str
+ """)
def _GetPartnerHandle(self):
- return self._Handle.split(':')[0]
+ return self.Handle.split(':')[0]
PartnerHandle = property(_GetPartnerHandle,
- doc='''Skypename of the user this stream is connected to.
+ doc="""Skypename of the user this stream is connected to.
- @type: unicode
- ''')
+ :type: str
+ """)
+
+
+class ApplicationStreamCollection(CachedCollection):
+ _CachedType = ApplicationStream
Modified: software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/call.py
===================================================================
--- software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/call.py 2009-10-01 12:21:30 UTC (rev 5577)
+++ software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/call.py 2009-10-01 12:23:33 UTC (rev 5578)
@@ -1,644 +1,709 @@
-'''Calls, conferences.
-'''
+"""Calls, conferences.
+"""
+__docformat__ = 'restructuredtext en'
+
+from types import NoneType
+
from utils import *
from enums import *
-from errors import *
-class ICall(Cached):
- '''Represents a voice/video call.
- '''
+class DeviceMixin(object):
+ def _Device(self, Name, DeviceType=None, Set=NoneType):
+ args = args2dict(self._Property(Name, Cache=False))
+ if Set is NoneType:
+ for dev, value in args.items():
+ try:
+ args[dev] = int(value)
+ except ValueError:
+ pass
+ if DeviceType is None:
+ return args
+ return args.get(DeviceType, None)
+ elif DeviceType is None:
+ raise TypeError('DeviceType must be specified if Set is used')
+ if Set:
+ args[DeviceType] = tounicode(Set)
+ else:
+ args.pop(DeviceType, None)
+ for dev, value in args.items():
+ args[dev] = quote(value, True)
+ self._Alter('SET_%s' % Name,
+ ', '.join('%s=%s' % item for item in args.items()))
+ def CaptureMicDevice(self, DeviceType=None, Set=NoneType):
+ """Queries or sets the mic capture device.
+
+ :Parameters:
+ DeviceType : `enums`.callIoDeviceType* or None
+ Mic capture device type.
+ Set
+ Value the device should be set to or None if it should be deactivated.
+
+ Querying all active devices:
+ Devices = CaptureMicDevice()
+
+ Returns a mapping of device types to their values. Only active devices are
+ returned.
+
+ Querying a specific device:
+ Value = CaptureMicDevice(DeviceType)
+
+ Returns a device value for the given DeviceType.
+
+ Setting a device value:
+ CaptureMicDevice(DeviceType, Value)
+
+ If Value is None, the device will be deactivated.
+
+ :note: This command functions for active calls only.
+ """
+ return self._Device('CAPTURE_MIC', DeviceType, Set)
+
+ def InputDevice(self, DeviceType=None, Set=NoneType):
+ """Queries or sets the sound input device.
+
+ :Parameters:
+ DeviceType : `enums`.callIoDeviceType* or None
+ Sound input device type.
+ Set
+ Value the device should be set to or None if it should be deactivated.
+
+ Querying all active devices:
+ Devices = InputDevice()
+
+ Returns a mapping of device types to their values. Only active devices are
+ returned.
+
+ Querying a specific device:
+ Value = InputDevice(DeviceType)
+
+ Returns a device value for the given DeviceType.
+
+ Setting a device value:
+ InputDevice(DeviceType, Value)
+
+ If Value is None, the device will be deactivated.
+
+ :note: This command functions for active calls only.
+ """
+ return self._Device('INPUT', DeviceType, Set)
+
+ def OutputDevice(self, DeviceType=None, Set=NoneType):
+ """Queries or sets the sound output device.
+
+ :Parameters:
+ DeviceType : `enums`.callIoDeviceType* or None
+ Sound output device type.
+ Set
+ Value the device should be set to or None if it should be deactivated.
+
+ Querying all active devices:
+ Devices = OutputDevice()
+
+ Returns a mapping of device types to their values. Only active devices are
+ returned.
+
+ Querying a specific device:
+ Value = OutputDevice(DeviceType)
+
+ Returns a device value for the given DeviceType.
+
+ Setting a device value:
+ OutputDevice(DeviceType, Value)
+
+ If Value is None, the device will be deactivated.
+
+ :note: This command functions for active calls only.
+ """
+ return self._Device('OUTPUT', DeviceType, Set)
+
+
+class Call(Cached, DeviceMixin):
+ """Represents a voice/video call.
+ """
+ _ValidateHandle = int
+
def __repr__(self):
- return '<%s with Id=%s>' % (Cached.__repr__(self)[1:-1], repr(self.Id))
+ return Cached.__repr__(self, 'Id')
def _Alter(self, AlterName, Args=None):
- return self._Skype._Alter('CALL', self._Id, AlterName, Args)
+ return self._Owner._Alter('CALL', self.Id, AlterName, Args)
- def _Init(self, Id, Skype):
- self._Skype = Skype
- self._Id = int(Id)
+ def _Init(self):
+ self._MakeOwner()
def _Property(self, PropName, Set=None, Cache=True):
- return self._Skype._Property('CALL', self._Id, PropName, Set, Cache)
+ return self._Owner._Property('CALL', self.Id, PropName, Set, Cache)
def Answer(self):
- '''Answers the call.
- '''
- self._Property('STATUS', 'INPROGRESS')
+ """Answers the call.
+ """
+ #self._Property('STATUS', 'INPROGRESS')
+ self._Alter('ANSWER')
def CanTransfer(self, Target):
- '''Queries if a call can be transferred to a contact or phone number.
+ """Queries if a call can be transferred to a contact or phone number.
- @param Target: Skypename or phone number the call is to be transfered to.
- @type Target: unicode
- @return: True if call can be transfered, False otherwise.
- @rtype: bool
- '''
+ :Parameters:
+ Target : str
+ Skypename or phone number the call is to be transferred to.
+
+ :return: True if call can be transferred, False otherwise.
+ :rtype: bool
+ """
return self._Property('CAN_TRANSFER %s' % Target) == 'TRUE'
- def CaptureMicDevice(self, DeviceType=None, Set=None):
- '''Queries or sets the mic capture device.
-
- @param DeviceType: Mic capture device type or None.
- @type DeviceType: L{Call IO device type<enums.callIoDeviceTypeUnknown>} or None
- @param Set: Value the device should be set to or None.
- @type Set: unicode, int or None
- @return: If DeviceType and Set are None, returns a dictionary of device types and their
- values. Dictionary contains only those device types, whose values were set. If the
- DeviceType is not None but Set is None, returns the current value of the device or
- None if the device wasn't set. If Set is not None, sets a new value for the device.
- @rtype: unicode, dict or None
-
- @note: This command functions for active calls only.
- '''
- if Set == None: # get
- args = args2dict(self._Property('CAPTURE_MIC', Cache=False))
- for t in args:
- if t == callIoDeviceTypePort:
- args[t] = int(args[t])
- if DeviceType == None: # get active devices
- return args
- return args.get(DeviceType, None)
- elif DeviceType != None: # set
- self._Alter('SET_CAPTURE_MIC', '%s=%s' % (DeviceType, quote(unicode(Set), True)))
- else:
- raise TypeError('DeviceType must be specified if Set is used')
-
def Finish(self):
- '''Ends the call.
- '''
- self._Property('STATUS', 'FINISHED')
+ """Ends the call.
+ """
+ #self._Property('STATUS', 'FINISHED')
+ self._Alter('END', 'HANGUP')
def Forward(self):
- '''Forwards a call.
- '''
+ """Forwards a call.
+ """
self._Alter('END', 'FORWARD_CALL')
def Hold(self):
- '''Puts the call on hold.
- '''
- self._Property('STATUS', 'ONHOLD')
+ """Puts the call on hold.
+ """
+ #self._Property('STATUS', 'ONHOLD')
+ self._Alter('HOLD')
- def InputDevice(self, DeviceType=None, Set=None):
- '''Queries or sets the sound input device.
+ def Join(self, Id):
+ """Joins with another call to form a conference.
- @param DeviceType: Sound input device type or None.
- @type DeviceType: L{Call IO device type<enums.callIoDeviceTypeUnknown>} or None
- @param Set: Value the device should be set to or None.
- @type Set: unicode, int or None
- @return: If DeviceType and Set are None, returns a dictionary of device types and their
- values. Dictionary contains only those device types, whose values were set. If the
- DeviceType is not None but Set is None, returns the current value of the device or
- None if the device wasn't set. If Set is not None, sets a new value for the device.
- @rtype: unicode, dict or None
+ :Parameters:
+ Id : int
+ Call Id of the other call to join to the conference.
- @note: This command functions for active calls only.
- '''
- if Set == None: # get
- args = args2dict(self._Property('INPUT', Cache=False))
- for t in args:
- if t == callIoDeviceTypePort:
- args[t] = int(args[t])
- if DeviceType == None: # get active devices
- return args
- return args.get(DeviceType, None)
- elif DeviceType != None: # set
- self._Alter('SET_INPUT', '%s=%s' % (DeviceType, quote(unicode(Set), True)))
- else:
- raise TypeError('DeviceType must be specified if Set is used')
+ :return: Conference object.
+ :rtype: `Conference`
+ """
+ #self._Alter('JOIN_CONFERENCE', Id)
+ reply = self._Owner._DoCommand('SET CALL %s JOIN_CONFERENCE %s' % (self.Id, Id),
+ 'CALL %s CONF_ID' % self.Id)
+ return Conference(self._Owner, reply.split()[-1])
- def Join(self, Id):
- '''Joins with another call to form a conference.
-
- @param Id: Call Id of the other call to join to the conference.
- @type Id: int
- @return: Conference object.
- @rtype: L{IConference}
- '''
- reply = self._Skype._DoCommand('SET CALL %s JOIN_CONFERENCE %s' % (self._Id, Id),
- 'CALL %s CONF_ID' % self._Id)
- return IConference(reply.split()[-1], self._Skype)
-
def MarkAsSeen(self):
- '''Marks the call as seen.
- '''
+ """Marks the call as seen.
+ """
self.Seen = True
- def OutputDevice(self, DeviceType=None, Set=None):
- '''Queries or sets the sound output device.
-
- @param DeviceType: Sound output device type or None.
- @type DeviceType: L{Call IO device type<enums.callIoDeviceTypeUnknown>} or None
- @param Set: Value the device should be set to or None.
- @type Set: unicode, int or None
- @return: If DeviceType and Set are None, returns a dictionary of device types and their
- values. Dictionary contains only those device types, whose values were set. If the
- DeviceType is not None but Set is None, returns the current value of the device or
- None if the device wasn't set. If Set is not None, sets a new value for the device.
- @rtype: unicode, dict or None
-
- @note: This command functions for active calls only.
- '''
- if Set == None: # get
- args = args2dict(self._Property('OUTPUT', Cache=False))
- for t in args:
- if t == callIoDeviceTypePort:
- args[t] = int(args[t])
- if DeviceType == None: # get active devices
- return args
- return args.get(DeviceType, None)
- elif DeviceType != None: # set
- self._Alter('SET_OUTPUT', '%s=%s' % (DeviceType, quote(unicode(Set), True)))
- else:
- raise TypeError('DeviceType must be specified if Set is used')
-
def RedirectToVoicemail(self):
- '''Redirects a call to voicemail.
- '''
+ """Redirects a call to voicemail.
+ """
self._Alter('END', 'REDIRECT_TO_VOICEMAIL')
def Resume(self):
- '''Resumes the held call.
- '''
- self.Answer()
+ """Resumes the held call.
+ """
+ #self.Answer()
+ self._Alter('RESUME')
def StartVideoReceive(self):
- '''Starts video receive.
- '''
+ """Starts video receive.
+ """
self._Alter('START_VIDEO_RECEIVE')
def StartVideoSend(self):
- '''Starts video send.
- '''
+ """Starts video send.
+ """
self._Alter('START_VIDEO_SEND')
def StopVideoReceive(self):
- '''Stops video receive.
- '''
+ """Stops video receive.
+ """
self._Alter('STOP_VIDEO_RECEIVE')
def StopVideoSend(self):
- '''Stops video send.
- '''
+ """Stops video send.
+ """
self._Alter('STOP_VIDEO_SEND')
def Transfer(self, *Targets):
- '''Transfers a call to one or more contacts or phone numbers.
+ """Transfers a call to one or more contacts or phone numbers.
- @param Targets: one or more phone numbers or Skypenames the call is beeing transferred to.
- @type Targets: unicode
- @see: L{CanTransfer}
+ :Parameters:
+ Targets : str
+ one or more phone numbers or Skypenames the call is being transferred to.
- @note: You can transfer an incoming call to a group by specifying more than one
- target, first one of the group to answer will get the call.
- '''
+ :note: You can transfer an incoming call to a group by specifying more than one target,
+ first one of the group to answer will get the call.
+ :see: `CanTransfer`
+ """
self._Alter('TRANSFER', ', '.join(Targets))
def _GetConferenceId(self):
return int(self._Property('CONF_ID'))
ConferenceId = property(_GetConferenceId,
- doc='''ConferenceId.
+ doc="""Conference Id.
- @type: int
- ''')
+ :type: int
+ """)
def _GetDatetime(self):
from datetime import datetime
return datetime.fromtimestamp(self.Timestamp)
Datetime = property(_GetDatetime,
- doc='''Date and time of the call.
+ doc="""Date and time of the call.
- @type: datetime.datetime
- @see: L{Timestamp}
- ''')
+ :type: datetime.datetime
- def _SetDTMF(self, value):
- self._Property('DTMF', value)
+ :see: `Timestamp`
+ """)
+ def _SetDTMF(self, Value):
+ self._Alter('DTMF', Value)
+
DTMF = property(fset=_SetDTMF,
- doc='''Set this property to send DTMF codes.
+ doc="""Set this property to send DTMF codes. Permitted symbols are: [0..9, #, \*].
- @type: unicode
+ :type: str
- @note: This command functions for active calls only.
- ''')
+ :note: This command functions for active calls only.
+ """)
def _GetDuration(self):
return int(self._Property('DURATION', Cache=False))
Duration = property(_GetDuration,
- doc='''Duration of the call in seconds.
+ doc="""Duration of the call in seconds.
- @type: int
- ''')
+ :type: int
+ """)
def _GetFailureReason(self):
return int(self._Property('FAILUREREASON'))
FailureReason = property(_GetFailureReason,
- doc='''Call failure reason. Read if L{Status} == L{clsFailed<enums.clsFailed>}.
+ doc="""Call failure reason. Read if `Status` == `enums.clsFailed`.
- @type: L{Call failure reason<enums.cfrUnknown>}
- ''')
+ :type: `enums`.cfr*
+ """)
def _GetForwardedBy(self):
- return self._Property('FORWARDED_BY')
+ return str(self._Property('FORWARDED_BY'))
ForwardedBy = property(_GetForwardedBy,
- doc='''Skypename of the user who forwarded a call.
+ doc="""Skypename of the user who forwarded a call.
- @type: unicode
- ''')
+ :type: str
+ """)
def _GetId(self):
- return self._Id
+ return self._Handle
Id = property(_GetId,
- doc='''Call Id.
+ doc="""Call Id.
- @type: int
- ''')
+ :type: int
+ """)
def _GetInputStatus(self):
- return self._Property('VAA_INPUT_STATUS') == 'TRUE'
+ return (self._Property('VAA_INPUT_STATUS') == 'TRUE')
InputStatus = property(_GetInputStatus,
- doc='''True if call voice input is enabled.
+ doc="""True if call voice input is enabled.
- @type: bool
- ''')
+ :type: bool
+ """)
def _GetParticipants(self):
count = int(self._Property('CONF_PARTICIPANTS_COUNT'))
- return tuple(IParticipant((self._Id, x), self._Skype) for x in xrange(count))
+ return ParticipantCollection(self, xrange(count))
Participants = property(_GetParticipants,
- doc='''Participants of a conference call not hosted by the user.
+ doc="""Participants of a conference call not hosted by the user.
- @type: tuple of L{IParticipant}
- ''')
+ :type: `ParticipantCollection`
+ """)
def _GetPartnerDisplayName(self):
return self._Property('PARTNER_DISPNAME')
PartnerDisplayName = property(_GetPartnerDisplayName,
- doc='''The DisplayName of the remote caller.
+ doc="""The DisplayName of the remote caller.
- @type: unicode
- ''')
+ :type: unicode
+ """)
def _GetPartnerHandle(self):
- return self._Property('PARTNER_HANDLE')
+ return str(self._Property('PARTNER_HANDLE'))
PartnerHandle = property(_GetPartnerHandle,
- doc='''The Skypename of the remote caller.
+ doc="""The Skypename of the remote caller.
- @type: unicode
- ''')
+ :type: str
+ """)
def _GetPstnNumber(self):
- return self._Property('PSTN_NUMBER')
+ return str(self._Property('PSTN_NUMBER'))
PstnNumber = property(_GetPstnNumber,
- doc='''PSTN number of the call.
+ doc="""PSTN number of the call.
- @type: unicode
- ''')
+ :type: str
+ """)
def _GetPstnStatus(self):
return self._Property('PSTN_STATUS')
PstnStatus = property(_GetPstnStatus,
- doc='''PSTN number status.
+ doc="""PSTN number status.
- @type: unicode
- ''')
+ :type: unicode
+ """)
def _GetRate(self):
return int(self._Property('RATE'))
Rate = property(_GetRate,
- doc='''Call rate. Expressed using L{RatePrecision}. If you're just interested in the call rate
- expressed in current currency, use L{RateValue} instead.
+ doc="""Call rate. Expressed using `RatePrecision`. If you're just interested in the call rate
+ expressed in current currency, use `RateValue` instead.
- @type: int
- @see: L{RateCurrency}, L{RatePrecision}, L{RateToText}, L{RateValue}
- ''')
+ :type: int
+ :see: `RateCurrency`, `RatePrecision`, `RateToText`, `RateValue`
+ """)
+
def _GetRateCurrency(self):
return self._Property('RATE_CURRENCY')
RateCurrency = property(_GetRateCurrency,
- doc='''Call rate currency.
+ doc="""Call rate currency.
- @type: unicode
- @see: L{Rate}, L{RatePrecision}, L{RateToText}, L{RateValue}
- ''')
+ :type: unicode
+ :see: `Rate`, `RatePrecision`, `RateToText`, `RateValue`
+ """)
+
def _GetRatePrecision(self):
return int(self._Property('RATE_PRECISION'))
RatePrecision = property(_GetRatePrecision,
- doc='''Call rate precision. Expressed as a number of times the call rate has to be divided by 10.
+ doc="""Call rate precision. Expressed as a number of times the call rate has to be divided by 10.
- @type: int
- @see: L{Rate}, L{RateCurrency}, L{RateToText}, L{RateValue}
- ''')
+ :type: int
+ :see: `Rate`, `RateCurrency`, `RateToText`, `RateValue`
+ """)
+
def _GetRateToText(self):
return (u'%s %.3f' % (self.RateCurrency, self.RateValue)).strip()
RateToText = property(_GetRateToText,
- doc='''Returns the call rate as a text with currency and properly formatted value.
+ doc="""Returns the call rate as a text with currency and properly formatted value.
- @type: unicode
- @see: L{Rate}, L{RateCurrency}, L{RatePrecision}, L{RateValue}
- ''')
+ :type: unicode
+ :see: `Rate`, `RateCurrency`, `RatePrecision`, `RateValue`
+ """)
+
def _GetRateValue(self):
if self.Rate < 0:
return 0.0
return float(self.Rate) / (10 ** self.RatePrecision)
RateValue = property(_GetRateValue,
- doc='''Call rate value. Expressed in current currency.
+ doc="""Call rate value. Expressed in current currency.
- @type: float
- @see: L{Rate}, L{RateCurrency}, L{RatePrecision}, L{RateToText}
- ''')
+ :type: float
+ :see: `Rate`, `RateCurrency`, `RatePrecision`, `RateToText`
+ """)
+
def _GetSeen(self):
- return self._Property('SEEN') == 'TRUE'
+ return (self._Property('SEEN') == 'TRUE')
- def _SetSeen(self, value):
- self._Property('SEEN', cndexp(value, 'TRUE', 'FALSE'))
+ def _SetSeen(self, Value):
+ self._Property('SEEN', cndexp(Value, 'TRUE', 'FALSE'))
Seen = property(_GetSeen, _SetSeen,
- doc='''Queries/sets the seen status of the call. True if the call was seen, False otherwise.
+ doc="""Queries/sets the seen status of the call. True if the call was seen, False otherwise.
- @type: bool
-
- @note: You cannot alter the call seen status from seen to unseen.
- ''')
+ :type: bool
+ :note: You cannot alter the call seen status from seen to unseen.
+ """)
+
def _GetStatus(self):
- return self._Property('STATUS')
+ return str(self._Property('STATUS'))
- def _SetStatus(self, value):
- self._Property('STATUS', str(value))
+ def _SetStatus(self, Value):
+ self._Property('STATUS', str(Value))
Status = property(_GetStatus, _SetStatus,
- doc='''The call status.
+ doc="""The call status.
- @type: L{Call status<enums.clsUnknown>}
- ''')
+ :type: `enums`.cls*
+ """)
def _GetSubject(self):
return self._Property('SUBJECT')
Subject = property(_GetSubject,
- doc='''Call subject.
+ doc="""Call subject.
- @type: unicode
- ''')
+ :type: unicode
+ """)
- def _GetTargetIdentify(self):
- return self._Property('TARGET_IDENTIFY')
+ def _GetTargetIdentity(self):
+ return str(self._Property('TARGET_IDENTITY'))
- TargetIdentify = property(_GetTargetIdentify,
- doc='''Target number for incoming SkypeIn calls.
+ TargetIdentity = property(_GetTargetIdentity,
+ doc="""Target number for incoming SkypeIn calls.
- @type: unicode
- ''')
+ :type: str
+ """)
def _GetTimestamp(self):
return float(self._Property('TIMESTAMP'))
Timestamp = property(_GetTimestamp,
- doc='''Call date and time expressed as a timestamp.
+ doc="""Call date and time expressed as a timestamp.
- @type: float
- @see: L{Datetime}
- ''')
+ :type: float
+ :see: `Datetime`
+ """)
+
def _GetTransferActive(self):
return self._Property('TRANSFER_ACTIVE') == 'TRUE'
TransferActive = property(_GetTransferActive,
- doc='''Returns True if the call has been transfered.
+ doc="""Returns True if the call has been transferred.
- @type: bool
- ''')
+ :type: bool
+ """)
def _GetTransferredBy(self):
- return self._Property('TRANSFERRED_BY')
+ return str(self._Property('TRANSFERRED_BY'))
TransferredBy = property(_GetTransferredBy,
- doc='''Returns the Skypename of the user who transferred the call.
+ doc="""Returns the Skypename of the user who transferred the call.
- @type: unicode
- ''')
+ :type: str
+ """)
def _GetTransferredTo(self):
- return self._Property('TRANSFERRED_TO')
+ return str(self._Property('TRANSFERRED_TO'))
TransferredTo = property(_GetTransferredTo,
- doc='''Returns the Skypename of the user or phone number the call has been transferred to.
+ doc="""Returns the Skypename of the user or phone number the call has been transferred to.
- @type: unicode
- ''')
+ :type: str
+ """)
def _GetTransferStatus(self):
- return self._Property('TRANSFER_STATUS')
+ return str(self._Property('TRANSFER_STATUS'))
TransferStatus = property(_GetTransferStatus,
- doc='''Returns the call transfer status.
+ doc="""Returns the call transfer status.
- @type: L{Call status<enums.clsUnknown>}
- ''')
+ :type: `enums`.cls*
+ """)
def _GetType(self):
- return self._Property('TYPE')
+ return str(self._Property('TYPE'))
Type = property(_GetType,
- doc='''Call type.
+ doc="""Call type.
- @type: L{Call type<enums.cltUnknown>}
- ''')
+ :type: `enums`.clt*
+ """)
def _GetVideoReceiveStatus(self):
- return self._Property('VIDEO_RECEIVE_STATUS')
+ return str(self._Property('VIDEO_RECEIVE_STATUS'))
VideoReceiveStatus = property(_GetVideoReceiveStatus,
- doc='''Call video receive status.
+ doc="""Call video receive status.
- @type: L{Call video send status<enums.vssUnknown>}
- ''')
+ :type: `enums`.vss*
+ """)
def _GetVideoSendStatus(self):
- return self._Property('VIDEO_SEND_STATUS')
+ return str(self._Property('VIDEO_SEND_STATUS'))
VideoSendStatus = property(_GetVideoSendStatus,
- doc='''Call video send status.
+ doc="""Call video send status.
- @type: L{Call video send status<enums.vssUnknown>}
- ''')
+ :type: `enums`.vss*
+ """)
def _GetVideoStatus(self):
- return self._Property('VIDEO_STATUS')
+ return str(self._Property('VIDEO_STATUS'))
VideoStatus = property(_GetVideoStatus,
- doc='''Call video status.
+ doc="""Call video status.
- @type: L{Call video status<enums.cvsUnknown>}
- ''')
+ :type: `enums`.cvs*
+ """)
def _GetVmAllowedDuration(self):
return int(self._Property('VM_ALLOWED_DURATION'))
VmAllowedDuration = property(_GetVmAllowedDuration,
- doc='''Returns the permitted duration of a voicemail in seconds.
+ doc="""Returns the permitted duration of a voicemail in seconds.
- @type: int
- ''')
+ :type: int
+ """)
def _GetVmDuration(self):
return int(self._Property('VM_DURATION'))
VmDuration = property(_GetVmDuration,
- doc='''Returns the duration of a voicemail.
+ doc="""Returns the duration of a voicemail.
- @type: int
- ''')
+ :type: int
+ """)
-class IParticipant(Cached):
- '''Represents a conference call participant.
- '''
+class CallCollection(CachedCollection):
+ _CachedType = Call
+
+class Participant(Cached):
+ """Represents a conference call participant.
+ """
+ _ValidateHandle = int
+
def __repr__(self):
- return '<%s with Id=%s, Idx=%s, Handle=%s>' % (Cached.__repr__(self)[1:-1], repr(self.Id), repr(self.Idx), repr(self.Handle))
+ return Cached.__repr__(self, 'Id', 'Idx', 'Handle')
- def _Init(self, (Id, Idx), Skype):
- self._Skype = Skype
- self._Id = int(Id)
- self._Idx = int(Idx)
-
def _Property(self, Prop):
- reply = self._Skype._Property('CALL', self._Id, 'CONF_PARTICIPANT %d' % self._Idx)
+ # Prop: 0 = user name, 1 = call type, 2 = call status, 3 = display name
+ reply = self._Owner._Property('CONF_PARTICIPANT %d' % self.Idx)
return chop(reply, 3)[Prop]
+ def _GetCall(self):
+ return self._Owner
+
+ Call = property(_GetCall,
+ doc="""Call object.
+
+ :type: `Call`
+ """)
+
def _GetCallStatus(self):
- return self._Property(2)
+ return str(self._Property(2))
CallStatus = property(_GetCallStatus,
- doc='''Call status of a participant in a conference call.
+ doc="""Call status of a participant in a conference call.
- @type: L{Call status<enums.clsUnknown>}
- ''')
+ :type: `enums`.cls*
+ """)
def _GetCallType(self):
- return self._Property(1)
+ return str(self._Property(1))
CallType = property(_GetCallType,
- doc='''Call type in a conference call.
+ doc="""Call type in a conference call.
- @type: L{Call type<enums.cltUnknown>}
- ''')
+ :type: `enums`.clt*
+ """)
def _GetDisplayName(self):
return self._Property(3)
DisplayName = property(_GetDisplayName,
- doc='''DisplayName of a participant in a conference call.
+ doc="""DisplayName of a participant in a conference call.
- @type: unicode
- ''')
+ :type: unicode
+ """)
def _GetHandle(self):
- return self._Property(0)
+ return str(self._Property(0))
Handle = property(_GetHandle,
- doc='''Skypename of a participant in a conference call.
+ doc="""Skypename of a participant in a conference call.
- @type: unicode
- ''')
+ :type: str
+ """)
def _GetId(self):
- return self._Id
+ return self._Owner.Id
Id = property(_GetId,
- doc='''Call Id.
+ doc="""Call Id.
- @type: int
- ''')
+ :type: int
+ """)
def _GetIdx(self):
- return self._Idx
+ return self._Handle
Idx = property(_GetIdx,
- doc='''Call participant index.
+ doc="""Call participant index.
- @type: int
- ''')
+ :type: int
+ """)
-class IConference(Cached):
- '''Represents a conference call.
- '''
+class ParticipantCollection(CachedCollection):
+ _CachedType = Participant
+
+class Conference(Cached):
+ """Represents a conference call.
+ """
+ _ValidateHandle = int
+
def __repr__(self):
- return '<%s with Id=%s>' % (Cached.__repr__(self)[1:-1], repr(self.Id))
+ return Cached.__repr__(self, 'Id')
- def _Init(self, Id, Skype):
- self._Skype = Skype
- self._Id = int(Id)
-
def Finish(self):
- '''Finishes a conference so all active calls have the status L{clsFinished<enums.clsFinished>}.
- '''
+ """Finishes a conference so all active calls have the status
+ `enums.clsFinished`.
+ """
for c in self._GetCalls():
c.Finish()
def Hold(self):
- '''Places all calls in a conference on hold so all active calls have the status L{clsLocalHold<enums.clsLocalHold>}.
- '''
+ """Places all calls in a conference on hold so all active calls
+ have the status `enums.clsLocalHold`.
+ """
for c in self._GetCalls():
c.Hold()
def Resume(self):
- '''Resumes a conference that was placed on hold so all active calls have the status L{clsInProgress<enums.clsInProgress>}.
- '''
+ """Resumes a conference that was placed on hold so all active calls
+ have the status `enums.clsInProgress`.
+ """
for c in self._GetCalls():
c.Resume()
def _GetActiveCalls(self):
- return tuple(x for x in self._Skype.ActiveCalls if x.ConferenceId == self._Id)
+ return CallCollection(self._Owner, (x.Id for x in self._Owner.ActiveCalls if x.ConferenceId == self.Id))
ActiveCalls = property(_GetActiveCalls,
- doc='''Active calls with the same conference ID.
+ doc="""Active calls with the same conference ID.
- @type: tuple of L{ICall}
- ''')
+ :type: `CallCollection`
+ """)
def _GetCalls(self):
- return tuple(x for x in self._Skype.Calls() if x.ConferenceId == self._Id)
+ return CallCollection(self._Owner, (x.Id for x in self._Owner.Calls() if x.ConferenceId == self.Id))
Calls = property(_GetCalls,
- doc='''Calls with the same conference ID.
+ doc="""Calls with the same conference ID.
- @type: tuple of L{ICall}
- ''')
+ :type: `CallCollection`
+ """)
def _GetId(self):
- return self._Id
+ return self._Handle
Id = property(_GetId,
- doc='''Id of a conference.
+ doc="""Id of a conference.
- @type: int
- ''')
+ :type: int
+ """)
+
+
+class ConferenceCollection(CachedCollection):
+ _CachedType = Conference
Modified: software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/callchannel.py
===================================================================
--- software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/callchannel.py 2009-10-01 12:21:30 UTC (rev 5577)
+++ software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/callchannel.py 2009-10-01 12:23:33 UTC (rev 5578)
@@ -1,327 +1,322 @@
-'''Data channels for calls.
-'''
+"""Data channels for calls.
+"""
+__docformat__ = 'restructuredtext en'
+
+import time
+from copy import copy
+
from utils import *
from enums import *
-from errors import *
-import time
+from errors import SkypeError
-class ICallChannel(object):
- '''Represents a call channel.
- '''
+class CallChannelManager(EventHandlingBase):
+ """Instantiate this class to create a call channel manager. A call channel manager will
+ automatically create a data channel (based on the APP2APP protocol) for voice calls.
- def __init__(self, Manager, Call, Stream, Type):
- '''__init__.
+ Usage
+ =====
- @param Manager: Manager
- @type Manager: L{ICallChannelManager}
- @param Call: Call
- @type Call: L{ICall}
- @param Stream: Stream
- @type Stream: L{IApplicationStream}
- @param Type: Type
- @type Type: L{Call channel type<enums.cctUnknown>}
- '''
- self._Manager = Manager
- self._Call = Call
- self._Stream = Stream
- self._Type = Type
+ You should access this class using the alias at the package level:
+
+ .. python::
- def __repr__(self):
- return '<%s with Manager=%s, Call=%s, Stream=%s>' % (object.__repr__(self)[1:-1], repr(self.Manager), repr(self.Call), repr(self.Stream))
+ import Skype4Py
- def SendTextMessage(self, Text):
- '''Sends text message over channel.
+ skype = Skype4Py.Skype()
- @param Text: Text
- @type Text: unicode
- '''
- if self._Type == cctReliable:
- self._Stream.Write(Text)
- elif self._Type == cctDatagram:
- self._Stream.SendDatagram(Text)
- else:
- raise ISkypeError(0, 'Cannot send using %s channel type' & repr(self._Type))
+ ccm = Skype4Py.CallChannelManager()
+ ccm.Connect(skype)
- def _GetCall(self):
- return self._Call
+ Read the constructor (`CallChannelManager.__init__`) documentation for a list of
+ accepted arguments.
- Call = property(_GetCall,
- doc='''Call.
+ Events
+ ======
- @type: L{ICall}
- ''')
+ This class provides events.
- def _GetManager(self):
- return self._Manager
+ The events names and their arguments lists can be found in the
+ `CallChannelManagerEvents` class in this module.
- Manager = property(_GetManager,
- doc='''Manager.
+ The use of events is explained in `EventHandlingBase` class which
+ is a superclass of this class.
+ """
- @type: L{ICallChannelManager}
- ''')
-
- def _GetStream(self):
- return self._Stream
-
- Stream = property(_GetStream,
- doc='''Stream.
-
- @type: L{IApplicationStream}
- ''')
-
- def _GetType(self):
- return self._Type
-
- Type = property(_GetType,
- doc='''Type.
-
- @type: L{Call channel type<enums.cctUnknown>}
- ''')
-
-
-class ICallChannelManager(EventHandlingBase):
- '''Instatinate this class to create a call channel manager. A call channel manager will
- automatically create a data channel for voice calls base...
[truncated message content] |
|
From: jerome <c2m...@c2...> - 2009-10-01 14:31:01
|
Author: jerome
Date: 2009-10-01 14:25:22 +0200 (Thu, 01 Oct 2009)
New Revision: 5580
Added:
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/__init__.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/darwin.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/faked_dbus.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/posix.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/posix_dbus.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/posix_x11.py
software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/windows.py
Log:
* Added new api transport package.
Added: software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/__init__.py
===================================================================
--- software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/__init__.py (rev 0)
+++ software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/__init__.py 2009-10-01 12:25:22 UTC (rev 5580)
@@ -0,0 +1,240 @@
+"""
+Low-level Skype API definitions.
+
+This subpackage imports one of the:
+
+- `Skype4Py.api.darwin`
+- `Skype4Py.api.posix`
+- `Skype4Py.api.windows`
+
+modules based on the current platform.
+
+Name of the imported module in available in the `platform` variable.
+
+The modules implement the low-level Skype API and define options
+for the `Skype.__init__` constructor.
+"""
+__docformat__ = 'restructuredtext en'
+
+
+import sys
+import threading
+import logging
+
+from Skype4Py.utils import *
+from Skype4Py.enums import apiAttachUnknown
+from Skype4Py.errors import SkypeAPIError
+
+
+__all__ = ['Command', 'SkypeAPINotifier', 'SkypeAPI']
+
+
+DEFAULT_PROTOCOL = 5
+DEFAULT_FRIENDLYNAME = u'Skype4Py'
+DEFAULT_TIMEOUT = 30000
+
+
+class Command(object):
+ """Represents an API command. Use `Skype.Command` to instantiate.
+
+ To send a command to Skype, use `Skype.SendCommand`.
+ """
+
+ def __init__(self, Command, Expected=u'', Blocking=False, Timeout=DEFAULT_TIMEOUT, Id=-1):
+ """Use `Skype.Command` to instantiate the object instead of doing it directly.
+ """
+
+ self.Blocking = Blocking
+ """If set to True, `Skype.SendCommand` will block until the reply is received.
+
+ :type: bool"""
+
+ self.Command = tounicode(Command)
+ """Command string.
+
+ :type: unicode"""
+
+ self.Expected = tounicode(Expected)
+ """Expected reply.
+
+ :type: unicode"""
+
+ self.Id = Id
+ """Command Id.
+
+ :type: int"""
+
+ self.Reply = u''
+ """Reply after the command has been sent and Skype has replied.
+
+ :type: unicode"""
+
+ self.Timeout = Timeout
+ """Timeout if Blocking == True.
+
+ :type: int"""
+
+ def __repr__(self):
+ return '<%s with Command=%s, Blocking=%s, Reply=%s, Id=%s>' % \
+ (object.__repr__(self)[1:-1], repr(self.Command), self.Blocking, repr(self.Reply), self.Id)
+
+ def timeout2float(self):
+ """A wrapper for `api.timeout2float` function. Returns the converted
+ `Timeout` property.
+ """
+ return timeout2float(self.Timeout)
+
+
+class SkypeAPINotifier(object):
+ def attachment_changed(self, status):
+ pass
+
+ def notification_received(self, notification):
+ pass
+
+ def sending_command(self, command):
+ pass
+
+ def reply_received(self, command):
+ pass
+
+
+class SkypeAPIBase(threading.Thread):
+ def __init__(self):
+ threading.Thread.__init__(self, name='Skype4Py API thread')
+ self.setDaemon(True)
+ if not hasattr(self, 'logger'):
+ # Create a logger if the subclass hasn't done it already.
+ self.logger = logging.getLogger('Skype4Py.api.SkypeAPIBase')
+ self.friendly_name = DEFAULT_FRIENDLYNAME
+ self.protocol = DEFAULT_PROTOCOL
+ self.commands = {}
+ # This lock is the main mechanism to make Skype4Py thread-safe.
+ self.rlock = threading.RLock()
+ self.notifier = SkypeAPINotifier()
+ self.attachment_status = apiAttachUnknown
+ self.logger.info('opened')
+
+ def _not_implemented(self):
+ raise SkypeAPIError('Function not implemented')
+
+ def set_notifier(self, notifier):
+ self.notifier = notifier
+
+ def push_command(self, command):
+ self.acquire()
+ try:
+ if command.Id < 0:
+ command.Id = 0
+ while command.Id in self.commands:
+ command.Id += 1
+ elif command.Id in self.commands:
+ raise SkypeAPIError('Command Id conflict')
+ self.commands[command.Id] = command
+ finally:
+ self.release()
+
+ def pop_command(self, id_):
+ self.acquire()
+ try:
+ try:
+ return self.commands.pop(id_)
+ except KeyError:
+ return None
+ finally:
+ self.release()
+
+ def acquire(self):
+ self.rlock.acquire()
+
+ def release(self):
+ self.rlock.release()
+
+ def close(self):
+ self.logger.info('closed')
+
+ def set_friendly_name(self, friendly_name):
+ self.friendly_name = friendly_name
+
+ def set_attachment_status(self, attachment_status):
+ if attachment_status != self.attachment_status:
+ self.logger.info('attachment: %s', attachment_status)
+ self.attachment_status = attachment_status
+ self.notifier.attachment_changed(attachment_status)
+
+ def attach(self, timeout, wait=True):
+ self._not_implemented()
+
+ def is_running(self):
+ self._not_implemented()
+
+ def startup(self, minimized, nosplash):
+ self._not_implemented()
+
+ def shutdown(self):
+ self._not_implemented()
+
+ def send_command(self, command):
+ self._not_implemented()
+
+ def security_context_enabled(self, context):
+ self._not_implemented()
+
+ def enable_security_context(self, context):
+ self._not_implemented()
+
+ def allow_focus(self, timeout):
+ pass
+
+
+def timeout2float(timeout):
+ """Converts a timeout expressed in milliseconds or seconds into a timeout expressed
+ in seconds using a floating point number.
+
+ :Parameters:
+ timeout : int, long or float
+ The input timeout. Assumed to be expressed in number of
+ milliseconds if the type is int or long. For float, assumed
+ to be a number of seconds (or fractions thereof).
+
+ :return: The timeout expressed in number of seconds (or fractions thereof).
+ :rtype: float
+ """
+ if isinstance(timeout, float):
+ return timeout
+ return timeout / 1000.0
+
+
+def finalize_opts(opts):
+ """Convinient function called after popping all options from a dictionary.
+ If there are any items left, a TypeError exception is raised listing all
+ unexpected keys in the error message.
+ """
+ if opts:
+ raise TypeError('Unexpected option(s): %s' % ', '.join(opts.keys()))
+
+
+# Select appropriate low-level Skype API module
+if getattr(sys, 'skype4py_setup', False):
+ # dummy for the setup.py run
+ SkypeAPI = lambda **Options: None
+ platform = ''
+elif sys.platform.startswith('win'):
+ from windows import SkypeAPI
+ platform = 'windows'
+elif sys.platform == 'darwin':
+ from darwin import SkypeAPI
+ platform = 'darwin'
+else:
+ from posix import SkypeAPI
+ platform = 'posix'
+
+
+# Note. py2exe will include the darwin but not the posix module. This seems to be the case
+# solely because of the "posix" name. It might be a bug in py2exe or modulefinder caused
+# by a failed attempt to import a "posix" module by the os module. If this is encountered
+# during modulefinder scanning, the Skype4Py.api.posix is simply ignored.
+#
+# That being said ideally we would like to exclude both of them but I couldn't find a way
+# to cause py2exe to skip them. I think py2exe should expose mechanisms to cooperate with
+# extension modules aware of its existence.
Added: software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/darwin.py
===================================================================
--- software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/darwin.py (rev 0)
+++ software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/darwin.py 2009-10-01 12:25:22 UTC (rev 5580)
@@ -0,0 +1,475 @@
+"""
+Low level *Skype for Mac OS X* interface implemented using *Carbon
+distributed notifications*. Uses direct *Carbon*/*CoreFoundation*
+calls through the *ctypes* module.
+
+This module handles the options that you can pass to
+`Skype.__init__` for *Mac OS X* machines.
+
+- ``RunMainLoop`` (bool) - If set to False, Skype4Py won't start the Carbon event
+ loop. Otherwise it is started in a separate thread. The loop must be running for
+ Skype4Py events to work properly. Set this option to False if you plan to run the
+ loop yourself or if, for example, your GUI framework does it for you.
+
+Thanks to **Eion Robb** for reversing *Skype for Mac* API protocol.
+"""
+__docformat__ = 'restructuredtext en'
+
+
+import sys
+from ctypes import *
+from ctypes.util import find_library
+import threading
+import time
+import logging
+
+from Skype4Py.api import Command, SkypeAPIBase, \
+ timeout2float, finalize_opts
+from Skype4Py.errors import SkypeAPIError
+from Skype4Py.enums import *
+
+
+__all__ = ['SkypeAPI']
+
+
+class CFType(object):
+ """Fundamental type for all CoreFoundation types.
+
+ :see: http://developer.apple.com/documentation/CoreFoundation/Reference/CFTypeRef/
+ """
+
+ def __init__(self, init):
+ self.owner = True
+ if isinstance(init, CFType):
+ # copy the handle and increase the use count
+ self.handle = init.get_handle()
+ coref.CFRetain(self)
+ elif isinstance(init, c_void_p):
+ self.handle = init
+ else:
+ raise TypeError('illegal init type: %s' % type(init))
+
+ @classmethod
+ def from_handle(cls, handle):
+ if isinstance(handle, (int, long)):
+ handle = c_void_p(handle)
+ elif not isinstance(handle, c_void_p):
+ raise TypeError('illegal handle type: %s' % type(handle))
+ obj = cls(handle)
+ obj.owner = False
+ return obj
+
+ def __del__(self):
+ if not coref:
+ return
+ if self.owner:
+ coref.CFRelease(self)
+
+ def __repr__(self):
+ return '%s(handle=%s)' % (self.__class__.__name__, repr(self.handle))
+
+ def retain(self):
+ if not self.owner:
+ coref.CFRetain(self)
+ self.owner = True
+
+ def get_retain_count(self):
+ return coref.CFGetRetainCount(self)
+
+ def get_handle(self):
+ return self.handle
+
+ # allows passing CF types as ctypes function parameters
+ _as_parameter_ = property(get_handle)
+
+
+class CFString(CFType):
+ """CoreFoundation string type.
+
+ Supports Python unicode type only. String is immutable.
+
+ :see: http://developer.apple.com/documentation/CoreFoundation/Reference/CFStringRef/
+ """
+
+ def __init__(self, init=u''):
+ if isinstance(init, (str, unicode)):
+ s = unicode(init).encode('utf-8')
+ init = c_void_p(coref.CFStringCreateWithBytes(None,
+ s, len(s), 0x08000100, False))
+ CFType.__init__(self, init)
+
+ def __str__(self):
+ i = coref.CFStringGetLength(self)
+ size = c_long()
+ if coref.CFStringGetBytes(self, 0, i, 0x08000100, 0, False, None, 0, byref(size)) > 0:
+ buf = create_string_buffer(size.value)
+ coref.CFStringGetBytes(self, 0, i, 0x08000100, 0, False, buf, size, None)
+ return buf.value
+ else:
+ raise UnicodeError('CFStringGetBytes() failed')
+
+ def __unicode__(self):
+ return self.__str__().decode('utf-8')
+
+ def __len__(self):
+ return coref.CFStringGetLength(self)
+
+ def __repr__(self):
+ return 'CFString(%s)' % repr(unicode(self))
+
+
+class CFNumber(CFType):
+ """CoreFoundation number type.
+
+ Supports Python int type only. Number is immutable.
+
+ :see: http://developer.apple.com/documentation/CoreFoundation/Reference/CFNumberRef/
+ """
+
+ def __init__(self, init=0):
+ if isinstance(init, (int, long)):
+ init = c_void_p(coref.CFNumberCreate(None, 3, byref(c_int(int(init)))))
+ CFType.__init__(self, init)
+
+ def __int__(self):
+ n = c_int()
+ if coref.CFNumberGetValue(self, 3, byref(n)):
+ return n.value
+ return 0
+
+ def __repr__(self):
+ return 'CFNumber(%s)' % repr(int(self))
+
+
+class CFDictionary(CFType):
+ """CoreFoundation immutable dictionary type.
+
+ :see: http://developer.apple.com/documentation/CoreFoundation/Reference/CFDictionaryRef/
+ """
+
+ def __init__(self, init={}):
+ if isinstance(init, dict):
+ d = dict(init)
+ keys = (c_void_p * len(d))()
+ values = (c_void_p * len(d))()
+ for i, (k, v) in enumerate(d.items()):
+ keys[i] = k.get_handle()
+ values[i] = v.get_handle()
+ init = c_void_p(coref.CFDictionaryCreate(None, keys, values, len(d),
+ coref.kCFTypeDictionaryKeyCallBacks, coref.kCFTypeDictionaryValueCallBacks))
+ CFType.__init__(self, init)
+
+ def get_dict(self):
+ n = len(self)
+ keys = (c_void_p * n)()
+ values = (c_void_p * n)()
+ coref.CFDictionaryGetKeysAndValues(self, keys, values)
+ d = dict()
+ for i in xrange(n):
+ d[CFType.from_handle(keys[i])] = CFType.from_handle(values[i])
+ return d
+
+ def __getitem__(self, key):
+ return CFType.from_handle(coref.CFDictionaryGetValue(self, key))
+
+ def __len__(self):
+ return coref.CFDictionaryGetCount(self)
+
+
+class CFDistributedNotificationCenter(CFType):
+ """CoreFoundation distributed notification center type.
+
+ :see: http://developer.apple.com/documentation/CoreFoundation/Reference/CFNotificationCenterRef/
+ """
+
+ CFNOTIFICATIONCALLBACK = CFUNCTYPE(None, c_void_p, c_void_p, c_void_p, c_void_p, c_void_p)
+
+ def __init__(self):
+ CFType.__init__(self, c_void_p(coref.CFNotificationCenterGetDistributedCenter()))
+ # there is only one distributed notification center per application
+ self.owner = False
+ self.callbacks = {}
+ self._c_callback = self.CFNOTIFICATIONCALLBACK(self._callback)
+
+ def _callback(self, center, observer, name, obj, userInfo):
+ observer = CFString.from_handle(observer)
+ name = CFString.from_handle(name)
+ if obj:
+ obj = CFString.from_handle(obj)
+ userInfo = CFDictionary.from_handle(userInfo)
+ callback = self.callbacks[(unicode(observer), unicode(name))]
+ callback(self, observer, name, obj, userInfo)
+
+ def add_observer(self, observer, callback, name=None, obj=None,
+ drop=False, coalesce=False, hold=False, immediate=False):
+ if not callable(callback):
+ raise TypeError('callback must be callable')
+ observer = CFString(observer)
+ self.callbacks[(unicode(observer), unicode(name))] = callback
+ if name is not None:
+ name = CFString(name)
+ if obj is not None:
+ obj = CFString(obj)
+ if drop:
+ behaviour = 1
+ elif coalesce:
+ behaviour = 2
+ elif hold:
+ behaviour = 3
+ elif immediate:
+ behaviour = 4
+ else:
+ behaviour = 0
+ coref.CFNotificationCenterAddObserver(self, observer,
+ self._c_callback, name, obj, behaviour)
+
+ def remove_observer(self, observer, name=None, obj=None):
+ observer = CFString(observer)
+ if name is not None:
+ name = CFString(name)
+ if obj is not None:
+ obj = CFString(obj)
+ coref.CFNotificationCenterRemoveObserver(self, observer, name, obj)
+ try:
+ del self.callbacks[(unicode(observer), unicode(name))]
+ except KeyError:
+ pass
+
+ def post_notification(self, name, obj=None, userInfo=None, immediate=False):
+ name = CFString(name)
+ if obj is not None:
+ obj = CFString(obj)
+ if userInfo is not None:
+ userInfo = CFDictionary(userInfo)
+ coref.CFNotificationCenterPostNotification(self, name, obj, userInfo, immediate)
+
+
+class EventLoop(object):
+ """Carbon event loop object for the current thread.
+
+ The Carbon reference documentation seems to be gone from developer.apple.com, the following
+ link points to a mirror I found. I don't know how long until this one is gone too.
+
+ :see: http://www.monen.nl/DevDoc/documentation/Carbon/Reference/Carbon_Event_Manager_Ref/index.html
+ """
+
+ def __init__(self):
+ self.handle = c_void_p(carbon.GetCurrentEventLoop())
+
+ @staticmethod
+ def run(timeout=-1):
+ # Timeout is expressed in seconds (float), -1 means forever.
+ # Returns True if aborted (eventLoopQuitErr).
+ return (carbon.RunCurrentEventLoop(timeout) == -9876)
+
+ def stop(self):
+ carbon.QuitEventLoop(self.handle)
+
+
+# load the Carbon and CoreFoundation frameworks
+# (only if not building the docs)
+if not getattr(sys, 'skype4py_setup', False):
+
+ path = find_library('Carbon')
+ if path is None:
+ raise ImportError('Could not find Carbon.framework')
+ carbon = cdll.LoadLibrary(path)
+ carbon.RunCurrentEventLoop.argtypes = (c_double,)
+
+ path = find_library('CoreFoundation')
+ if path is None:
+ raise ImportError('Could not find CoreFoundation.framework')
+ coref = cdll.LoadLibrary(path)
+
+
+class SkypeAPI(SkypeAPIBase):
+ """
+ :note: Code based on Pidgin Skype Plugin source
+ (http://code.google.com/p/skype4pidgin/).
+ Permission to use granted by the author.
+ """
+
+ def __init__(self, opts):
+ self.logger = logging.getLogger('Skype4Py.api.darwin.SkypeAPI')
+ SkypeAPIBase.__init__(self)
+ self.run_main_loop = opts.pop('RunMainLoop', True)
+ finalize_opts(opts)
+ self.center = CFDistributedNotificationCenter()
+ self.is_available = False
+ self.client_id = -1
+
+ def run(self):
+ self.logger.info('thread started')
+ if self.run_main_loop:
+ self.loop = EventLoop()
+ EventLoop.run()
+ self.logger.info('thread finished')
+
+ def close(self):
+ if hasattr(self, 'loop'):
+ self.loop.stop()
+ self.client_id = -1
+ SkypeAPIBase.close(self)
+
+ def set_friendly_name(self, friendly_name):
+ SkypeAPIBase.set_friendly_name(self, friendly_name)
+ if self.attachment_status == apiAttachSuccess:
+ # reattach with the new name
+ self.set_attachment_status(apiAttachUnknown)
+ self.attach()
+
+ def attach(self, timeout, wait=True):
+ if self.attachment_status in (apiAttachPendingAuthorization, apiAttachSuccess):
+ return
+ self.acquire()
+ try:
+ try:
+ self.start()
+ except AssertionError:
+ pass
+ t = threading.Timer(timeout2float(timeout), lambda: setattr(self, 'wait', False))
+ try:
+ self.init_observer()
+ self.client_id = -1
+ self.set_attachment_status(apiAttachPendingAuthorization)
+ self.post('SKSkypeAPIAttachRequest')
+ self.wait = True
+ if wait:
+ t.start()
+ while self.wait and self.attachment_status == apiAttachPendingAuthorization:
+ if self.run_main_loop:
+ time.sleep(1.0)
+ else:
+ EventLoop.run(1.0)
+ finally:
+ t.cancel()
+ if not self.wait:
+ self.set_attachment_status(apiAttachUnknown)
+ raise SkypeAPIError('Skype attach timeout')
+ finally:
+ self.release()
+ command = Command('PROTOCOL %s' % self.protocol, Blocking=True)
+ self.send_command(command)
+ self.protocol = int(command.Reply.rsplit(None, 1)[-1])
+
+ def is_running(self):
+ try:
+ self.start()
+ except AssertionError:
+ pass
+ self.init_observer()
+ self.is_available = False
+ self.post('SKSkypeAPIAvailabilityRequest')
+ time.sleep(1.0)
+ return self.is_available
+
+ def startup(self, minimized, nosplash):
+ if not self.is_running():
+ from subprocess import Popen
+ nul = file('/dev/null')
+ Popen(['/Applications/Skype.app/Contents/MacOS/Skype'], stdin=nul, stdout=nul, stderr=nul)
+
+ def send_command(self, command):
+ if not self.attachment_status == apiAttachSuccess:
+ self.attach(command.Timeout)
+ self.push_command(command)
+ self.notifier.sending_command(command)
+ cmd = u'#%d %s' % (command.Id, command.Command)
+ if command.Blocking:
+ if self.run_main_loop:
+ command._event = event = threading.Event()
+ else:
+ command._loop = EventLoop()
+ else:
+ command._timer = timer = threading.Timer(command.timeout2float(), self.pop_command, (command.Id,))
+
+ self.logger.debug('sending %s', repr(cmd))
+ userInfo = CFDictionary({CFString('SKYPE_API_COMMAND'): CFString(cmd),
+ CFString('SKYPE_API_CLIENT_ID'): CFNumber(self.client_id)})
+ self.post('SKSkypeAPICommand', userInfo)
+
+ if command.Blocking:
+ if self.run_main_loop:
+ event.wait(command.timeout2float())
+ if not event.isSet():
+ raise SkypeAPIError('Skype command timeout')
+ else:
+ if not EventLoop.run(command.timeout2float()):
+ raise SkypeAPIError('Skype command timeout')
+ else:
+ timer.start()
+
+ def init_observer(self):
+ if self.has_observer():
+ self.delete_observer()
+ self.observer = CFString(self.friendly_name)
+ self.center.add_observer(self.observer, self.SKSkypeAPINotification, 'SKSkypeAPINotification', immediate=True)
+ self.center.add_observer(self.observer, self.SKSkypeWillQuit, 'SKSkypeWillQuit', immediate=True)
+ self.center.add_observer(self.observer, self.SKSkypeBecameAvailable, 'SKSkypeBecameAvailable', immediate=True)
+ self.center.add_observer(self.observer, self.SKAvailabilityUpdate, 'SKAvailabilityUpdate', immediate=True)
+ self.center.add_observer(self.observer, self.SKSkypeAttachResponse, 'SKSkypeAttachResponse', immediate=True)
+
+ def delete_observer(self):
+ if not self.has_observer():
+ return
+ self.center.remove_observer(self.observer, 'SKSkypeAPINotification')
+ self.center.remove_observer(self.observer, 'SKSkypeWillQuit')
+ self.center.remove_observer(self.observer, 'SKSkypeBecameAvailable')
+ self.center.remove_observer(self.observer, 'SKAvailabilityUpdate')
+ self.center.remove_observer(self.observer, 'SKSkypeAttachResponse')
+ del self.observer
+
+ def has_observer(self):
+ return hasattr(self, 'observer')
+
+ def post(self, name, userInfo=None):
+ if not self.has_observer():
+ self.init_observer()
+ self.center.post_notification(name, self.observer, userInfo, immediate=True)
+
+ def SKSkypeAPINotification(self, center, observer, name, obj, userInfo):
+ client_id = int(CFNumber(userInfo[CFString('SKYPE_API_CLIENT_ID')]))
+ if client_id != 999 and (client_id == 0 or client_id != self.client_id):
+ return
+ cmd = unicode(CFString(userInfo[CFString('SKYPE_API_NOTIFICATION_STRING')]))
+ self.logger.debug('received %s', repr(cmd))
+
+ if cmd.startswith(u'#'):
+ p = cmd.find(u' ')
+ command = self.pop_command(int(cmd[1:p]))
+ if command is not None:
+ command.Reply = cmd[p + 1:]
+ if command.Blocking:
+ if self.run_main_loop:
+ command._event.set()
+ else:
+ command._loop.stop()
+ else:
+ command._timer.cancel()
+ self.notifier.reply_received(command)
+ else:
+ self.notifier.notification_received(cmd[p + 1:])
+ else:
+ self.notifier.notification_received(cmd)
+
+ def SKSkypeWillQuit(self, center, observer, name, obj, userInfo):
+ self.logger.debug('received SKSkypeWillQuit')
+ self.set_attachment_status(apiAttachNotAvailable)
+
+ def SKSkypeBecameAvailable(self, center, observer, name, obj, userInfo):
+ self.logger.debug('received SKSkypeBecameAvailable')
+ self.set_attachment_status(apiAttachAvailable)
+
+ def SKAvailabilityUpdate(self, center, observer, name, obj, userInfo):
+ self.logger.debug('received SKAvailabilityUpdate')
+ self.is_available = not not int(CFNumber(userInfo[CFString('SKYPE_API_AVAILABILITY')]))
+
+ def SKSkypeAttachResponse(self, center, observer, name, obj, userInfo):
+ self.logger.debug('received SKSkypeAttachResponse')
+ # It seems that this notification is not called if the access is refused. Therefore we can't
+ # distinguish between attach timeout and access refuse.
+ if unicode(CFString(userInfo[CFString('SKYPE_API_CLIENT_NAME')])) == self.friendly_name:
+ response = int(CFNumber(userInfo[CFString('SKYPE_API_ATTACH_RESPONSE')]))
+ if response and self.client_id == -1:
+ self.client_id = response
+ self.set_attachment_status(apiAttachSuccess)
Added: software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/faked_dbus.py
===================================================================
--- software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/faked_dbus.py (rev 0)
+++ software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/faked_dbus.py 2009-10-01 12:25:22 UTC (rev 5580)
@@ -0,0 +1,12 @@
+'''
+This faked module is used while building docs on windows
+where dbus package isn't available.
+'''
+
+class dbus(object):
+ class service(object):
+ class Object(object):
+ pass
+ @staticmethod
+ def method(*args, **kwargs):
+ return lambda *args, **kwargs: None
Added: software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/posix.py
===================================================================
--- software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/posix.py (rev 0)
+++ software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/posix.py 2009-10-01 12:25:22 UTC (rev 5580)
@@ -0,0 +1,40 @@
+"""
+Low level *Skype for Linux* interface.
+
+This module handles the options that you can pass to `Skype.__init__` for Linux machines.
+The options include:
+
+- ``Transport`` (str) - Name of a channel used to communicate with the Skype client.
+ Currently supported values:
+
+ - ``'dbus'`` (default)
+
+ Uses *DBus* thrugh *dbus-python* package.
+ This is the default if no transport is specified.
+
+ Look into `Skype4Py.api.posix_dbus` for additional options.
+
+ - ``'x11'``
+
+ Uses *X11* messaging through *Xlib*.
+
+ Look into `Skype4Py.api.posix_x11` module for additional options.
+"""
+__docformat__ = 'restructuredtext en'
+
+
+from Skype4Py.errors import SkypeAPIError
+
+
+__all__ = ['SkypeAPI']
+
+
+def SkypeAPI(opts):
+ trans = opts.pop('Transport', 'dbus')
+ if trans == 'dbus':
+ from posix_dbus import SkypeAPI
+ elif trans == 'x11':
+ from posix_x11 import SkypeAPI
+ else:
+ raise SkypeAPIError('Unknown transport: %s' % trans)
+ return SkypeAPI(opts)
Added: software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/posix_dbus.py
===================================================================
--- software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/posix_dbus.py (rev 0)
+++ software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/posix_dbus.py 2009-10-01 12:25:22 UTC (rev 5580)
@@ -0,0 +1,253 @@
+"""
+Low level *Skype for Linux* interface implemented using *dbus-python* package.
+
+This module handles the options that you can pass to `Skype.__init__`
+for Linux machines when the transport is set to *DBus*. See below.
+
+- ``RunMainLoop`` (bool) - If set to False, Skype4Py won't start the GLib main
+ loop. Otherwise it is started in a separate thread. The loop must be running for
+ Skype4Py events to work properly. Set this option to False if you plan to run the
+ loop yourself or if, for example, your GUI framework does it for you.
+
+:requires: Skype for Linux 2.0 (beta) or newer.
+"""
+__docformat__ = 'restructuredtext en'
+
+
+import sys
+import threading
+import time
+import warnings
+import logging
+
+from Skype4Py.api import Command, SkypeAPIBase, \
+ timeout2float, finalize_opts
+from Skype4Py.enums import *
+from Skype4Py.errors import SkypeAPIError
+from Skype4Py.utils import cndexp
+
+
+__all__ = ['SkypeAPI']
+
+
+if getattr(sys, 'skype4py_setup', False):
+ # we get here if we're building docs; to let the module import without
+ # exceptions, we emulate the dbus module using a class:
+ class dbus(object):
+ class service(object):
+ class Object(object):
+ pass
+ @staticmethod
+ def method(*args, **kwargs):
+ return lambda *args, **kwargs: None
+else:
+ import dbus
+ import dbus.service
+ from dbus.mainloop.glib import DBusGMainLoop
+ import gobject
+
+
+class SkypeNotify(dbus.service.Object):
+ """DBus object which exports a Notify method. This will be called by Skype for all
+ notifications with the notification string as a parameter. The Notify method of this
+ class calls in turn the callable passed to the constructor.
+ """
+
+ def __init__(self, bus, notify):
+ dbus.service.Object.__init__(self, bus, '/com/Skype/Client')
+ self.notify = notify
+
+ @dbus.service.method(dbus_interface='com.Skype.API.Client')
+ def Notify(self, com):
+ self.notify(unicode(com))
+
+
+class SkypeAPI(SkypeAPIBase):
+ def __init__(self, opts):
+ self.logger = logging.getLogger('Skype4Py.api.posix_dbus.SkypeAPI')
+ SkypeAPIBase.__init__(self)
+ self.run_main_loop = opts.pop('RunMainLoop', True)
+ finalize_opts(opts)
+ self.skype_in = self.skype_out = self.dbus_name_owner_watch = None
+
+ # initialize glib multithreading support
+ gobject.threads_init()
+
+ # dbus-python calls object.__init__() with arguments passed to SessionBus(),
+ # this throws a warning on newer Python versions; here we suppress it
+ warnings.simplefilter('ignore')
+ try:
+ self.bus = dbus.SessionBus(mainloop=DBusGMainLoop())
+ finally:
+ warnings.simplefilter('default')
+
+ if self.run_main_loop:
+ self.mainloop = gobject.MainLoop()
+
+ def run(self):
+ self.logger.info('thread started')
+ if self.run_main_loop:
+ self.mainloop.run()
+ self.logger.info('thread finished')
+
+ def close(self):
+ if self.run_main_loop:
+ 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
+ SkypeAPIBase.close(self)
+
+ def set_friendly_name(self, friendly_name):
+ SkypeAPIBase.set_friendly_name(self, friendly_name)
+ if self.skype_out:
+ self.send_command(Command('NAME %s' % friendly_name))
+
+ def start_watcher(self):
+ # starts a signal receiver detecting Skype being closed/opened
+ 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(self, timeout, wait=True):
+ self.acquire()
+ try:
+ try:
+ if not self.isAlive():
+ self.start_watcher()
+ self.start()
+ except AssertionError:
+ pass
+ try:
+ self.wait = True
+ t = threading.Timer(timeout2float(timeout), lambda: setattr(self, 'wait', False))
+ 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 = SkypeNotify(self.bus, self.notify)
+ except dbus.DBusException:
+ if not wait:
+ break
+ time.sleep(1.0)
+ else:
+ break
+ else:
+ raise SkypeAPIError('Skype attach timeout')
+ finally:
+ t.cancel()
+ command = Command('NAME %s' % self.friendly_name, '', True, timeout)
+ if self.skype_out:
+ self.release()
+ try:
+ self.send_command(command)
+ finally:
+ self.acquire()
+ if command.Reply != 'OK':
+ self.skype_out = None
+ self.set_attachment_status(apiAttachRefused)
+ return
+ self.set_attachment_status(apiAttachSuccess)
+ finally:
+ self.release()
+ command = Command('PROTOCOL %s' % self.protocol, Blocking=True)
+ self.send_command(command)
+ self.protocol = int(command.Reply.rsplit(None, 1)[-1])
+
+ def is_running(self):
+ try:
+ self.bus.get_object('com.Skype.API', '/com/Skype')
+ return True
+ except dbus.DBusException:
+ return False
+
+ def startup(self, minimized, nosplash):
+ # options are not supported as of Skype 1.4 Beta for Linux
+ if not self.is_running():
+ 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 send_command(self, command):
+ if not self.skype_out:
+ self.attach(command.Timeout)
+ self.push_command(command)
+ self.notifier.sending_command(command)
+ cmd = u'#%d %s' % (command.Id, command.Command)
+ self.logger.debug('sending %s', repr(cmd))
+ if command.Blocking:
+ if self.run_main_loop:
+ command._event = event = threading.Event()
+ else:
+ command._loop = loop = gobject.MainLoop()
+ command._set = False
+ else:
+ command._timer = timer = threading.Timer(command.timeout2float(), self.pop_command, (command.Id,))
+ try:
+ result = self.skype_out.Invoke(cmd)
+ except dbus.DBusException, err:
+ raise SkypeAPIError(str(err))
+ if result.startswith(u'#%d ' % command.Id):
+ self.notify(result)
+ if command.Blocking:
+ if self.run_main_loop:
+ event.wait(command.timeout2float())
+ if not event.isSet():
+ raise SkypeAPIError('Skype command timeout')
+ elif not command._set:
+ gobject.timeout_add_seconds(int(command.timeout2float()), loop.quit)
+ loop.run()
+ if not command._set:
+ raise SkypeAPIError('Skype command timeout')
+ else:
+ timer.start()
+
+ def notify(self, cmd):
+ cmd = unicode(cmd)
+ self.logger.debug('received %s', repr(cmd))
+ if cmd.startswith(u'#'):
+ p = cmd.find(u' ')
+ command = self.pop_command(int(cmd[1:p]))
+ if command is not None:
+ command.Reply = cmd[p + 1:]
+ if command.Blocking:
+ if self.run_main_loop:
+ command._event.set()
+ else:
+ command._set = True
+ command._loop.quit()
+ else:
+ command._timer.cancel()
+ self.notifier.reply_received(command)
+ else:
+ self.notifier.notification_received(cmd[p + 1:])
+ else:
+ self.notifier.notification_received(cmd)
+
+ def dbus_name_owner_changed(self, owned, old_owner, new_owner):
+ self.logger.debug('received dbus name owner changed')
+ if new_owner == '':
+ self.skype_out = None
+ self.set_attachment_status(cndexp((new_owner == ''),
+ apiAttachNotAvailable,
+ apiAttachAvailable))
Added: software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/posix_x11.py
===================================================================
--- software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/posix_x11.py (rev 0)
+++ software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/posix_x11.py 2009-10-01 12:25:22 UTC (rev 5580)
@@ -0,0 +1,465 @@
+"""
+Low level *Skype for Linux* interface implemented using *XWindows messaging*.
+Uses direct *Xlib* calls through *ctypes* module.
+
+This module handles the options that you can pass to `Skype.__init__`
+for Linux machines when the transport is set to *X11*.
+
+No further options are currently supported.
+
+Warning PyGTK framework users
+=============================
+
+The multithreaded architecture of Skype4Py requires a special treatment
+if the Xlib transport is combined with PyGTK GUI framework.
+
+The following code has to be called at the top of your script, before
+PyGTK is even imported.
+
+.. python::
+
+ from Skype4Py.api.posix_x11 import threads_init
+ threads_init()
+
+This function enables multithreading support in Xlib and GDK. If not done
+here, this is enabled for Xlib library when the `Skype` object is instantiated.
+If your script imports the PyGTK module, doing this so late may lead to a
+segmentation fault when the GUI is shown on the screen.
+
+A remedy is to enable the multithreading support before PyGTK is imported
+by calling the ``threads_init`` function.
+"""
+__docformat__ = 'restructuredtext en'
+
+
+import sys
+import threading
+import os
+from ctypes import *
+
+from ctypes.util import find_library
+import time
+import logging
+
+from Skype4Py.api import Command, SkypeAPIBase, \
+ timeout2float, finalize_opts
+from Skype4Py.enums import *
+from Skype4Py.errors import SkypeAPIError
+
+
+__all__ = ['SkypeAPI', 'threads_init']
+
+
+# The Xlib Programming Manual:
+# ============================
+# http://tronche.com/gui/x/xlib/
+
+
+# some Xlib constants
+PropertyChangeMask = 0x400000
+PropertyNotify = 28
+ClientMessage = 33
+PropertyNewValue = 0
+PropertyDelete = 1
+
+
+# some Xlib types
+c_ulong_p = POINTER(c_ulong)
+DisplayP = c_void_p
+Atom = c_ulong
+AtomP = c_ulong_p
+XID = c_ulong
+Window = XID
+Bool = c_int
+Status = c_int
+Time = c_ulong
+c_int_p = POINTER(c_int)
+
+
+# should the structures be aligned to 8 bytes?
+align = (sizeof(c_long) == 8 and sizeof(c_int) == 4)
+
+
+# some Xlib structures
+class XClientMessageEvent(Structure):
+ if align:
+ _fields_ = [('type', c_int),
+ ('pad0', c_int),
+ ('serial', c_ulong),
+ ('send_event', Bool),
+ ('pad1', c_int),
+ ('display', DisplayP),
+ ('window', Window),
+ ('message_type', Atom),
+ ('format', c_int),
+ ('pad2', c_int),
+ ('data', c_char * 20)]
+ else:
+ _fields_ = [('type', c_int),
+ ('serial', c_ulong),
+ ('send_event', Bool),
+ ('display', DisplayP),
+ ('window', Window),
+ ('message_type', Atom),
+ ('format', c_int),
+ ('data', c_char * 20)]
+
+class XPropertyEvent(Structure):
+ if align:
+ _fields_ = [('type', c_int),
+ ('pad0', c_int),
+ ('serial', c_ulong),
+ ('send_event', Bool),
+ ('pad1', c_int),
+ ('display', DisplayP),
+ ('window', Window),
+ ('atom', Atom),
+ ('time', Time),
+ ('state', c_int),
+ ('pad2', c_int)]
+ else:
+ _fields_ = [('type', c_int),
+ ('serial', c_ulong),
+ ('send_event', Bool),
+ ('display', DisplayP),
+ ('window', Window),
+ ('atom', Atom),
+ ('time', Time),
+ ('state', c_int)]
+
+class XErrorEvent(Structure):
+ if align:
+ _fields_ = [('type', c_int),
+ ('pad0', c_int),
+ ('display', DisplayP),
+ ('resourceid', XID),
+ ('serial', c_ulong),
+ ('error_code', c_ubyte),
+ ('request_code', c_ubyte),
+ ('minor_code', c_ubyte)]
+ else:
+ _fields_ = [('type', c_int),
+ ('display', DisplayP),
+ ('resourceid', XID),
+ ('serial', c_ulong),
+ ('error_code', c_ubyte),
+ ('request_code', c_ubyte),
+ ('minor_code', c_ubyte)]
+
+class XEvent(Union):
+ if align:
+ _fields_ = [('type', c_int),
+ ('xclient', XClientMessageEvent),
+ ('xproperty', XPropertyEvent),
+ ('xerror', XErrorEvent),
+ ('pad', c_long * 24)]
+ else:
+ _fields_ = [('type', c_int),
+ ('xclient', XClientMessageEvent),
+ ('xproperty', XPropertyEvent),
+ ('xerror', XErrorEvent),
+ ('pad', c_long * 24)]
+
+XEventP = POINTER(XEvent)
+
+
+if getattr(sys, 'skype4py_setup', False):
+ # we get here if we're building docs; to let the module import without
+ # exceptions, we emulate the X11 library using a class:
+ class X(object):
+ def __getattr__(self, name):
+ return self
+ def __setattr__(self, name, value):
+ pass
+ def __call__(self, *args, **kwargs):
+ pass
+ x11 = X()
+else:
+ # load X11 library (Xlib)
+ libpath = find_library('X11')
+ if not libpath:
+ raise ImportError('Could not find X11 library')
+ x11 = cdll.LoadLibrary(libpath)
+ del libpath
+
+
+# setup Xlib function prototypes
+x11.XCloseDisplay.argtypes = (DisplayP,)
+x11.XCloseDisplay.restype = None
+x11.XCreateSimpleWindow.argtypes = (DisplayP, Window, c_int, c_int, c_uint,
+ c_uint, c_uint, c_ulong, c_ulong)
+x11.XCreateSimpleWindow.restype = Window
+x11.XDefaultRootWindow.argtypes = (DisplayP,)
+x11.XDefaultRootWindow.restype = Window
+x11.XDeleteProperty.argtypes = (DisplayP, Window, Atom)
+x11.XDeleteProperty.restype = None
+x11.XDestroyWindow.argtypes = (DisplayP, Window)
+x11.XDestroyWindow.restype = None
+x11.XFree.argtypes = (c_void_p,)
+x11.XFree.restype = None
+x11.XGetAtomName.argtypes = (DisplayP, Atom)
+x11.XGetAtomName.restype = c_void_p
+x11.XGetErrorText.argtypes = (DisplayP, c_int, c_char_p, c_int)
+x11.XGetErrorText.restype = None
+x11.XGetWindowProperty.argtypes = (DisplayP, Window, Atom, c_long, c_long, Bool,
+ Atom, AtomP, c_int_p, c_ulong_p, c_ulong_p, POINTER(POINTER(Window)))
+x11.XGetWindowProperty.restype = c_int
+x11.XInitThreads.argtypes = ()
+x11.XInitThreads.restype = Status
+x11.XInternAtom.argtypes = (DisplayP, c_char_p, Bool)
+x11.XInternAtom.restype = Atom
+x11.XNextEvent.argtypes = (DisplayP, XEventP)
+x11.XNextEvent.restype = None
+x11.XOpenDisplay.argtypes = (c_char_p,)
+x11.XOpenDisplay.restype = DisplayP
+x11.XPending.argtypes = (DisplayP,)
+x11.XPending.restype = c_int
+x11.XSelectInput.argtypes = (DisplayP, Window, c_long)
+x11.XSelectInput.restype = None
+x11.XSendEvent.argtypes = (DisplayP, Window, Bool, c_long, XEventP)
+x11.XSendEvent.restype = Status
+x11.XLockDisplay.argtypes = (DisplayP,)
+x11.XLockDisplay.restype = None
+x11.XUnlockDisplay.argtypes = (DisplayP,)
+x11.XUnlockDisplay.restype = None
+
+
+def threads_init(gtk=True):
+ """Enables multithreading support in Xlib and PyGTK.
+ See the module docstring for more info.
+
+ :Parameters:
+ gtk : bool
+ May be set to False to skip the PyGTK module.
+ """
+ # enable X11 multithreading
+ x11.XInitThreads()
+ if gtk:
+ from gtk.gdk import threads_init
+ threads_init()
+
+
+class SkypeAPI(SkypeAPIBase):
+ def __init__(self, opts):
+ self.logger = logging.getLogger('Skype4Py.api.posix_x11.SkypeAPI')
+ SkypeAPIBase.__init__(self)
+ finalize_opts(opts)
+
+ # initialize threads if not done already by the user
+ threads_init(gtk=False)
+
+ # init Xlib display
+ self.disp = x11.XOpenDisplay(None)
+ if not self.disp:
+ raise SkypeAPIError('Could not open XDisplay')
+ self.win_root = x11.XDefaultRootWindow(self.disp)
+ self.win_self = x11.XCreateSimpleWindow(self.disp, self.win_root,
+ 100, 100, 100, 100, 1, 0, 0)
+ x11.XSelectInput(self.disp, self.win_root, PropertyChangeMask)
+ self.win_skype = self.get_skype()
+ ctrl = 'SKYPECONTROLAPI_MESSAGE'
+ self.atom_msg = x11.XInternAtom(self.disp, ctrl, False)
+ self.atom_msg_begin = x11.XInternAtom(self.disp, ctrl + '_BEGIN', False)
+
+ self.loop_event = threading.Event()
+ self.loop_timeout = 0.0001
+ self.loop_break = False
+
+ def __del__(self):
+ if x11:
+ if hasattr(self, 'disp'):
+ if hasattr(self, 'win_self'):
+ x11.XDestroyWindow(self.disp, self.win_self)
+ x11.XCloseDisplay(self.disp)
+
+ def run(self):
+ self.logger.info('thread started')
+ # main loop
+ event = XEvent()
+ data = ''
+ while not self.loop_break and x11:
+ while x11.XPending(self.disp):
+ self.loop_timeout = 0.0001
+ x11.XNextEvent(self.disp, byref(event))
+ # events we get here are already prefiltered by the predicate function
+ if event.type == ClientMessage:
+ if event.xclient.format == 8:
+ if event.xclient.message_type == self.atom_msg_begin:
+ data = str(event.xclient.data)
+ elif event.xclient.message_type == self.atom_msg:
+ if data != '':
+ data += str(event.xclient.data)
+ else:
+ self.logger.warning('Middle of Skype X11 message received with no beginning!')
+ else:
+ continue
+ if len(event.xclient.data) != 20 and data:
+ self.notify(data.decode('utf-8'))
+ data = ''
+ elif event.type == PropertyNotify:
+ namep = x11.XGetAtomName(self.disp, event.xproperty.atom)
+ is_inst = (c_char_p(namep).value == '_SKYPE_INSTANCE')
+ x11.XFree(namep)
+ if is_inst:
+ if event.xproperty.state == PropertyNewValue:
+ self.win_skype = self.get_skype()
+ # changing attachment status can cause an event handler to be fired, in
+ # turn it could try to call Attach() and doing this immediately seems to
+ # confuse Skype (command '#0 NAME xxx' returns '#0 CONNSTATUS OFFLINE' :D);
+ # to fix this, we give Skype some time to initialize itself
+ time.sleep(1.0)
+ self.set_attachment_status(apiAttachAvailable)
+ elif event.xproperty.state == PropertyDelete:
+ self.win_skype = None
+ self.set_attachment_status(apiAttachNotAvailable)
+ self.loop_event.wait(self.loop_timeout)
+ if self.loop_event.isSet():
+ self.loop_timeout = 0.0001
+ elif self.loop_timeout < 1.0:
+ self.loop_timeout *= 2
+ self.loop_event.clear()
+ self.logger.info('thread finished')
+
+ def get_skype(self):
+ """Returns Skype window ID or None if Skype not running."""
+ skype_inst = x11.XInternAtom(self.disp, '_SKYPE_INSTANCE', True)
+ if not skype_inst:
+ return
+ type_ret = Atom()
+ format_ret = c_int()
+ nitems_ret = c_ulong()
+ bytes_after_ret = c_ulong()
+ winp = pointer(Window())
+ fail = x11.XGetWindowProperty(self.disp, self.win_root, skype_inst,
+ 0, 1, False, 33, byref(type_ret), byref(format_ret),
+ byref(nitems_ret), byref(bytes_after_ret), byref(winp))
+ if not fail and format_ret.value == 32 and nitems_ret.value == 1:
+ return winp.contents.value
+
+ def close(self):
+ self.loop_break = True
+ self.loop_event.set()
+ while self.isAlive():
+ time.sleep(0.01)
+ SkypeAPIBase.close(self)
+
+ def set_friendly_name(self, friendly_name):
+ SkypeAPIBase.set_friendly_name(self, friendly_name)
+ if self.attachment_status == apiAttachSuccess:
+ # reattach with the new name
+ self.set_attachment_status(apiAttachUnknown)
+ self.attach()
+
+ def attach(self, timeout, wait=True):
+ if self.attachment_status == apiAttachSuccess:
+ return
+ self.acquire()
+ try:
+ if not self.isAlive():
+ try:
+ self.start()
+ except AssertionError:
+ raise SkypeAPIError('Skype API closed')
+ try:
+ self.wait = True
+ t = threading.Timer(timeout2float(timeout), lambda: setattr(self, 'wait', False))
+ if wait:
+ t.start()
+ while self.wait:
+ self.win_skype = self.get_skype()
+ if self.win_skype is not None:
+ break
+ else:
+ time.sleep(1.0)
+ else:
+ raise SkypeAPIError('Skype attach timeout')
+ finally:
+ t.cancel()
+ command = Command('NAME %s' % self.friendly_name, '', True, timeout)
+ self.release()
+ try:
+ self.send_command(command, True)
+ finally:
+ self.acquire()
+ if command.Reply != 'OK':
+ self.win_skype = None
+ self.set_attachment_status(apiAttachRefused)
+ return
+ self.set_attachment_status(apiAttachSuccess)
+ finally:
+ self.release()
+ command = Command('PROTOCOL %s' % self.protocol, Blocking=True)
+ self.send_command(command, True)
+ self.protocol = int(command.Reply.rsplit(None, 1)[-1])
+
+ def is_running(self):
+ return (self.get_skype() is not None)
+
+ def startup(self, minimized, nosplash):
+ # options are not supported as of Skype 1.4 Beta for Linux
+ if not self.is_running():
+ if os.fork() == 0: # we're the child
+ os.setsid()
+ os.execlp('skype')
+
+ def shutdown(self):
+ 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)
+ # Skype sometimes doesn't delete the '_SKYPE_INSTANCE' property
+ skype_inst = x11.XInternAtom(self.disp, '_SKYPE_INSTANCE', True)
+ if skype_inst:
+ x11.XDeleteProperty(self.disp, self.win_root, skype_inst)
+ self.win_skype = None
+ self.set_attachment_status(apiAttachNotAvailable)
+
+ def send_command(self, command, force=False):
+ if self.attachment_status != apiAttachSuccess and not force:
+ self.attach(command.Timeout)
+ self.push_command(command)
+ self.notifier.sending_command(command)
+ cmd = u'#%d %s' % (command.Id, command.Command)
+ self.logger.debug('sending %s', repr(cmd))
+ if command.Blocking:
+ command._event = bevent = threading.Event()
+ else:
+ command._timer = timer = threading.Timer(command.timeout2float(), self.pop_command, (command.Id,))
+ event = XEvent()
+ event.xclient.type = ClientMessage
+ event.xclient.display = self.disp
+ event.xclient.window = self.win_self
+ event.xclient.message_type = self.atom_msg_begin
+ event.xclient.format = 8
+ cmd = cmd.encode('utf-8') + '\x00'
+ for i in xrange(0, len(cmd), 20):
+ event.xclient.data = cmd[i:i + 20]
+ x11.XSendEvent(self.disp, self.win_skype, False, 0, byref(event))
+ event.xclient.message_type = self.atom_msg
+ self.loop_event.set()
+ if command.Blocking:
+ bevent.wait(command.timeout2float())
+ if not bevent.isSet():
+ raise SkypeAPIError('Skype command timeout')
+ else:
+ timer.start()
+
+ def notify(self, cmd):
+ self.logger.debug('received %s', repr(cmd))
+ # Called by main loop for all received Skype commands.
+ if cmd.startswith(u'#'):
+ p = cmd.find(u' ')
+ command = self.pop_command(int(cmd[1:p]))
+ if command is not None:
+ command.Reply = cmd[p + 1:]
+ if command.Blocking:
+ command._event.set()
+ else:
+ command._timer.cancel()
+ self.notifier.reply_received(command)
+ else:
+ self.notifier.notification_received(cmd[p + 1:])
+ else:
+ self.notifier.notification_received(cmd)
Added: software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/windows.py
===================================================================
--- software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/windows.py (rev 0)
+++ software_suite_v3/software/plugin/plugin-skype/trunk/executables/Skype4Py/api/windows.py 2009-10-01 12:25:22 UTC (rev 5580)
@@ -0,0 +1,352 @@
+"""
+Low level *Skype for Windows* interface implemented using *Windows messaging*.
+Uses direct *WinAPI* calls through *ctypes* module.
+
+This module handles the options that you can pass to `Skype.__init__`
+for Windows machines.
+
+No options are currently supported.
+"""
+__docformat__ = 'restructuredtext en'
+
+
+import sys
+import threading
+import time
+from ctypes import *
+import logging
+
+from Skype4Py.api import Command, SkypeAPIBase, \
+ timeout2float, finalize_opts, \
+ DEFAULT_TIMEOUT
+from Skype4Py.enums import *
+from Skype4Py.errors import SkypeAPIError
+
+
+__all__ = ['SkypeAPI']
+
+
+try:
+ WNDPROC = WINFUNCTYPE(c_long, c_int, c_uint, c_int, c_int)
+except NameError:
+ # Proceed only if our setup.py is not running.
+ if not getattr(sys, 'skype4py_setup', False):
+ raise
+ # This will allow importing of this module on non-Windows machines. It won't work
+ # of course but this will allow building documentation on any platform.
+ WNDPROC = c_void_p
+
+
+class WNDCLASS(Structure):
+ _fields_ = [('style', c_uint),
+ ('lpfnWndProc', WNDPROC),
+ ('cbClsExtra', c_int),
+ ('cbWndExtra', c_int),
+ ('hInstance', c_int),
+ ('hIcon', c_int),
+ ('hCursor', c_int),
+ ('hbrBackground', c_int),
+ ('lpszMenuName', c_char_p),
+ ('lpszClassName', c_char_p)]
+
+
+class MSG(Structure):
+ _fields_ = [('hwnd', c_int),
+ ('message', c_uint),
+ ('wParam', c_int),
+ ('lParam', c_int),
+ ('time', c_int),
+ ('pointX', c_long),
+ ('pointY', c_long)]
+
+
+class COPYDATASTRUCT(Structure):
+ _fields_ = [('dwData', POINTER(c_uint)),
+ ('cbData', c_uint),
+ ('lpData', c_char_p)]
+
+
+PCOPYDATASTRUCT = POINTER(COPYDATASTRUCT)
+
+WM_QUIT = 0x12
+WM_COPYDATA = 0x4A
+
+HWND_BROADCAST = 0xFFFF
+
+
+class SkypeAPI(SkypeAPIBase):
+ def __init__(self, opts):
+ self.logger = logging.getLogger('Skype4Py.api.windows.SkypeAPI')
+ SkypeAPIBase.__init__(self)
+ finalize_opts(opts)
+ self.window_class = None
+ self.hwnd = None
+ self.skype = None
+ self.wait = False
+ self.SkypeControlAPIDiscover = windll.user32.RegisterWindowMessageA('SkypeControlAPIDiscover')
+ self.SkypeControlAPIAttach = windll.user32.RegisterWindowMessageA('SkypeControlAPIAttach')
+ windll.user32.GetWindowLongA.restype = c_ulong
+
+ def run(self):
+ self.logger.info('thread started')
+ if not self.create_window():
+ self.hwnd = None
+ return
+
+ msg = MSG()
+ pmsg = pointer(msg)
+ while self.hwnd and windll.user32.GetMessageA(pmsg, self.hwnd, 0, 0):
+ windll.user32.TranslateMessage(pmsg)
+ windll.user32.DispatchMessageA(pmsg)
+
+ self.destroy_window()
+ self.hwnd = None
+ self.logger.info('thread finished')
+
+ def close(self):
+ if self.hwnd:
+ windll.user32.PostMessageA(self.hwnd, WM_QUIT, 0, 0)
+ while self.hwnd:
+ time.sleep(0.01)
+ self.skype = None
+ SkypeAPIBase.close(self)
+
+ def set_friendly_name(sel...
[truncated message content] |
|
From: jerome <c2m...@c2...> - 2009-10-01 14:14:46
|
Author: jerome
Date: 2009-10-01 15:18:53 +0200 (Thu, 01 Oct 2009)
New Revision: 5582
Modified:
software_suite_v3/software/plugin/plugin-skype/trunk/executables/plugin-skype.py
Log:
* Fixed a dummy bug starting skype client on Windblows.
Modified: software_suite_v3/software/plugin/plugin-skype/trunk/executables/plugin-skype.py
===================================================================
--- software_suite_v3/software/plugin/plugin-skype/trunk/executables/plugin-skype.py 2009-10-01 12:39:26 UTC (rev 5581)
+++ software_suite_v3/software/plugin/plugin-skype/trunk/executables/plugin-skype.py 2009-10-01 13:18:53 UTC (rev 5582)
@@ -95,7 +95,11 @@
"""Plugin entry point.
This method should be used to dispatch commands.
"""
- self.__skype = Skype4Py.Skype(Transport='x11')
+ if os.name != 'nt':
+ self.__skype = Skype4Py.Skype(Transport='x11')
+ else:
+ self.__skype = Skype4Py.Skype()
+
if self.getCommand() == "run":
self.run()
else:
@@ -132,14 +136,14 @@
self.__skype._API.Close()
self.__skype = None
self.__apiAttachState = -1
- if self.__skype.Client.IsRunning != None:
+ if self.__skype.Client.IsRunning:
#Shutting down Skype application.
self.__skype.Client.Shutdown()
refreshTaskBar()
try:
if self.__skype != None:
self.hangUp()
- if self.__skype.Client.IsRunning != None:
+ if self.__skype.Client.IsRunning:
closeSkype()
else:
self.__skype._API.Close()
|
|
From: ks156 <c2m...@c2...> - 2009-10-01 13:56:54
|
Author: ks156
Date: 2009-10-01 15:26:08 +0200 (Thu, 01 Oct 2009)
New Revision: 5583
Modified:
software_suite_v3/smart-core/smart-server/branches/user_mode/installer.nsi
software_suite_v3/smart-core/smart-server/branches/user_mode/util/applicationserver/plugin/interpreters/PluginInterpreter.py
software_suite_v3/smart-core/smart-server/branches/user_mode/version.py
Log:
* Merged r5520 through r5582 from trunk into user_mode
Modified: software_suite_v3/smart-core/smart-server/branches/user_mode/installer.nsi
===================================================================
--- software_suite_v3/smart-core/smart-server/branches/user_mode/installer.nsi 2009-10-01 13:18:53 UTC (rev 5582)
+++ software_suite_v3/smart-core/smart-server/branches/user_mode/installer.nsi 2009-10-01 13:26:08 UTC (rev 5583)
@@ -4,7 +4,7 @@
; HM NIS Edit Wizard helper defines
!define PRODUCT_NAME "Smart Server"
-!define PRODUCT_VERSION "0.4.2-b3"
+!define PRODUCT_VERSION "0.4.3-b0"
; Output names
!define FINAL_INSTALLER_EXE "SmartServerInstaller_${PRODUCT_VERSION}.exe"
Modified: software_suite_v3/smart-core/smart-server/branches/user_mode/util/applicationserver/plugin/interpreters/PluginInterpreter.py
===================================================================
--- software_suite_v3/smart-core/smart-server/branches/user_mode/util/applicationserver/plugin/interpreters/PluginInterpreter.py 2009-10-01 13:18:53 UTC (rev 5582)
+++ software_suite_v3/smart-core/smart-server/branches/user_mode/util/applicationserver/plugin/interpreters/PluginInterpreter.py 2009-10-01 13:26:08 UTC (rev 5583)
@@ -295,11 +295,12 @@
self.__onPluginStartedCallback()
while self.__getRun():
line = self.__process.stdout.readline()
- try:
- tmp = line.decode("latin-1", "ignore")
- line = tmp.encode("utf-8", "ignore")
- except:
- pass
+ if os.name == 'nt':
+ try:
+ tmp = line.decode("latin-1", "ignore")
+ line = tmp.encode("utf-8", "ignore")
+ except:
+ pass
if len(line) == 0:
self.__setRun(False)
if self.__onPluginStoppedCallback != None:
Modified: software_suite_v3/smart-core/smart-server/branches/user_mode/version.py
===================================================================
--- software_suite_v3/smart-core/smart-server/branches/user_mode/version.py 2009-10-01 13:18:53 UTC (rev 5582)
+++ software_suite_v3/smart-core/smart-server/branches/user_mode/version.py 2009-10-01 13:26:08 UTC (rev 5583)
@@ -7,7 +7,7 @@
# Distributed under the terms of the GNU General Public License
# http://www.gnu.org/copyleft/gpl.html
-version = '0.4.2-b3'
+version = '0.4.3-b0'
author = "Remi Jocaille (rem...@c2...)"
licence = "GPL"
date = "2009"
|
|
From: remi <c2m...@c2...> - 2009-10-01 08:58:35
|
Author: remi
Date: 2009-10-01 10:58:23 +0200 (Thu, 01 Oct 2009)
New Revision: 5576
Modified:
software_suite_v3/smart-core/smart-lib/java/smart-core-paths/trunk/pom.xml
Log:
* Updated version to 0.0.2
Modified: software_suite_v3/smart-core/smart-lib/java/smart-core-paths/trunk/pom.xml
===================================================================
--- software_suite_v3/smart-core/smart-lib/java/smart-core-paths/trunk/pom.xml 2009-10-01 08:57:57 UTC (rev 5575)
+++ software_suite_v3/smart-core/smart-lib/java/smart-core-paths/trunk/pom.xml 2009-10-01 08:58:23 UTC (rev 5576)
@@ -3,7 +3,7 @@
<groupId>com.kysoh</groupId>
<artifactId>smart-core-paths</artifactId>
<packaging>jar</packaging>
- <version>0.0.1</version>
+ <version>0.0.2</version>
<name>Smart-Core Paths Library</name>
<url>http://www.tuxisalive.com</url>
<dependencies/>
|
|
From: remi <c2m...@c2...> - 2009-10-01 08:58:08
|
Author: remi Date: 2009-10-01 10:57:57 +0200 (Thu, 01 Oct 2009) New Revision: 5575 Added: software_suite_v3/smart-core/smart-lib/java/smart-core-paths/tags/0.0.1/ Log: * Tagged to 0.0.1 Copied: software_suite_v3/smart-core/smart-lib/java/smart-core-paths/tags/0.0.1 (from rev 5031, software_suite_v3/smart-core/smart-lib/java/smart-core-paths/trunk) |
|
From: remi <c2m...@c2...> - 2009-10-01 08:57:01
|
Author: remi
Date: 2009-10-01 10:56:51 +0200 (Thu, 01 Oct 2009)
New Revision: 5574
Modified:
software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/simpleplugin-java-kit/trunk/pom.xml
Log:
* Updated version to 0.0.4
Modified: software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/simpleplugin-java-kit/trunk/pom.xml
===================================================================
--- software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/simpleplugin-java-kit/trunk/pom.xml 2009-10-01 08:56:25 UTC (rev 5573)
+++ software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/simpleplugin-java-kit/trunk/pom.xml 2009-10-01 08:56:51 UTC (rev 5574)
@@ -3,7 +3,7 @@
<groupId>com.kysoh</groupId>
<artifactId>tuxdroid-plugin-java-kit</artifactId>
<packaging>jar</packaging>
- <version>0.0.3</version>
+ <version>0.0.4</version>
<name>Smart-Core Plugin Java Kit</name>
<url>http://www.tuxisalive.com</url>
<dependencies>
|
|
From: remi <c2m...@c2...> - 2009-10-01 08:56:36
|
Author: remi Date: 2009-10-01 10:56:25 +0200 (Thu, 01 Oct 2009) New Revision: 5573 Added: software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/simpleplugin-java-kit/tags/0.0.3/ Log: * Tagged to 0.0.3 Copied: software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/simpleplugin-java-kit/tags/0.0.3 (from rev 4732, software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/simpleplugin-java-kit/trunk) |
|
From: remi <c2m...@c2...> - 2009-10-01 08:55:19
|
Author: remi
Date: 2009-10-01 10:55:09 +0200 (Thu, 01 Oct 2009)
New Revision: 5572
Modified:
software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/skeleton/trunk/pom.xml
software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/skeleton/trunk/resources/plugin.xml
Log:
* Updated version to 0.0.2
Modified: software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/skeleton/trunk/pom.xml
===================================================================
--- software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/skeleton/trunk/pom.xml 2009-10-01 08:54:45 UTC (rev 5571)
+++ software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/skeleton/trunk/pom.xml 2009-10-01 08:55:09 UTC (rev 5572)
@@ -4,7 +4,7 @@
<groupId>com.kysoh</groupId>
<artifactId>plugin-javaSkeleton</artifactId>
<packaging>jar</packaging>
- <version>0.0.1</version>
+ <version>0.0.2</version>
<name>This is a skeleton to build a java plugin.</name>
<url>http://www.tuxisalive.com</url>
Modified: software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/skeleton/trunk/resources/plugin.xml
===================================================================
--- software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/skeleton/trunk/resources/plugin.xml 2009-10-01 08:54:45 UTC (rev 5571)
+++ software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/skeleton/trunk/resources/plugin.xml 2009-10-01 08:55:09 UTC (rev 5572)
@@ -8,7 +8,7 @@
<ttsName>Java plugin.</ttsName>
<description>This is a skeleton to build a java plugin.</description>
<author>Kysoh</author>
- <version>0.0.1</version>
+ <version>0.0.2</version>
<iconFile>resources/icon.png</iconFile>
<uuid>23ab109b-9bad-41cb-bca6-ab6d4bbe632f</uuid>
<platform>all</platform>
|
|
From: remi <c2m...@c2...> - 2009-10-01 08:55:00
|
Author: remi Date: 2009-10-01 10:54:45 +0200 (Thu, 01 Oct 2009) New Revision: 5571 Added: software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/skeleton/tags/0.0.1/ Log: * Tagged to 0.0.1 Copied: software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/skeleton/tags/0.0.1 (from rev 4735, software_suite_v3/smart-core/smart-dev/plugin-toolkit/java/skeleton/trunk) |
|
From: remi <c2m...@c2...> - 2009-10-01 08:53:49
|
Author: remi Date: 2009-10-01 10:53:33 +0200 (Thu, 01 Oct 2009) New Revision: 5570 Modified: software_suite_v3/smart-core/smart-dev/plugin-toolkit/python/skeleton/trunk/builder/version.py software_suite_v3/smart-core/smart-dev/plugin-toolkit/python/skeleton/trunk/executables/plugin-skeleton.py software_suite_v3/smart-core/smart-dev/plugin-toolkit/python/skeleton/trunk/resources/plugin.xml Log: * Updated version to 0.0.2 Modified: software_suite_v3/smart-core/smart-dev/plugin-toolkit/python/skeleton/trunk/builder/version.py =================================================================== --- software_suite_v3/smart-core/smart-dev/plugin-toolkit/python/skeleton/trunk/builder/version.py 2009-10-01 08:53:00 UTC (rev 5569) +++ software_suite_v3/smart-core/smart-dev/plugin-toolkit/python/skeleton/trunk/builder/version.py 2009-10-01 08:53:33 UTC (rev 5570) @@ -3,7 +3,7 @@ # Distributed under the terms of the GNU General Public License # http://www.gnu.org/copyleft/gpl.html -version = '0.0.1' +version = '0.0.2' author = "Remi Jocaille (rem...@c2...)" licence = "GPL" date = "2009" Modified: software_suite_v3/smart-core/smart-dev/plugin-toolkit/python/skeleton/trunk/executables/plugin-skeleton.py =================================================================== --- software_suite_v3/smart-core/smart-dev/plugin-toolkit/python/skeleton/trunk/executables/plugin-skeleton.py 2009-10-01 08:53:00 UTC (rev 5569) +++ software_suite_v3/smart-core/smart-dev/plugin-toolkit/python/skeleton/trunk/executables/plugin-skeleton.py 2009-10-01 08:53:33 UTC (rev 5570) @@ -7,7 +7,7 @@ __author__ = "Kysoh" __appname__ = "Python plugin skeleton" -__version__ = "0.0.1" +__version__ = "0.0.2" __date__ = "2009/05/05" __license__ = "GPL" Modified: software_suite_v3/smart-core/smart-dev/plugin-toolkit/python/skeleton/trunk/resources/plugin.xml =================================================================== --- software_suite_v3/smart-core/smart-dev/plugin-toolkit/python/skeleton/trunk/resources/plugin.xml 2009-10-01 08:53:00 UTC (rev 5569) +++ software_suite_v3/smart-core/smart-dev/plugin-toolkit/python/skeleton/trunk/resources/plugin.xml 2009-10-01 08:53:33 UTC (rev 5570) @@ -8,7 +8,7 @@ <ttsName>Python plugin.</ttsName> <description>This is a skeleton to build a python plugin.</description> <author>Kysoh</author> - <version>0.0.1</version> + <version>0.0.2</version> <iconFile>resources/icon.png</iconFile> <uuid>23ab109b-9bad-41cb-bca6-ab6d4bbe632e</uuid> <platform>all</platform> |
|
From: remi <c2m...@c2...> - 2009-10-01 08:53:14
|
Author: remi Date: 2009-10-01 10:53:00 +0200 (Thu, 01 Oct 2009) New Revision: 5569 Added: software_suite_v3/smart-core/smart-dev/plugin-toolkit/python/skeleton/tags/0.0.1/ Log: * Tagged to 0.0.1 Copied: software_suite_v3/smart-core/smart-dev/plugin-toolkit/python/skeleton/tags/0.0.1 (from rev 4941, software_suite_v3/smart-core/smart-dev/plugin-toolkit/python/skeleton/trunk) |
|
From: remi <c2m...@c2...> - 2009-10-01 08:51:29
|
Author: remi
Date: 2009-10-01 10:51:18 +0200 (Thu, 01 Oct 2009)
New Revision: 5568
Modified:
software_suite_v3/smart-core/smart-api/python/trunk/installer.nsi
software_suite_v3/smart-core/smart-api/python/trunk/setup.py
software_suite_v3/smart-core/smart-api/python/trunk/tuxisalive/api/version.py
Log:
* Updated version 0.5.0
Modified: software_suite_v3/smart-core/smart-api/python/trunk/installer.nsi
===================================================================
--- software_suite_v3/smart-core/smart-api/python/trunk/installer.nsi 2009-10-01 08:50:11 UTC (rev 5567)
+++ software_suite_v3/smart-core/smart-api/python/trunk/installer.nsi 2009-10-01 08:51:18 UTC (rev 5568)
@@ -4,7 +4,7 @@
; HM NIS Edit Wizard helper defines
!define PRODUCT_NAME "Smart API for python"
-!define PRODUCT_VERSION "0.4.0-b1"
+!define PRODUCT_VERSION "0.5.0-b0"
; Output names
!define FINAL_INSTALLER_EXE "pySmartAPIInstaller_${PRODUCT_VERSION}.exe"
Modified: software_suite_v3/smart-core/smart-api/python/trunk/setup.py
===================================================================
--- software_suite_v3/smart-core/smart-api/python/trunk/setup.py 2009-10-01 08:50:11 UTC (rev 5567)
+++ software_suite_v3/smart-core/smart-api/python/trunk/setup.py 2009-10-01 08:51:18 UTC (rev 5568)
@@ -49,7 +49,7 @@
# Install the package
#
setup(name = 'tuxapi',
- version = '0.4.0',
+ version = '0.5.0',
description = 'Python API for Tuxdroid',
author = 'Remi Jocaille',
author_email = 'rem...@c2...',
Modified: software_suite_v3/smart-core/smart-api/python/trunk/tuxisalive/api/version.py
===================================================================
--- software_suite_v3/smart-core/smart-api/python/trunk/tuxisalive/api/version.py 2009-10-01 08:50:11 UTC (rev 5567)
+++ software_suite_v3/smart-core/smart-api/python/trunk/tuxisalive/api/version.py 2009-10-01 08:51:18 UTC (rev 5568)
@@ -7,5 +7,5 @@
author = "Remi Jocaille (rem...@c2...)"
date = "2009"
-version = '0.4.0'
+version = '0.5.0'
licence = "GPL"
|
|
From: remi <c2m...@c2...> - 2009-10-01 08:50:29
|
Author: remi Date: 2009-10-01 10:50:11 +0200 (Thu, 01 Oct 2009) New Revision: 5567 Added: software_suite_v3/smart-core/smart-api/python/tags/0.4.0/ Log: * Tagged to 0.4.0 Copied: software_suite_v3/smart-core/smart-api/python/tags/0.4.0 (from rev 5224, software_suite_v3/smart-core/smart-api/python/trunk) |
|
From: remi <c2m...@c2...> - 2009-10-01 08:44:12
|
Author: remi
Date: 2009-10-01 10:44:06 +0200 (Thu, 01 Oct 2009)
New Revision: 5566
Modified:
software_suite_v3/software/plugin/plugin-xmms/trunk/pom.xml
software_suite_v3/software/plugin/plugin-xmms/trunk/resources/plugin.xml
Log:
* Updated version 3.0
Modified: software_suite_v3/software/plugin/plugin-xmms/trunk/pom.xml
===================================================================
--- software_suite_v3/software/plugin/plugin-xmms/trunk/pom.xml 2009-10-01 08:43:27 UTC (rev 5565)
+++ software_suite_v3/software/plugin/plugin-xmms/trunk/pom.xml 2009-10-01 08:44:06 UTC (rev 5566)
@@ -4,7 +4,7 @@
<groupId>com.kysoh</groupId>
<artifactId>plugin-xmms</artifactId>
<packaging>jar</packaging>
- <version>2.0</version>
+ <version>3.0</version>
<name>XMMS player for Tux Droid</name>
<url>http://www.tuxisalive.com</url>
Modified: software_suite_v3/software/plugin/plugin-xmms/trunk/resources/plugin.xml
===================================================================
--- software_suite_v3/software/plugin/plugin-xmms/trunk/resources/plugin.xml 2009-10-01 08:43:27 UTC (rev 5565)
+++ software_suite_v3/software/plugin/plugin-xmms/trunk/resources/plugin.xml 2009-10-01 08:44:06 UTC (rev 5566)
@@ -8,7 +8,7 @@
<name>Xmms Plugin</name>
<description>Take control of XMMS with the Tux Droid remote control or flippers.</description>
<author>Jérôme Conan</author>
- <version>2.0</version>
+ <version>3.0</version>
<iconFile>resources/plugin.png</iconFile>
<executionMode>command</executionMode>
<uuid>f63af23e-7ae0-4389-b89b-bc5a8185b0c1</uuid>
|
|
From: remi <c2m...@c2...> - 2009-10-01 08:43:39
|
Author: remi Date: 2009-10-01 10:43:27 +0200 (Thu, 01 Oct 2009) New Revision: 5565 Added: software_suite_v3/software/plugin/plugin-xmms/tags/2.0/ Log: * Tagged to 2.0 Copied: software_suite_v3/software/plugin/plugin-xmms/tags/2.0 (from rev 5394, software_suite_v3/software/plugin/plugin-xmms/trunk) |
|
From: remi <c2m...@c2...> - 2009-10-01 08:42:30
|
Author: remi
Date: 2009-10-01 10:42:16 +0200 (Thu, 01 Oct 2009)
New Revision: 5564
Modified:
software_suite_v3/software/plugin/plugin-WMP/trunk/pom.xml
software_suite_v3/software/plugin/plugin-WMP/trunk/resources/plugin.xml
Log:
* Updated version 3.0
Modified: software_suite_v3/software/plugin/plugin-WMP/trunk/pom.xml
===================================================================
--- software_suite_v3/software/plugin/plugin-WMP/trunk/pom.xml 2009-10-01 08:41:55 UTC (rev 5563)
+++ software_suite_v3/software/plugin/plugin-WMP/trunk/pom.xml 2009-10-01 08:42:16 UTC (rev 5564)
@@ -4,7 +4,7 @@
<groupId>com.kysoh</groupId>
<artifactId>plugin-WMP</artifactId>
<packaging>jar</packaging>
- <version>2.0</version>
+ <version>3.0</version>
<name>Windows media player for Tux Droid</name>
<url>http://www.tuxisalive.com</url>
Modified: software_suite_v3/software/plugin/plugin-WMP/trunk/resources/plugin.xml
===================================================================
--- software_suite_v3/software/plugin/plugin-WMP/trunk/resources/plugin.xml 2009-10-01 08:41:55 UTC (rev 5563)
+++ software_suite_v3/software/plugin/plugin-WMP/trunk/resources/plugin.xml 2009-10-01 08:42:16 UTC (rev 5564)
@@ -8,7 +8,7 @@
<name>WMP Plugin</name>
<description>Take control of Windows media player with the Tux Droid remote control or flippers.</description>
<author>Jérôme Conan</author>
- <version>2.0</version>
+ <version>3.0</version>
<iconFile>resources/plugin.png</iconFile>
<uuid>f63af23e-7ae0-4389-b89b-bc5a8185a84f</uuid>
<platform>windows</platform>
|
|
From: remi <c2m...@c2...> - 2009-10-01 08:42:11
|
Author: remi Date: 2009-10-01 10:41:55 +0200 (Thu, 01 Oct 2009) New Revision: 5563 Added: software_suite_v3/software/plugin/plugin-WMP/tags/2.0/ Log: * Tagged to 2.0 Copied: software_suite_v3/software/plugin/plugin-WMP/tags/2.0 (from rev 5394, software_suite_v3/software/plugin/plugin-WMP/trunk) |
|
From: remi <c2m...@c2...> - 2009-10-01 08:41:17
|
Author: remi Date: 2009-10-01 10:41:06 +0200 (Thu, 01 Oct 2009) New Revision: 5562 Added: software_suite_v3/software/plugin/plugin-webradio-de/trunk/README Log: * Added a note about this plugin. "This plugin is a temporary hack of the webradio plugin. It will be deleted ..." Added: software_suite_v3/software/plugin/plugin-webradio-de/trunk/README =================================================================== --- software_suite_v3/software/plugin/plugin-webradio-de/trunk/README (rev 0) +++ software_suite_v3/software/plugin/plugin-webradio-de/trunk/README 2009-10-01 08:41:06 UTC (rev 5562) @@ -0,0 +1 @@ +This plugin is a temporary hack of the webradio plugin. It will be deleted ... \ No newline at end of file |
|
From: remi <c2m...@c2...> - 2009-10-01 08:38:15
|
Author: remi
Date: 2009-10-01 10:37:56 +0200 (Thu, 01 Oct 2009)
New Revision: 5561
Modified:
software_suite_v3/software/plugin/plugin-webradio/trunk/executables/plugin-webradio.py
software_suite_v3/software/plugin/plugin-webradio/trunk/resources/plugin.xml
Log:
* Updated version 0.0.10
Modified: software_suite_v3/software/plugin/plugin-webradio/trunk/executables/plugin-webradio.py
===================================================================
--- software_suite_v3/software/plugin/plugin-webradio/trunk/executables/plugin-webradio.py 2009-10-01 08:37:35 UTC (rev 5560)
+++ software_suite_v3/software/plugin/plugin-webradio/trunk/executables/plugin-webradio.py 2009-10-01 08:37:56 UTC (rev 5561)
@@ -62,7 +62,7 @@
__author__ = "Eric Lescaudron AKA Gwadavel"
__appname__ = "tux web radio"
-__version__ = "0.0.9"
+__version__ = "0.0.10"
__date__ = "2009/08/31"
__license__ = "GPL"
Modified: software_suite_v3/software/plugin/plugin-webradio/trunk/resources/plugin.xml
===================================================================
--- software_suite_v3/software/plugin/plugin-webradio/trunk/resources/plugin.xml 2009-10-01 08:37:35 UTC (rev 5560)
+++ software_suite_v3/software/plugin/plugin-webradio/trunk/resources/plugin.xml 2009-10-01 08:37:56 UTC (rev 5561)
@@ -8,7 +8,7 @@
<ttsName>Plugin webradio.</ttsName>
<description>This plugin controls the webradios.</description>
<author>Gwadavel and Kysoh</author>
- <version>0.0.9</version>
+ <version>0.0.10</version>
<iconFile>resources/icon.png</iconFile>
<uuid>8349ed52-572d-4c3f-a7b8-05c2a8aec2c6</uuid>
<platform>all</platform>
|
|
From: remi <c2m...@c2...> - 2009-10-01 08:37:55
|
Author: remi Date: 2009-10-01 10:37:35 +0200 (Thu, 01 Oct 2009) New Revision: 5560 Added: software_suite_v3/software/plugin/plugin-webradio/tags/0.0.9/ Log: * Tagged to 0.0.9 Copied: software_suite_v3/software/plugin/plugin-webradio/tags/0.0.9 (from rev 5514, software_suite_v3/software/plugin/plugin-webradio/trunk) |
|
From: remi <c2m...@c2...> - 2009-10-01 08:36:26
|
Author: remi
Date: 2009-10-01 10:36:11 +0200 (Thu, 01 Oct 2009)
New Revision: 5559
Modified:
software_suite_v3/software/plugin/plugin-weather/trunk/plugin-weather/pom.xml
software_suite_v3/software/plugin/plugin-weather/trunk/plugin-weather/resources/plugin.xml
Log:
* Updated version 3.0
Modified: software_suite_v3/software/plugin/plugin-weather/trunk/plugin-weather/pom.xml
===================================================================
--- software_suite_v3/software/plugin/plugin-weather/trunk/plugin-weather/pom.xml 2009-10-01 08:35:53 UTC (rev 5558)
+++ software_suite_v3/software/plugin/plugin-weather/trunk/plugin-weather/pom.xml 2009-10-01 08:36:11 UTC (rev 5559)
@@ -4,7 +4,7 @@
<groupId>com.kysoh</groupId>
<artifactId>plugin-weather</artifactId>
<packaging>jar</packaging>
- <version>2.0</version>
+ <version>3.0</version>
<name>Weather forecast plugin for Tux Droid</name>
<url>http://www.tuxisalive.com</url>
Modified: software_suite_v3/software/plugin/plugin-weather/trunk/plugin-weather/resources/plugin.xml
===================================================================
--- software_suite_v3/software/plugin/plugin-weather/trunk/plugin-weather/resources/plugin.xml 2009-10-01 08:35:53 UTC (rev 5558)
+++ software_suite_v3/software/plugin/plugin-weather/trunk/plugin-weather/resources/plugin.xml 2009-10-01 08:36:11 UTC (rev 5559)
@@ -9,7 +9,7 @@
<ttsName>Weather Plugin</ttsName>
<description>Google Weather Plugin</description>
<author>Yoran Brault</author>
- <version>2.0</version>
+ <version>3.0</version>
<iconFile>resources/plugin.png</iconFile>
<executionMode>service</executionMode>
<uuid>f63af23e-7ae0-4389-b89b-bc5a8185b0b8</uuid>
|
|
From: remi <c2m...@c2...> - 2009-10-01 08:36:05
|
Author: remi Date: 2009-10-01 10:35:53 +0200 (Thu, 01 Oct 2009) New Revision: 5558 Added: software_suite_v3/software/plugin/plugin-weather/tags/2.0/ Log: * Tagged to 2.0 Copied: software_suite_v3/software/plugin/plugin-weather/tags/2.0 (from rev 5407, software_suite_v3/software/plugin/plugin-weather/trunk) |
|
From: remi <c2m...@c2...> - 2009-10-01 08:30:09
|
Author: remi
Date: 2009-10-01 10:29:54 +0200 (Thu, 01 Oct 2009)
New Revision: 5557
Modified:
software_suite_v3/software/plugin/plugin-twitter/trunk/plugin-twitter/pom.xml
software_suite_v3/software/plugin/plugin-twitter/trunk/plugin-twitter/resources/plugin.xml
Log:
* Updated version 3.0
Modified: software_suite_v3/software/plugin/plugin-twitter/trunk/plugin-twitter/pom.xml
===================================================================
--- software_suite_v3/software/plugin/plugin-twitter/trunk/plugin-twitter/pom.xml 2009-10-01 08:29:28 UTC (rev 5556)
+++ software_suite_v3/software/plugin/plugin-twitter/trunk/plugin-twitter/pom.xml 2009-10-01 08:29:54 UTC (rev 5557)
@@ -4,7 +4,7 @@
<groupId>com.kysoh</groupId>
<artifactId>plugin-twitter</artifactId>
<packaging>jar</packaging>
- <version>2.0</version>
+ <version>3.0</version>
<name>Twitter plugin for Tux Droid</name>
<url>http://www.tuxisalive.com</url>
Modified: software_suite_v3/software/plugin/plugin-twitter/trunk/plugin-twitter/resources/plugin.xml
===================================================================
--- software_suite_v3/software/plugin/plugin-twitter/trunk/plugin-twitter/resources/plugin.xml 2009-10-01 08:29:28 UTC (rev 5556)
+++ software_suite_v3/software/plugin/plugin-twitter/trunk/plugin-twitter/resources/plugin.xml 2009-10-01 08:29:54 UTC (rev 5557)
@@ -9,7 +9,7 @@
<ttsName>Twitter</ttsName>
<description>The Twitter plugin will make Tux Droid read your tweets from your Twitter account.</description>
<author>Jérôme Conan</author>
- <version>2.0</version>
+ <version>3.0</version>
<iconFile>resources/plugin.png</iconFile>
<executionMode>command</executionMode>
<uuid>623afa3f-7ae3-43f9-b89b-bc5a8185b0cf</uuid>
|
|
From: remi <c2m...@c2...> - 2009-10-01 08:29:40
|
Author: remi Date: 2009-10-01 10:29:28 +0200 (Thu, 01 Oct 2009) New Revision: 5556 Added: software_suite_v3/software/plugin/plugin-twitter/tags/2.0/ Log: * Tagged to 2.0 Copied: software_suite_v3/software/plugin/plugin-twitter/tags/2.0 (from rev 5394, software_suite_v3/software/plugin/plugin-twitter/trunk) |