Esempio n. 1
0
    def __init__(self):
        PBDaemon.__init__(self, keeproot=True)
        ZCmdBase.__init__(self)

        self.log.info('Starting...')

        wants_ssl = self.options.ssl
        if wants_ssl and not HAVE_SSL:
            self.log.error('SSL was requested for Jabber connection, but pyopenssl is not installed.  Please install it and start the xmppBot again.')
            sys.exit(2)

        if not self.options.jabber_pass:
            self.log.error('--jabber_pass is required')
            sys.exit(2)

        if not self.options.jabber_user:
            self.log.error('--jabber_user is required')
            sys.exit(2)

        if self.options.first_user:
            try:
                zenUser, jabberId = self.options.first_user.split(',')
            except ValueError:
                self.log.error('--first_user option must contain both zenuser and jabberid separated by a comma.  Example: chudler,[email protected]')
                sys.exit(2)

            if zenUser and jabberId:
                self.setFirstUser(zenUser, jabberId)
            else:
                self.log.error('--first_user option must contain both zenuser and jabberid separated by a comma.  Example: chudler,[email protected]')
                sys.exit(2)

        # taken from zenactions.py
        self.schedule = Schedule(self.options, self.dmd)
        self.actions = []
        self.loadActionRules()
        self.updateCheck = UpdateCheck()

        self.sendEvent(Event.Event(device=self.options.monitor,
        eventClass=App_Start, summary='Jabber Bot started', severity=0, component='xmppbot'))
        self.adapter = JabberAdapter(True)
        password = self.options.jabber_pass
        chatroom = self.options.chatroom
        username = self.options.jabber_user
        host = self.options.jabber_host
        port = self.options.jabber_port
        groupServer = self.options.group_server
        realHost = self.options.im_host
        server = '%s:%s' % (host, port)

        client = TwistedJabberClient(dialogHandler = self.adapter,
        server = server,
        userId = username, userPassword = password,
        firstRoom = chatroom, debug = True,
        groupServer = groupServer, realHost = realHost, wants_ssl = wants_ssl)

        self.adapter.client = client

        path = os.path.realpath(sys.argv[0])
        pluginPath = os.path.dirname(path) + '/Jabber/plugins'
        self.log.info("xmppBot plugins will be loaded from %s" % pluginPath)

        plugins = [pluginFile.split('/')[-1].split('.py')[0] for pluginFile in glob.glob( os.path.join(pluginPath, '*.py') )]
        initPluginSystem({'pluginPath': pluginPath, 'plugins': plugins})

        self.log.info('started')

        # connect to the jabber server
        jabber_reactor = client.connect()

        # begin looking for zenevents
        self.schedule.start()
        self.runCycle()

        # start event loop which will process jabber messages and zenevents
        jabber_reactor.run()
