home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / var / lib / python-support / python2.6 / dbus / proxies.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  19.6 KB  |  434 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import sys
  5. import logging
  6.  
  7. try:
  8.     from threading import RLock
  9. except ImportError:
  10.     from dummy_threading import RLock
  11.  
  12. import _dbus_bindings
  13. from dbus._expat_introspect_parser import process_introspection_data
  14. from dbus.exceptions import MissingReplyHandlerException, MissingErrorHandlerException, IntrospectionParserException, DBusException
  15. __docformat__ = 'restructuredtext'
  16. _logger = logging.getLogger('dbus.proxies')
  17. from _dbus_bindings import LOCAL_PATH, BUS_DAEMON_NAME, BUS_DAEMON_PATH, BUS_DAEMON_IFACE, INTROSPECTABLE_IFACE
  18.  
  19. class _DeferredMethod:
  20.     '''A proxy method which will only get called once we have its
  21.     introspection reply.
  22.     '''
  23.     
  24.     def __init__(self, proxy_method, append, block):
  25.         self._proxy_method = proxy_method
  26.         self._method_name = proxy_method._method_name
  27.         self._append = append
  28.         self._block = block
  29.  
  30.     
  31.     def __call__(self, *args, **keywords):
  32.         if keywords.has_key('reply_handler') or keywords.get('ignore_reply', False):
  33.             self._append(self._proxy_method, args, keywords)
  34.             return None
  35.         self._block()
  36.         return self._proxy_method(*args, **keywords)
  37.  
  38.     
  39.     def call_async(self, *args, **keywords):
  40.         self._append(self._proxy_method, args, keywords)
  41.  
  42.  
  43.  
  44. class _ProxyMethod:
  45.     '''A proxy method.
  46.  
  47.     Typically a member of a ProxyObject. Calls to the
  48.     method produce messages that travel over the Bus and are routed
  49.     to a specific named Service.
  50.     '''
  51.     
  52.     def __init__(self, proxy, connection, bus_name, object_path, method_name, iface):
  53.         if object_path == LOCAL_PATH:
  54.             raise DBusException('Methods may not be called on the reserved path %s' % LOCAL_PATH)
  55.         object_path == LOCAL_PATH
  56.         self._proxy = proxy
  57.         self._connection = connection
  58.         self._named_service = bus_name
  59.         self._object_path = object_path
  60.         _dbus_bindings.validate_member_name(method_name)
  61.         self._method_name = method_name
  62.         if iface is not None:
  63.             _dbus_bindings.validate_interface_name(iface)
  64.         
  65.         self._dbus_interface = iface
  66.  
  67.     
  68.     def __call__(self, *args, **keywords):
  69.         reply_handler = keywords.pop('reply_handler', None)
  70.         error_handler = keywords.pop('error_handler', None)
  71.         ignore_reply = keywords.pop('ignore_reply', False)
  72.         if reply_handler is not None or error_handler is not None:
  73.             if reply_handler is None:
  74.                 raise MissingReplyHandlerException()
  75.             reply_handler is None
  76.             if error_handler is None:
  77.                 raise MissingErrorHandlerException()
  78.             error_handler is None
  79.             if ignore_reply:
  80.                 raise TypeError('ignore_reply and reply_handler cannot be used together')
  81.             ignore_reply
  82.         
  83.         dbus_interface = keywords.pop('dbus_interface', self._dbus_interface)
  84.         if dbus_interface is None:
  85.             key = self._method_name
  86.         else:
  87.             key = dbus_interface + '.' + self._method_name
  88.         introspect_sig = self._proxy._introspect_method_map.get(key, None)
  89.         if ignore_reply or reply_handler is not None:
  90.             self._connection.call_async(self._named_service, self._object_path, dbus_interface, self._method_name, introspect_sig, args, reply_handler, error_handler, **keywords)
  91.         else:
  92.             return self._connection.call_blocking(self._named_service, self._object_path, dbus_interface, self._method_name, introspect_sig, args, **keywords)
  93.         return reply_handler is not None
  94.  
  95.     
  96.     def call_async(self, *args, **keywords):
  97.         reply_handler = keywords.pop('reply_handler', None)
  98.         error_handler = keywords.pop('error_handler', None)
  99.         dbus_interface = keywords.pop('dbus_interface', self._dbus_interface)
  100.         if dbus_interface:
  101.             key = dbus_interface + '.' + self._method_name
  102.         else:
  103.             key = self._method_name
  104.         introspect_sig = self._proxy._introspect_method_map.get(key, None)
  105.         self._connection.call_async(self._named_service, self._object_path, dbus_interface, self._method_name, introspect_sig, args, reply_handler, error_handler, **keywords)
  106.  
  107.  
  108.  
  109. class ProxyObject(object):
  110.     '''A proxy to the remote Object.
  111.  
  112.     A ProxyObject is provided by the Bus. ProxyObjects
  113.     have member functions, and can be called like normal Python objects.
  114.     '''
  115.     ProxyMethodClass = _ProxyMethod
  116.     DeferredMethodClass = _DeferredMethod
  117.     INTROSPECT_STATE_DONT_INTROSPECT = 0
  118.     INTROSPECT_STATE_INTROSPECT_IN_PROGRESS = 1
  119.     INTROSPECT_STATE_INTROSPECT_DONE = 2
  120.     
  121.     def __init__(self, conn = None, bus_name = None, object_path = None, introspect = True, follow_name_owner_changes = False, **kwargs):
  122.         '''Initialize the proxy object.
  123.  
  124.         :Parameters:
  125.             `conn` : `dbus.connection.Connection`
  126.                 The bus or connection on which to find this object.
  127.                 The keyword argument `bus` is a deprecated alias for this.
  128.             `bus_name` : str
  129.                 A bus name for the application owning the object, to be used
  130.                 as the destination for method calls and the sender for
  131.                 signal matches. The keyword argument ``named_service`` is a
  132.                 deprecated alias for this.
  133.             `object_path` : str
  134.                 The object path at which the application exports the object
  135.             `introspect` : bool
  136.                 If true (default), attempt to introspect the remote
  137.                 object to find out supported methods and their signatures
  138.             `follow_name_owner_changes` : bool
  139.                 If true (default is false) and the `bus_name` is a
  140.                 well-known name, follow ownership changes for that name
  141.         '''
  142.         bus = kwargs.pop('bus', None)
  143.         if bus is not None:
  144.             if conn is not None:
  145.                 raise TypeError('conn and bus cannot both be specified')
  146.             conn is not None
  147.             conn = bus
  148.             warn = warn
  149.             import warnings
  150.             warn('Passing the bus parameter to ProxyObject by name is deprecated: please use positional parameters', DeprecationWarning, stacklevel = 2)
  151.         
  152.         named_service = kwargs.pop('named_service', None)
  153.         if named_service is not None:
  154.             if bus_name is not None:
  155.                 raise TypeError('bus_name and named_service cannot both be specified')
  156.             bus_name is not None
  157.             bus_name = named_service
  158.             warn = warn
  159.             import warnings
  160.             warn('Passing the named_service parameter to ProxyObject by name is deprecated: please use positional parameters', DeprecationWarning, stacklevel = 2)
  161.         
  162.         if kwargs:
  163.             raise TypeError('ProxyObject.__init__ does not take these keyword arguments: %s' % ', '.join(kwargs.iterkeys()))
  164.         kwargs
  165.         if follow_name_owner_changes:
  166.             conn._require_main_loop()
  167.         
  168.         self._bus = conn
  169.         if bus_name is not None:
  170.             _dbus_bindings.validate_bus_name(bus_name)
  171.         
  172.         self._named_service = self._requested_bus_name = bus_name
  173.         _dbus_bindings.validate_object_path(object_path)
  174.         self.__dbus_object_path__ = object_path
  175.         if not follow_name_owner_changes:
  176.             self._named_service = conn.activate_name_owner(bus_name)
  177.         
  178.         self._pending_introspect = None
  179.         self._pending_introspect_queue = []
  180.         self._introspect_method_map = { }
  181.         self._introspect_lock = RLock()
  182.         if not introspect or self.__dbus_object_path__ == LOCAL_PATH:
  183.             self._introspect_state = self.INTROSPECT_STATE_DONT_INTROSPECT
  184.         else:
  185.             self._introspect_state = self.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS
  186.             self._pending_introspect = self._Introspect()
  187.  
  188.     bus_name = property((lambda self: self._named_service), None, None, 'The bus name to which this proxy is bound. (Read-only,\n            may change.)\n\n            If the proxy was instantiated using a unique name, this property\n            is that unique name.\n\n            If the proxy was instantiated with a well-known name and with\n            ``follow_name_owner_changes`` set false (the default), this\n            property is the unique name of the connection that owned that\n            well-known name when the proxy was instantiated, which might\n            not actually own the requested well-known name any more.\n\n            If the proxy was instantiated with a well-known name and with\n            ``follow_name_owner_changes`` set true, this property is that\n            well-known name.\n            ')
  189.     requested_bus_name = property((lambda self: self._requested_bus_name), None, None, 'The bus name which was requested when this proxy was\n            instantiated.\n            ')
  190.     object_path = property((lambda self: self.__dbus_object_path__), None, None, 'The object-path of this proxy.')
  191.     
  192.     def connect_to_signal(self, signal_name, handler_function, dbus_interface = None, **keywords):
  193.         """Arrange for the given function to be called when the given signal
  194.         is received.
  195.  
  196.         :Parameters:
  197.             `signal_name` : str
  198.                 The name of the signal
  199.             `handler_function` : callable
  200.                 A function to be called when the signal is emitted by
  201.                 the remote object. Its positional arguments will be the
  202.                 arguments of the signal; optionally, it may be given
  203.                 keyword arguments as described below.
  204.             `dbus_interface` : str
  205.                 Optional interface with which to qualify the signal name.
  206.                 If None (the default) the handler will be called whenever a
  207.                 signal of the given member name is received, whatever
  208.                 its interface.
  209.         :Keywords:
  210.             `utf8_strings` : bool
  211.                 If True, the handler function will receive any string
  212.                 arguments as dbus.UTF8String objects (a subclass of str
  213.                 guaranteed to be UTF-8). If False (default) it will receive
  214.                 any string arguments as dbus.String objects (a subclass of
  215.                 unicode).
  216.             `byte_arrays` : bool
  217.                 If True, the handler function will receive any byte-array
  218.                 arguments as dbus.ByteArray objects (a subclass of str).
  219.                 If False (default) it will receive any byte-array
  220.                 arguments as a dbus.Array of dbus.Byte (subclasses of:
  221.                 a list of ints).
  222.             `sender_keyword` : str
  223.                 If not None (the default), the handler function will receive
  224.                 the unique name of the sending endpoint as a keyword
  225.                 argument with this name
  226.             `destination_keyword` : str
  227.                 If not None (the default), the handler function will receive
  228.                 the bus name of the destination (or None if the signal is a
  229.                 broadcast, as is usual) as a keyword argument with this name.
  230.             `interface_keyword` : str
  231.                 If not None (the default), the handler function will receive
  232.                 the signal interface as a keyword argument with this name.
  233.             `member_keyword` : str
  234.                 If not None (the default), the handler function will receive
  235.                 the signal name as a keyword argument with this name.
  236.             `path_keyword` : str
  237.                 If not None (the default), the handler function will receive
  238.                 the object-path of the sending object as a keyword argument
  239.                 with this name
  240.             `message_keyword` : str
  241.                 If not None (the default), the handler function will receive
  242.                 the `dbus.lowlevel.SignalMessage` as a keyword argument with
  243.                 this name.
  244.             `arg...` : unicode or UTF-8 str
  245.                 If there are additional keyword parameters of the form
  246.                 ``arg``\\ *n*, match only signals where the *n*\\ th argument
  247.                 is the value given for that keyword parameter. As of this time
  248.                 only string arguments can be matched (in particular,
  249.                 object paths and signatures can't).
  250.         """
  251.         return self._bus.add_signal_receiver(handler_function, signal_name = signal_name, dbus_interface = dbus_interface, bus_name = self._named_service, path = self.__dbus_object_path__, **keywords)
  252.  
  253.     
  254.     def _Introspect(self):
  255.         return self._bus.call_async(self._named_service, self.__dbus_object_path__, INTROSPECTABLE_IFACE, 'Introspect', '', (), self._introspect_reply_handler, self._introspect_error_handler, utf8_strings = True, require_main_loop = False)
  256.  
  257.     
  258.     def _introspect_execute_queue(self):
  259.         for proxy_method, args, keywords in self._pending_introspect_queue:
  260.             proxy_method(*args, **keywords)
  261.         
  262.  
  263.     
  264.     def _introspect_reply_handler(self, data):
  265.         self._introspect_lock.acquire()
  266.         
  267.         try:
  268.             self._introspect_method_map = process_introspection_data(data)
  269.         except IntrospectionParserException:
  270.             e = None
  271.             self._introspect_error_handler(e)
  272.             return None
  273.         else:
  274.             self._introspect_state = self.INTROSPECT_STATE_INTROSPECT_DONE
  275.             self._pending_introspect = None
  276.             self._introspect_execute_queue()
  277.         finally:
  278.             self._introspect_lock.release()
  279.  
  280.  
  281.     
  282.     def _introspect_error_handler(self, error):
  283.         logging.basicConfig()
  284.         _logger.error('Introspect error on %s:%s: %s.%s: %s', self._named_service, self.__dbus_object_path__, error.__class__.__module__, error.__class__.__name__, error)
  285.         self._introspect_lock.acquire()
  286.         
  287.         try:
  288.             _logger.debug('Executing introspect queue due to error')
  289.             self._introspect_state = self.INTROSPECT_STATE_DONT_INTROSPECT
  290.             self._pending_introspect = None
  291.             self._introspect_execute_queue()
  292.         finally:
  293.             self._introspect_lock.release()
  294.  
  295.  
  296.     
  297.     def _introspect_block(self):
  298.         self._introspect_lock.acquire()
  299.         
  300.         try:
  301.             if self._pending_introspect is not None:
  302.                 self._pending_introspect.block()
  303.         finally:
  304.             self._introspect_lock.release()
  305.  
  306.  
  307.     
  308.     def _introspect_add_to_queue(self, callback, args, kwargs):
  309.         self._introspect_lock.acquire()
  310.         
  311.         try:
  312.             if self._introspect_state == self.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS:
  313.                 self._pending_introspect_queue.append((callback, args, kwargs))
  314.             else:
  315.                 callback(*args, **kwargs)
  316.         finally:
  317.             self._introspect_lock.release()
  318.  
  319.  
  320.     
  321.     def __getattr__(self, member):
  322.         if member.startswith('__') and member.endswith('__'):
  323.             raise AttributeError(member)
  324.         member.endswith('__')
  325.         return self.get_dbus_method(member)
  326.  
  327.     
  328.     def get_dbus_method(self, member, dbus_interface = None):
  329.         '''Return a proxy method representing the given D-Bus method. The
  330.         returned proxy method can be called in the usual way. For instance, ::
  331.  
  332.             proxy.get_dbus_method("Foo", dbus_interface=\'com.example.Bar\')(123)
  333.  
  334.         is equivalent to::
  335.  
  336.             proxy.Foo(123, dbus_interface=\'com.example.Bar\')
  337.  
  338.         or even::
  339.  
  340.             getattr(proxy, "Foo")(123, dbus_interface=\'com.example.Bar\')
  341.  
  342.         However, using `get_dbus_method` is the only way to call D-Bus
  343.         methods with certain awkward names - if the author of a service
  344.         implements a method called ``connect_to_signal`` or even
  345.         ``__getattr__``, you\'ll need to use `get_dbus_method` to call them.
  346.  
  347.         For services which follow the D-Bus convention of CamelCaseMethodNames
  348.         this won\'t be a problem.
  349.         '''
  350.         ret = self.ProxyMethodClass(self, self._bus, self._named_service, self.__dbus_object_path__, member, dbus_interface)
  351.         if self._introspect_state == self.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS:
  352.             ret = self.DeferredMethodClass(ret, self._introspect_add_to_queue, self._introspect_block)
  353.         
  354.         return ret
  355.  
  356.     
  357.     def __repr__(self):
  358.         return '<ProxyObject wrapping %s %s %s at %#x>' % (self._bus, self._named_service, self.__dbus_object_path__, id(self))
  359.  
  360.     __str__ = __repr__
  361.  
  362.  
  363. class Interface(object):
  364.     '''An interface into a remote object.
  365.  
  366.     An Interface can be used to wrap ProxyObjects
  367.     so that calls can be routed to their correct
  368.     D-Bus interface.
  369.     '''
  370.     
  371.     def __init__(self, object, dbus_interface):
  372.         '''Construct a proxy for the given interface on the given object.
  373.  
  374.         :Parameters:
  375.             `object` : `dbus.proxies.ProxyObject` or `dbus.Interface`
  376.                 The remote object or another of its interfaces
  377.             `dbus_interface` : str
  378.                 An interface the `object` implements
  379.         '''
  380.         if isinstance(object, Interface):
  381.             self._obj = object.proxy_object
  382.         else:
  383.             self._obj = object
  384.         self._dbus_interface = dbus_interface
  385.  
  386.     object_path = property((lambda self: self._obj.object_path), None, None, 'The D-Bus object path of the underlying object')
  387.     __dbus_object_path__ = object_path
  388.     bus_name = property((lambda self: self._obj.bus_name), None, None, 'The bus name to which the underlying proxy object is bound')
  389.     requested_bus_name = property((lambda self: self._obj.requested_bus_name), None, None, 'The bus name which was requested when the underlying object was created')
  390.     proxy_object = property((lambda self: self._obj), None, None, 'The underlying proxy object')
  391.     dbus_interface = property((lambda self: self._dbus_interface), None, None, 'The D-Bus interface represented')
  392.     
  393.     def connect_to_signal(self, signal_name, handler_function, dbus_interface = None, **keywords):
  394.         '''Arrange for a function to be called when the given signal is
  395.         emitted.
  396.  
  397.         The parameters and keyword arguments are the same as for
  398.         `dbus.proxies.ProxyObject.connect_to_signal`, except that if
  399.         `dbus_interface` is None (the default), the D-Bus interface that
  400.         was passed to the `Interface` constructor is used.
  401.         '''
  402.         if not dbus_interface:
  403.             dbus_interface = self._dbus_interface
  404.         
  405.         return self._obj.connect_to_signal(signal_name, handler_function, dbus_interface, **keywords)
  406.  
  407.     
  408.     def __getattr__(self, member):
  409.         if member.startswith('__') and member.endswith('__'):
  410.             raise AttributeError(member)
  411.         member.endswith('__')
  412.         return self._obj.get_dbus_method(member, self._dbus_interface)
  413.  
  414.     
  415.     def get_dbus_method(self, member, dbus_interface = None):
  416.         '''Return a proxy method representing the given D-Bus method.
  417.  
  418.         This is the same as `dbus.proxies.ProxyObject.get_dbus_method`
  419.         except that if `dbus_interface` is None (the default),
  420.         the D-Bus interface that was passed to the `Interface` constructor
  421.         is used.
  422.         '''
  423.         if dbus_interface is None:
  424.             dbus_interface = self._dbus_interface
  425.         
  426.         return self._obj.get_dbus_method(member, dbus_interface)
  427.  
  428.     
  429.     def __repr__(self):
  430.         return '<Interface %r implementing %r at %#x>' % (self._obj, self._dbus_interface, id(self))
  431.  
  432.     __str__ = __repr__
  433.  
  434.