gozerbot.fleet

fleet is a list of bots.

class gozerbot.fleet.Fleet

Bases: object

a fleet contains multiple bots (list of bots). used the datadir set in gozerbot/datadir.py

addbot(*args, **kwargs)

the locked function.

avail()

show available fleet bots.

broadcast(txt)

broadcast txt to all bots.

byname(name)

return bot by name.

cmnd(event, name, cmnd)

do command on a bot.

cmndall(event, cmnd)

do a command on all bots.

connect(name)

connect bot to the server.

delete(*args, **kwargs)

the locked function.

exit(name=None, jabber=False)

call exit on all bots. if jabber=True only jabberbots will exit.

getfirstbot()

return the main bot of the fleet.

getfirstjabber()

return the first jabber bot of the fleet.

initbot(bot)

initialise a bot.

list()

return list of bot names.

makebot(name, cfg=None)

create a bot .. use configuration if provided.

remove(bot)

delete bot by object.

replace(name, bot)

replace bot with a new bot.

resume(sessionfile)

resume bot from session file.

resumebot(botname, data={}, printto=None)

resume individual bot.

save()

save fleet data and call save on all the bots.

size()

return number of bots in fleet.

start(botlist=[], enable=False)

start the bots.

stopall()

call stop() on all fleet bots.

exception gozerbot.fleet.FleetBotAlreadyExists

Bases: exceptions.Exception

CODE

# gozerbot/fleet.py
#
#

""" fleet is a list of bots. """

__status__ = "seen"

gozerbot imports

from gozerbot.datadir import datadir
from utils.exception import handle_exception
from utils.generic import waitforqueue
from utils.log import rlog
from utils.locking import lockdec
from threads.thr import start_new_thread, threaded
from config import Config, fleetbotconfigtxt, config
from users import users
from plugins import plugins
from simplejson import load

basic imports

import Queue
import os
import types
import threading
import time
import pickle
import glob
import logging
import shutil
import thread

locks

fleetlock = thread.allocate_lock()
fleetlocked = lockdec(fleetlock)

FleetBotAlreadyExists class

class FleetBotAlreadyExists(Exception):
    pass

Fleet class