Esempio n. 2
0
class XmppBot(ZenActions, ZCmdBase, PBDaemon):
    def buildOptions(self):
        ZCmdBase.buildOptions(self)
        self.parser.add_option(
            '--jabber_pass',
            dest='jabber_pass',
            type='string',
            help='Password used to connect to the XMPP server')
        self.parser.add_option(
            '--jabber_user',
            dest='jabber_user',
            type='string',
            help='Username used to connect to the XMPP server')
        self.parser.add_option('--jabber_host',
                               dest='jabber_host',
                               type='string',
                               default='localhost',
                               help='(OPTIONAL) XMPP server to connect')
        self.parser.add_option(
            '--jabber_port',
            dest='jabber_port',
            type='int',
            help='(OPTIONAL) Port used to connect to the XMPP server')
        self.parser.add_option(
            '--first_user',
            dest='first_user',
            type='string',
            help=
            'User mapping to bootstrap the bot with at least on authorized user.  Example specification myzenossname,[email protected]'
        )
        self.parser.add_option('--resource',
                               dest='resource',
                               type='string',
                               default='xmppbot',
                               help='(OPTIONAL) jabber resource name.')
        self.parser.add_option(
            '--im_host',
            dest='im_host',
            type='string',
            help=
            '(OPTIONAL) option for addressing IM users when the server is not known.  If this is ommitted, jabber_host will be used.'
        )
        self.parser.add_option('--ssl',
                               dest='ssl',
                               action='store_true',
                               help='(OPTIONAL) ssl.')
        self.parser.add_option(
            '--group_server',
            type='string',
            dest='group_server',
            help=
            '(OPTIONAL) Conference/groupchat server.  If the name has no dots, it will use group_server.jabber_host'
        )
        self.parser.add_option(
            '--chatrooms',
            dest='chatrooms',
            action='append',
            type='string',
            help=
            '(OPTIONAL) First chatroom joined to when connecting.  May be specified multiple times to join multiple rooms.'
        )
        self.parser.add_option(
            '--cycletime',
            dest='cycletime',
            default=60,
            type='int',
            help='(OPTIONAL) check events every cycletime seconds')
        self.parser.add_option(
            '--zopeurl',
            type='string',
            dest='zopeurl',
            default='http://%s:%d' % (socket.getfqdn(), 8080),
            help='(OPTIONAL) http path to the root of the zope server')
        self.parser.add_option(
            '--monitor',
            type='string',
            dest='monitor',
            default=DEFAULT_MONITOR,
            help=
            '(OPTIONAL) Name of monitor instance to use for heartbeat events. Default is %s.'
            % DEFAULT_MONITOR)

    def __init__(self):
        PBDaemon.__init__(self, keeproot=True)
        ZCmdBase.__init__(self)

        wants_ssl = self.options.ssl
        if wants_ssl and not HAVE_SSL:
            self.log.error(
                'SSL was requested for Jabber connection, but pyopenssl is not installed.  Please install it and start the xmppBot again.'
            )
            sys.exit(2)

        if not self.options.jabber_pass:
            self.log.error('--jabber_pass is required')
            sys.exit(2)

        if not self.options.jabber_user:
            self.log.error('--jabber_user is required')
            sys.exit(2)

        if self.options.first_user:
            try:
                zenUser, jabberId = self.options.first_user.split(',')
            except ValueError:
                self.log.error(
                    '--first_user option must contain both zenuser and jabberid separated by a comma.  Example: chudler,[email protected]'
                )
                sys.exit(2)

            if zenUser and jabberId:
                self.setFirstUser(zenUser, jabberId)
            else:
                self.log.error(
                    '--first_user option must contain both zenuser and jabberid separated by a comma.  Example: chudler,[email protected]'
                )
                sys.exit(2)

        # taken from zenactions.py
        self.schedule = Schedule(self.options, self.dmd)
        self.actions = []
        self.loadActionRules()
        self.updateCheck = UpdateCheck()

        self.sendEvent(
            Event.Event(device=self.options.monitor,
                        eventClass=App_Start,
                        summary='Jabber Bot started',
                        severity=0,
                        component='xmppbot'))

        password = self.options.jabber_pass
        chatrooms = self.options.chatrooms
        username = self.options.jabber_user
        server = self.options.jabber_host
        port = self.options.jabber_port
        groupServer = self.options.group_server
        realHost = self.options.im_host
        resource = self.options.resource

        self.client = TwistedJabberClient(server=server,
                                          username=username,
                                          password=password,
                                          port=port,
                                          groupServer=groupServer,
                                          chatrooms=chatrooms,
                                          ssl=wants_ssl,
                                          realHost=realHost,
                                          resource=resource)

        path = os.path.realpath(sys.argv[0])
        pluginPath = os.path.dirname(path) + '/Jabber/plugins'
        self.log.info("xmppBot plugins will be loaded from %s" % pluginPath)

        plugins = [
            pluginFile.split('/')[-1].split('.py')[0]
            for pluginFile in glob.glob(os.path.join(pluginPath, '*.py'))
        ]

        self.log.debug("xmppBot loading pugins  %s" % ', '.join(plugins))
        initPluginSystem(pluginPath=pluginPath,
                         plugins=plugins,
                         jabberClient=self.client)

        # connect to the jabber server
        self.log.info('Connecting to server')
        reactor = self.client.connect()

        # begin looking for zenevents
        self.schedule.start()
        self.runCycle()

        reactor.suggestThreadPoolSize(10)
        reactor.run()

    def setFirstUser(self, zenUser, jabberId):
        zenUser = zenUser.lower()
        haveUser = False
        for user in self.dmd.ZenUsers.getAllUserSettings():
            if user.id.lower() == zenUser:
                haveUser = True
                user._updateProperty('JabberId', jabberId)
                transaction.commit()
                break
        return haveUser

    # ripped from zenactions.py
    def mainbody(self):
        """main loop to run actions.
        """
        from twisted.internet.process import reapAllProcesses
        reapAllProcesses()
        zem = self.dmd.ZenEventManager
        self.loadActionRules()
        self.processRules(zem)

    # ripped from zenactions.py
    def runCycle(self):
        try:
            start = time.time()
            self.syncdb()
            self.mainbody()
            self.log.info('processed %s rules in %.2f secs', len(self.actions),
                          time.time() - start)
        except:
            self.log.exception('unexpected exception')
        reactor.callLater(60, self.runCycle)

    # ripped from zenactions.py
    def loadActionRules(self):
        self.actions = []
        for ar in self.dmd.ZenUsers.getAllActionRules():
            if not ar.enabled: continue
            if not ar.action.title() == 'Xmpp': continue
            userid = ar.getUser().id
            self.actions.append(ar)
            self.log.debug('action:%s for:%s loaded', ar.getId(), userid)

    # ripped from zenactions.py
    def sendHeartbeat(self):
        """Send a heartbeat event for this monitor.
        """
        timeout = self.options.cycletime * 3
        evt = Event.EventHeartbeat(self.options.monitor, 'xmppbot', timeout)
        self.sendEvent(evt)
        self.niceDoggie(self.options.cycletime)

    # zenactions will call sendXmpp when an event comes in that the user wants
    # to see.
    def sendXmpp(self, action, data, clear=None):
        message, body = self.format(action, data, clear)
        recipients = self.getAddress(action)
        if not recipients:
            self.log.warning('failed to send message %s on rule %s: %s',
                             action.getUser().id, action.id,
                             'Unspecified recipient.')
            return True
        for recipient in recipients:
            self.log.debug('Sending message to %s: %s', recipient, message)
            if recipient.lower().endswith('/groupchat'):
                messageType = 'groupchat'
            else:
                messageType = 'chat'
            self.client.sendMessage(message, recipient, messageType)
            return True

    def getAddress(self, action):
        if action.targetAddr:
            return [action.targetAddr]
        else:
            results = []
            zenUser = action.getUser()
            # attempt to detect a group and resolve its users, otherwise see if it is a user
            if 'getMemberUserIds' in dir(zenUser):
                for username in zenUser.getMemberUserIds():
                    try:
                        results.append(
                            zenUser.getUserSettings(username).getProperty(
                                'JabberId').strip())
                    except None:
                        self.log.error(
                            'Unable to send xmpp alert message to %s.  This might happen if they are missing the jabberId property.  Try the bot command "setjid"'
                            % username)

            # getEmailAddresses should at least identify an entity that would have a jabberId on it, unless it was a group (above)
            elif 'getEmailAddresses' in dir(zenUser):
                try:
                    results.append(zenUser.getProperty('JabberId').lower())
                except None:
                    self.log.error(
                        'Unable to send xmpp alert message to %s.  This might happen if they are missing the jabberId property.  Try the bot command "setjid"'
                        % zenUser)
            else:
                self.log.error(
                    'Unable to send xmpp alert message to %s.  Please report this error to the author of this plugin'
                    % zenUser)

            return results
