Package Camelot :: Package camelot :: Package view :: Module remote_signals |
[frames] | no frames]

# Source Code for Module Camelot.camelot.view.remote_signals

      1  #  ==================================================================================
      2  #
      3  #  Copyright (C) 2007-2008 Conceptive Engineering bvba. All rights reserved.
      4  #  www.conceptive.be / project-camelot@conceptive.be
      5  #
      6  #  This file is part of the Camelot Library.
      7  #
      8  #  This file may be used under the terms of the GNU General Public
      9  #  License version 2.0 as published by the Free Software Foundation
     10  #  and appearing in the file LICENSE.GPL included in the packaging of
     11  #  this file.  Please review the following information to ensure GNU
     12  #  General Public Licensing requirements will be met:
     13  #  http://www.trolltech.com/products/qt/opensource.html
     14  #
     15  #  If you are unsure which license is appropriate for your use, please
     16  #  review the following information:
     17  #  http://www.trolltech.com/products/qt/licensing.html or contact
     18  #  project-camelot@conceptive.be.
     19  #
     20  #  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
     21  #  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     22  #
     23  #  For use of this library in commercial applications, please contact
     24  #  project-camelot@conceptive.be
     25  #
     26  #  ==================================================================================
     27
     28  """
     29  Classes to connect the QT event loop with a messaging
     30  server.  To enable multiple clients to push model updates
     31  to each other or messages for the users.
     32
     33  As a messaging server, Apache active MQ was tested in combination
     34  with the stomp library (http://docs.codehaus.org/display/STOMP/Python)
     35  """
     36
     37  import logging
     38  import re
     39
     40  logger = logging.getLogger('remote_signals')
     41
     42  from PyQt4.QtCore import *
     43
     44 -class SignalHandler(QObject):
     45 -    def __init__(self):
     46          QObject.__init__(self)
     47          import settings
     48          self.entity_update_signal = SIGNAL("entity_update")
     49          self.entity_delete_signal = SIGNAL("entity_delete")
     50          self.entity_create_signal = SIGNAL("entity_create")
     51          self.update_expression = re.compile(r'^/topic/Camelot.Entity.(?P<entity>.*).update$')
     52          if hasattr(settings, 'CAMELOT_SERVER') and settings.CAMELOT_SERVER:
     53              from stomp import stomp
     54              self.connection = stomp.Connection(host_and_ports = [ (settings.CAMELOT_SERVER, 61613) ])
     55              self.connection.add_listener(self)
     56              self.connection.start()
     57              logger.debug('connection to servers started')
     58          else:
     59              self.connection = None
     60              logger.debug('not connected to a server')
     61 -    def on_error(self, headers, message):
     62          logger.error('received an error %s'%message)
     63 -    def on_message(self, headers, message):
     64          from elixir import entities
     65          logger.debug('received a message %s : %s'%(str(headers),message))
     66          match = self.update_expression.match(headers['destination'])
     67          if match:
     68              entity = match.group('entity')
     69              logger.debug(' decoded as update signal for entity %s'%entity)
     70              self.emit(self.entity_update_signal, self, [e for e in entities if e.__name__==entity][0].get(eval(message)))
     71 -    def on_connecting(self, server):
     72          logger.debug('try to connect to message service')
     73          self.connection.connect()
     74 -    def on_connected(self, *args, **kwargs):
     75          logger.debug('connected to message service %s, %s'%((str(args), str(kwargs))))
     76          self.connection.subscribe(destination='/topic/Camelot.Entity.>', ack='auto')
     77 -    def on_disconnected(self):
     78          logger.debug('stomp service disconnected')
     79 -    def send_entity_update(self, sender, entity, scope='local'):
     80          self.sendEntityUpdate(sender, entity, scope)
     81 -    def sendEntityUpdate(self, sender, entity, scope='local'):
     82          # deprecated
     83          self.emit(self.entity_update_signal, sender, entity)
     84          if self.connection and scope=='remote':
     85              self.connection.send(str([entity.id]), destination='/topic/Camelot.Entity.%s.update'%entity.__class__.__name__)
     86 -    def sendEntityDelete(self, sender, entity, scope='local'):
     87          if self.connection and scope=='remote':
     88              self.connection.send(str([entity.id]), destination='/topic/Camelot.Entity.%s.delete'%entity.__class__.__name__)
     89 -    def sendEntityCreate(self, sender, entity, scope='local'):
     90          if self.connection and scope=='remote':
     91              self.connection.send(str([entity.id]), destination='/topic/Camelot.Entity.%s.create'%entity.__class__.__name__)
     92
     93  _signal_handler_ = []
     94
     95 -def construct_signal_handler(*args, **kwargs):
     96      _signal_handler_.append(SignalHandler(*args, **kwargs))
     97
     98 -def get_signal_handler():
     99      if not len(_signal_handler_):
    100          construct_signal_handler()
    101      return _signal_handler_[-1]
    102
    103 -def has_signal_handler():
    104      return len(_signal_handler_)
    105