class Fleet(object):

    """
        a fleet contains multiple bots (list of bots). used the datadir
        set in gozerbot/datadir.py

    """

    def __init__(self):
        self.datadir = datadir + os.sep + 'fleet'
        if not os.path.exists(self.datadir): os.mkdir(self.datadir)
        self.startok = threading.Event()
        self.bots = []

    def getfirstbot(self):
        """ return the main bot of the fleet. """
        self.startok.wait()
        return self.bots[0]

    def getfirstjabber(self):
        """ return the first jabber bot of the fleet. """
        self.startok.wait()
        for bot in self.bots:
            if bot.type == 'xmpp': return bot

    def size(self):
        """ return number of bots in fleet. """
        return len(self.bots)

    def resume(self, sessionfile):
        """ resume bot from session file. """
        session = load(open(sessionfile))
        for name in session['bots'].keys():
            reto = None
            if name == session['name']: reto = session['channel']
            start_new_thread(self.resumebot, (name, session['bots'][name], reto))
        time.sleep(5)
        self.startok.set()

    def makebot(self, name, cfg=None):
        """ create a bot .. use configuration if provided. """
        if self.byname(name): raise FleetBotAlreadyExists("there is already a %s bot in the fleet" % name)
        rlog(10, 'fleet', 'making bot')
        bot = None
        if not cfg:
            cfg = Config(self.datadir + os.sep + name, 'config', inittxt=fleetbotconfigtxt)
            cfg.save()
        if cfg['type'] == 'irc':
            from gozerbot.irc.bot import Bot
            bot = Bot(name, cfg)
        elif cfg['type'] == 'xmpp' or cfg['type'] == 'jabber':
            from gozerbot.xmpp.bot import Bot
            bot = Bot(name, cfg)
        elif cfg['type'] == 'gozernet':
            from gozerbot.gozernet.bot import GozerNetBot
            bot = GozerNetBot(name, cfg)
        else: rlog(10, 'fleet', '%s .. unproper type: %s' % (cfg['name'], cfg['type']))
        if bot:
            cfg['name'] = bot.name = name
            self.initbot(bot)
            return bot
        raise Exception("can't make %s bot" % name)

    def resumebot(self, botname, data={}, printto=None):
        """ resume individual bot. """
        oldbot = self.byname(botname)
        if oldbot: oldbot.exit()
        cfg = Config(datadir + os.sep + 'fleet' + os.sep + botname, 'config')
        bot = self.makebot(botname, cfg)
        rlog(100, 'fleet', 'bot made: %s' % str(bot))
        if bot:
            if oldbot: self.replace(oldbot, bot)
            else: self.bots.append(bot)
            if not bot.jabber: bot._resume(data, printto)
            else: start_new_thread(bot.connectwithjoin, ())

    def start(self, botlist=[], enable=False):
        """ start the bots. """
        dirs = []
        got = []
        for bot in botlist: dirs.append(self.datadir + os.sep + bot)
        if not dirs: dirs = glob.glob(self.datadir + os.sep + "*")
        for fleetdir in dirs:
            if fleetdir.endswith('fleet'): continue
            rlog(10, 'fleet', 'found bot: ' + fleetdir)
            cfg = Config(fleetdir, 'config')
            if not cfg: rlog(10, 'fleet', "can't read %s config file" % fleetdir) ; continue
            name = fleetdir.split(os.sep)[-1]
            if not name: rlog(10, 'fleet', "can't read botname from %s config file" % fleetdir) ; continue
            if not enable and not cfg['enable']: rlog(10, 'fleet', '%s bot is disabled' % name) ; continue
            else: rlog(10, 'fleet', '%s bot is enabled' % name)
            if not name in fleetdir: rlog(10, 'fleet', 'bot name in config file doesnt match dir name') ; continue
            try: bot = self.makebot(name, cfg)
            except FleetBotAlreadyExists: rlog(10, 'fleet', 'there is already a fleetbot with the name %s' % name) ; continue
            if bot:
                self.addbot(bot)
                start_new_thread(bot.connectwithjoin, ())
                got.append(bot)
        self.startok.set()
        return got

    def save(self):
        """ save fleet data and call save on all the bots. """
        for i in self.bots:
            try: i.save()
            except Exception, ex: handle_exception()

    def avail(self):
        """ show available fleet bots. """
        return os.listdir(self.datadir)

    def list(self):
        """ return list of bot names. """
        result = []
        for i in self.bots: result.append(i.name)
        return result

    def stopall(self):
        """ call stop() on all fleet bots. """
        for i in self.bots:
            try: i.stop()
            except: pass

    def byname(self, name):
        """ return bot by name. """
        for i in self.bots:
            if name == i.name: return i

    def replace(self, name, bot):
        """ replace bot with a new bot. """
        for i in range(len(self.bots)):
            if name == self.bots[i].name: self.bots[i] = bot ; return

    def initbot(self, bot):
        """ initialise a bot. """
        if bot not in self.bots:
            if not os.path.exists(self.datadir + os.sep + bot.name): os.mkdir(self.datadir + os.sep + bot.name)
            if type(bot.cfg['owner']) == types.StringType or type(bot.cfg['owner']) == types.UnicodeType:
                bot.cfg['owner'] = [bot.cfg['owner'], ]
                bot.cfg.save()
            users.make_owner(config['owner'] + bot.cfg['owner'])
            rlog(10, 'fleet', 'added bot: ' + bot.name)

    @fleetlocked
    def addbot(self, bot):
        """
            add a bot to the fleet .. remove all existing bots with the
            same name.

        """
        if not bot: return False
        for i in range(len(self.bots)-1, -1, -1):
            if self.bots[i].name == bot.name: rlog(10, 'fleet', 'removing %s from fleet' % bot.name) ; del self.bots[i]
        rlog(10, 'fleet', 'adding %s' % bot.name)
        self.bots.append(bot)
        return True

    def connect(self, name):
        """ connect bot to the server. """
        for i in self.bots:
            if i.name == name:
                got = i.connect()
                if got: start_new_thread(i.joinchannels, ()) ; return True
                else: return False

    @fleetlocked
    def delete(self, name):
        """ delete bot with name from fleet. """
        for i in self.bots:
            if i.name == name:
                i.exit()
                self.remove(i)
                i.cfg['enable'] = 0
                i.cfg.save()
                rlog(10, 'fleet', '%s disabled' % i.name)
                return True
        return False

    def remove(self, bot):
        """ delete bot by object. """
        try: self.bots.remove(bot) ; return True
        except ValueError: return False

    def exit(self, name=None, jabber=False):
        """ call exit on all bots. if jabber=True only jabberbots will exit. """
        if not name:
            threads = []
            for i in self.bots:
                if jabber and not i.jabber: pass
                else: threads.append(start_new_thread(i.exit, ()))
            for thr in threads: thr.join()
            return
        for i in self.bots:
            if i.name == name:
                try: i.exit()
                except: handle_exception()
                self.remove(i)
                return True
        return False

    def cmnd(self, event, name, cmnd):
        """ do command on a bot. """
        bot = self.byname(name)
        if not bot: return 0
        from gozerbot.eventbase import EventBase
        j = plugins.clonedevent(bot, event)
        j.onlyqueues = True
        j.txt = cmnd
        q = Queue.Queue()
        j.queues = [q]
        j.speed = 3
        start_new_thread(plugins.trydispatch, (bot, j))
        result = waitforqueue(q)
        if not result: return
        res = ["<%s>" % bot.name, ]
        res += result
        event.reply(res)

    def cmndall(self, event, cmnd):
        """ do a command on all bots. """
        threads = []
        for i in self.bots:
            thread = start_new_thread(self.cmnd, (event, i.name, cmnd))
            threads.append(thread)
        for i in threads: i.join()

    def broadcast(self, txt):
        """ broadcast txt to all bots. """
        for i in self.bots: i.broadcast(txt)

defines

fleet = Fleet()

Table Of Contents

Previous topic

gozerbot.exit

Next topic

gozerbot.generic

This Page