Esempio n. 3
0
    def __init__(self):
        PBDaemon.__init__(self, keeproot=True)
        ZCmdBase.__init__(self)

        wants_ssl = self.options.ssl
        if wants_ssl and not HAVE_SSL:
            self.log.error(
                'SSL was requested for Jabber connection, but pyopenssl is not installed.  Please install it and start the xmppBot again.'
            )
            sys.exit(2)

        if not self.options.jabber_pass:
            self.log.error('--jabber_pass is required')
            sys.exit(2)

        if not self.options.jabber_user:
            self.log.error('--jabber_user is required')
            sys.exit(2)

        if self.options.first_user:
            try:
                zenUser, jabberId = self.options.first_user.split(',')
            except ValueError:
                self.log.error(
                    '--first_user option must contain both zenuser and jabberid separated by a comma.  Example: chudler,[email protected]'
                )
                sys.exit(2)

            if zenUser and jabberId:
                self.setFirstUser(zenUser, jabberId)
            else:
                self.log.error(
                    '--first_user option must contain both zenuser and jabberid separated by a comma.  Example: chudler,[email protected]'
                )
                sys.exit(2)

        # taken from zenactions.py
        self.schedule = Schedule(self.options, self.dmd)
        self.actions = []
        self.loadActionRules()
        self.updateCheck = UpdateCheck()

        self.sendEvent(
            Event.Event(device=self.options.monitor,
                        eventClass=App_Start,
                        summary='Jabber Bot started',
                        severity=0,
                        component='xmppbot'))

        password = self.options.jabber_pass
        chatrooms = self.options.chatrooms
        username = self.options.jabber_user
        server = self.options.jabber_host
        port = self.options.jabber_port
        groupServer = self.options.group_server
        realHost = self.options.im_host
        resource = self.options.resource

        self.client = TwistedJabberClient(server=server,
                                          username=username,
                                          password=password,
                                          port=port,
                                          groupServer=groupServer,
                                          chatrooms=chatrooms,
                                          ssl=wants_ssl,
                                          realHost=realHost,
                                          resource=resource)

        path = os.path.realpath(sys.argv[0])
        pluginPath = os.path.dirname(path) + '/Jabber/plugins'
        self.log.info("xmppBot plugins will be loaded from %s" % pluginPath)

        plugins = [
            pluginFile.split('/')[-1].split('.py')[0]
            for pluginFile in glob.glob(os.path.join(pluginPath, '*.py'))
        ]

        self.log.debug("xmppBot loading pugins  %s" % ', '.join(plugins))
        initPluginSystem(pluginPath=pluginPath,
                         plugins=plugins,
                         jabberClient=self.client)

        # connect to the jabber server
        self.log.info('Connecting to server')
        reactor = self.client.connect()

        # begin looking for zenevents
        self.schedule.start()
        self.runCycle()

        reactor.suggestThreadPoolSize(10)
        reactor.run()
Esempio n. 4
0
    def __init__(self):
        PBDaemon.__init__(self, keeproot=True)
        ZCmdBase.__init__(self)

        wants_ssl = self.options.ssl
        if wants_ssl and not HAVE_SSL:
            self.log.error('SSL was requested for Jabber connection, but pyopenssl is not installed.  Please install it and start the xmppBot again.')
            sys.exit(2)

        if not self.options.jabber_pass:
            self.log.error('--jabber_pass is required')
            sys.exit(2)

        if not self.options.jabber_user:
            self.log.error('--jabber_user is required')
            sys.exit(2)

        if self.options.first_user:
            try:
                zenUser, jabberId = self.options.first_user.split(',')
            except ValueError:
                self.log.error('--first_user option must contain both zenuser and jabberid separated by a comma.  Example: chudler,[email protected]')
                sys.exit(2)
                
            if zenUser and jabberId:    
                self.setFirstUser(zenUser, jabberId)
            else:
                self.log.error('--first_user option must contain both zenuser and jabberid separated by a comma.  Example: chudler,[email protected]')
                sys.exit(2)

        # taken from zenactions.py
        self.schedule = Schedule(self.options, self.dmd)
        self.actions = []
        self.loadActionRules()
        self.updateCheck = UpdateCheck()

        self.sendEvent(Event.Event(device=self.options.monitor,
        eventClass=App_Start, summary='Jabber Bot started', severity=0, component='xmppbot'))
        self.adapter = JabberAdapter(True)
        password = self.options.jabber_pass
        chatroom = self.options.chatroom
        username = self.options.jabber_user
        host = self.options.jabber_host
        port = self.options.jabber_port
        groupServer = self.options.group_server
        realHost = self.options.im_host
        server = '%s:%s' % (host, port)

        client = TwistedJabberClient(dialogHandler = self.adapter, 
        server = server,
        userId = username, userPassword = password, 
        firstRoom = chatroom, debug = True, 
        groupServer = groupServer, realHost = realHost, wants_ssl = wants_ssl)

        self.adapter.client = client

        path = os.path.realpath(sys.argv[0])
        pluginPath = os.path.dirname(path) + '/Jabber/plugins'
        self.log.info("xmppBot plugins will be loaded from %s" % pluginPath)

        plugins = [pluginFile.split('/')[-1].split('.py')[0] for pluginFile in glob.glob( os.path.join(pluginPath, '*.py') )]
        initPluginSystem({'pluginPath': pluginPath, 'plugins': plugins})

        self.log.info('started')

        # connect to the jabber server
        jabber_reactor = client.connect()

        # begin looking for zenevents
        self.schedule.start()
        self.runCycle()

        # start event loop which will process jabber messages and zenevents
        jabber_reactor.run()
Esempio n. 5
0
    def __init__(self):
        PBDaemon.__init__(self, keeproot=True)
        ZCmdBase.__init__(self)

        wants_ssl = self.options.ssl
        if wants_ssl and not HAVE_SSL:
            self.log.error('SSL was requested for Jabber connection, but pyopenssl is not installed.  Please install it and start the xmppBot again.')
            sys.exit(2)

        if not self.options.jabber_pass:
            self.log.error('--jabber_pass is required')
            sys.exit(2)

        if not self.options.jabber_user:
            self.log.error('--jabber_user is required')
            sys.exit(2)

        if self.options.first_user:
            try:
                zenUser, jabberId = self.options.first_user.split(',')
            except ValueError:
                self.log.error('--first_user option must contain both zenuser and jabberid separated by a comma.  Example: chudler,[email protected]')
                sys.exit(2)

            if zenUser and jabberId:
                self.setFirstUser(zenUser, jabberId)
            else:
                self.log.error('--first_user option must contain both zenuser and jabberid separated by a comma.  Example: chudler,[email protected]')
                sys.exit(2)

        # taken from zenactions.py
        self.schedule = Schedule(self.options, self.dmd)
        self.actions = []
        self.loadActionRules()
        self.updateCheck = UpdateCheck()

        self.sendEvent(Event.Event(device=self.options.monitor,
        eventClass=App_Start, summary='Jabber Bot started', severity=0, component='xmppbot'))

        password = self.options.jabber_pass
        chatrooms = self.options.chatrooms
        username = self.options.jabber_user
        server = self.options.jabber_host
        port = self.options.jabber_port
        groupServer = self.options.group_server
        realHost = self.options.im_host
        resource = self.options.resource

        self.client = TwistedJabberClient(server=server, username=username, password=password,
                                 port=port,
                                 groupServer=groupServer,
                                 chatrooms=chatrooms, ssl=wants_ssl,
                                 realHost=realHost, resource=resource)

        path = os.path.realpath(sys.argv[0])
        pluginPath = os.path.dirname(path) + '/Jabber/plugins'
        self.log.info("xmppBot plugins will be loaded from %s" % pluginPath)

        plugins = [pluginFile.split('/')[-1].split('.py')[0] for pluginFile in glob.glob( os.path.join(pluginPath, '*.py') )]

        self.log.debug("xmppBot loading pugins  %s" % ', '.join(plugins))
        initPluginSystem(pluginPath=pluginPath, plugins=plugins, jabberClient=self.client)

        # connect to the jabber server
        self.log.info('Connecting to server')
        reactor = self.client.connect()

        # begin looking for zenevents
        self.schedule.start()
        self.runCycle()

        reactor.suggestThreadPoolSize(10)
        reactor.run()
Esempio n. 6
0
class XmppBot(ZenActions, ZCmdBase, PBDaemon):

    def buildOptions(self):
        ZCmdBase.buildOptions(self)
        self.parser.add_option( '--jabber_pass', dest='jabber_pass', type='string', help='Password used to connect to the XMPP server')
        self.parser.add_option( '--jabber_user', dest='jabber_user', type='string', help='Username used to connect to the XMPP server')
        self.parser.add_option( '--jabber_host', dest='jabber_host', type='string', default='localhost', help='(OPTIONAL) XMPP server to connect')
        self.parser.add_option( '--jabber_port', dest='jabber_port', type='int', help='(OPTIONAL) Port used to connect to the XMPP server')
        self.parser.add_option( '--first_user', dest='first_user', type='string', help='User mapping to bootstrap the bot with at least on authorized user.  Example specification myzenossname,[email protected]')
        self.parser.add_option( '--resource', dest='resource', type='string', default='xmppbot', help='(OPTIONAL) jabber resource name.')
        self.parser.add_option( '--im_host', dest='im_host', type='string', help='(OPTIONAL) option for addressing IM users when the server is not known.  If this is ommitted, jabber_host will be used.')
        self.parser.add_option( '--ssl', dest='ssl', action='store_true', help='(OPTIONAL) ssl.')
        self.parser.add_option( '--group_server', type='string', dest='group_server', help='(OPTIONAL) Conference/groupchat server.  If the name has no dots, it will use group_server.jabber_host')
        self.parser.add_option( '--chatrooms', dest='chatrooms', action='append', type='string', help='(OPTIONAL) First chatroom joined to when connecting.  May be specified multiple times to join multiple rooms.')
        self.parser.add_option('--cycletime', dest='cycletime', default=60, type='int', help='(OPTIONAL) check events every cycletime seconds')
        self.parser.add_option( '--zopeurl', type='string', dest='zopeurl', default='http://%s:%d' % (socket.getfqdn(), 8080), help='(OPTIONAL) http path to the root of the zope server')
        self.parser.add_option('--monitor', type='string', dest='monitor', default=DEFAULT_MONITOR, help='(OPTIONAL) Name of monitor instance to use for heartbeat events. Default is %s.' % DEFAULT_MONITOR)

    def __init__(self):
        PBDaemon.__init__(self, keeproot=True)
        ZCmdBase.__init__(self)

        wants_ssl = self.options.ssl
        if wants_ssl and not HAVE_SSL:
            self.log.error('SSL was requested for Jabber connection, but pyopenssl is not installed.  Please install it and start the xmppBot again.')
            sys.exit(2)

        if not self.options.jabber_pass:
            self.log.error('--jabber_pass is required')
            sys.exit(2)

        if not self.options.jabber_user:
            self.log.error('--jabber_user is required')
            sys.exit(2)

        if self.options.first_user:
            try:
                zenUser, jabberId = self.options.first_user.split(',')
            except ValueError:
                self.log.error('--first_user option must contain both zenuser and jabberid separated by a comma.  Example: chudler,[email protected]')
                sys.exit(2)

            if zenUser and jabberId:
                self.setFirstUser(zenUser, jabberId)
            else:
                self.log.error('--first_user option must contain both zenuser and jabberid separated by a comma.  Example: chudler,[email protected]')
                sys.exit(2)

        # taken from zenactions.py
        self.schedule = Schedule(self.options, self.dmd)
        self.actions = []
        self.loadActionRules()
        self.updateCheck = UpdateCheck()

        self.sendEvent(Event.Event(device=self.options.monitor,
        eventClass=App_Start, summary='Jabber Bot started', severity=0, component='xmppbot'))

        password = self.options.jabber_pass
        chatrooms = self.options.chatrooms
        username = self.options.jabber_user
        server = self.options.jabber_host
        port = self.options.jabber_port
        groupServer = self.options.group_server
        realHost = self.options.im_host
        resource = self.options.resource

        self.client = TwistedJabberClient(server=server, username=username, password=password,
                                 port=port,
                                 groupServer=groupServer,
                                 chatrooms=chatrooms, ssl=wants_ssl,
                                 realHost=realHost, resource=resource)

        path = os.path.realpath(sys.argv[0])
        pluginPath = os.path.dirname(path) + '/Jabber/plugins'
        self.log.info("xmppBot plugins will be loaded from %s" % pluginPath)

        plugins = [pluginFile.split('/')[-1].split('.py')[0] for pluginFile in glob.glob( os.path.join(pluginPath, '*.py') )]

        self.log.debug("xmppBot loading pugins  %s" % ', '.join(plugins))
        initPluginSystem(pluginPath=pluginPath, plugins=plugins, jabberClient=self.client)

        # connect to the jabber server
        self.log.info('Connecting to server')
        reactor = self.client.connect()

        # begin looking for zenevents
        self.schedule.start()
        self.runCycle()

        reactor.suggestThreadPoolSize(10)
        reactor.run()

    def setFirstUser(self, zenUser, jabberId):
        zenUser = zenUser.lower()
        haveUser = False
        for user in  self.dmd.ZenUsers.getAllUserSettings():
            if user.id.lower() == zenUser:
                haveUser = True
                user._updateProperty('JabberId', jabberId)
                transaction.commit()
                break
        return haveUser

    # ripped from zenactions.py
    def mainbody(self):
        """main loop to run actions.
        """
        from twisted.internet.process import reapAllProcesses
        reapAllProcesses()
        zem = self.dmd.ZenEventManager
        self.loadActionRules()
        self.processRules(zem)

    # ripped from zenactions.py
    def runCycle(self):
        try:
            start = time.time()
            self.syncdb()
            self.mainbody()
            self.log.info('processed %s rules in %.2f secs', len(self.actions), time.time()-start)
        except:
            self.log.exception('unexpected exception')
        reactor.callLater(60, self.runCycle)

    # ripped from zenactions.py
    def loadActionRules(self):
        self.actions = []
        for ar in self.dmd.ZenUsers.getAllActionRules():
            if not ar.enabled: continue
            if not ar.action.title() == 'Xmpp': continue
            userid = ar.getUser().id
            self.actions.append(ar)
            self.log.debug('action:%s for:%s loaded', ar.getId(), userid)

    # ripped from zenactions.py
    def sendHeartbeat(self):
        """Send a heartbeat event for this monitor.
        """
        timeout = self.options.cycletime*3
        evt = Event.EventHeartbeat(self.options.monitor, 'xmppbot', timeout)
        self.sendEvent(evt)
        self.niceDoggie(self.options.cycletime)

    # zenactions will call sendXmpp when an event comes in that the user wants
    # to see.
    def sendXmpp(self, action, data, clear = None):
        message, body = self.format(action, data, clear)
        recipients = self.getAddress(action)
        if not recipients:
            self.log.warning('failed to send message %s on rule %s: %s', action.getUser().id, action.id, 'Unspecified recipient.')
            return True
        for recipient in recipients:
            self.log.debug('Sending message to %s: %s', recipient, message)
            if recipient.lower().endswith('/groupchat'):
                messageType = 'groupchat'
            else:
                messageType = 'chat'
            self.client.sendMessage(message, recipient, messageType)
            return True

    def getAddress(self, action):
        if action.targetAddr:
            return [action.targetAddr]
        else:
            results = []
            zenUser = action.getUser()
            # attempt to detect a group and resolve its users, otherwise see if it is a user
            if 'getMemberUserIds' in dir(zenUser):
                for username in zenUser.getMemberUserIds():
                    try:
                        results.append(zenUser.getUserSettings(username).getProperty('JabberId').strip())
                    except None:
                        self.log.error('Unable to send xmpp alert message to %s.  This might happen if they are missing the jabberId property.  Try the bot command "setjid"' % username)

            # getEmailAddresses should at least identify an entity that would have a jabberId on it, unless it was a group (above)
            elif 'getEmailAddresses' in dir(zenUser):
                try:
                    results.append(zenUser.getProperty('JabberId').lower())
                except None:
                    self.log.error('Unable to send xmpp alert message to %s.  This might happen if they are missing the jabberId property.  Try the bot command "setjid"' % zenUser)
            else:
                self.log.error('Unable to send xmpp alert message to %s.  Please report this error to the author of this plugin' % zenUser)

            return results