コード例 #1
0
ファイル: bot.py プロジェクト: DesertBot/DesertBot-old
 def __init__(self, configFile):
     self.config = Config(configFile)
     self.connectionFactory = DesertBotFactory(self)
     self.log = None
     self.moduleHandler = ModuleHandler(self)
     self.servers = {}
     self.storage = None
     self.storageSync = None
     self.startTime = now()
コード例 #2
0
ファイル: bothandler.py プロジェクト: Heufneutje/DesertBot
 def __init__(self, cmdArgs):
     self.configs = {}
     for server in cmdArgs.servers:
         config = Config("{}.yaml".format(server))
         if config.loadConfig():
             self.configs[server] = config
     self.botfactories = {}
     for server, configObject in self.configs.iteritems():
         self.startBotFactory(configObject)
コード例 #3
0
ファイル: bothandler.py プロジェクト: bjornsnoen/DesertBot
 def __init__(self, cmdArgs):
     self.configs = {}
     for configFileName in cmdArgs.configs:
         if not configFileName.endswith(".yaml"):
             config = Config("{}.yaml".format(configFileName))
         else:
             config = Config(configFileName)
         if config.loadConfig():
             self.configs[config.configFileName] = config
     self.botfactories = {}
     for configFileName, configObject in self.configs.iteritems():
         self.startBotFactory(configObject)
     reactor.run()
コード例 #4
0
ファイル: util.py プロジェクト: Tantusar/DesertBot
    def __init__(self, section):
        parser = argparse.ArgumentParser(description='PyHeufyBot shelve parsing tool.')
        parser.add_argument('-s', '--storage', help='The storage file to use', type=str, default='../../data/heufybot.db')
        parser.add_argument('-n', '--network', help='The network name to import from', type=str, required=True)
        parser.add_argument('-c', '--config', help='the config file to read from', type=str, required=True)
        options = parser.parse_args()

        self.config = Config(options.config)
        self.config.loadConfig()

        with shelve.open(options.storage) as storage:
            self.data = storage[section][options.network]
            storage.close()

        self.rootDir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir))
        self.dataPath = os.path.join(self.rootDir, 'data', self.config['server'])
        if not os.path.exists(self.dataPath):
            os.makedirs(self.dataPath)

        self.storage = DataStore(os.path.join(self.dataPath, 'desertbot.json'))
コード例 #5
0
ファイル: factory.py プロジェクト: DesertBot/DesertBot
    def __init__(self, config: Config):
        self.logger = logging.getLogger('desertbot.factory')
        self.exitStatus = 0

        self.bot = DesertBot(self, config)
        self.protocol = self.bot

        self.server = config['server']
        self.port = config.getWithDefault('port', 6667)
        if config.getWithDefault('tls', False):
            self.logger.info('Attempting secure connection to {}:{}...'
                             .format(self.server, self.port))
            if ssl is not None:
                reactor.connectSSL(self.server, self.port, self, ssl.ClientContextFactory())
            else:
                self.logger.error('Connection to {}:{} failed;'
                                  ' PyOpenSSL is required for secure connections.'
                                  .format(self.server, self.port))
        else:
            self.logger.info('Attempting connection to {}:{}'.format(self.server, self.port))
            reactor.connectTCP(self.server, self.port, self)
コード例 #6
0
ファイル: util.py プロジェクト: DesertBot/DesertBot
class PyHeufyBotUtil(object):
    def __init__(self, section):
        parser = argparse.ArgumentParser(description='PyHeufyBot shelve parsing tool.')
        parser.add_argument('-s', '--storage', help='The storage file to use', type=str, default='../../data/heufybot.db')
        parser.add_argument('-n', '--network', help='The network name to import from', type=str, required=True)
        parser.add_argument('-c', '--config', help='the config file to read from', type=str, required=True)
        options = parser.parse_args()

        self.config = Config(options.config)
        self.config.loadConfig()

        with shelve.open(options.storage) as storage:
            self.data = storage[section][options.network]
            storage.close()

        self.rootDir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir))
        self.dataPath = os.path.join(self.rootDir, 'data', self.config['server'])
        if not os.path.exists(self.dataPath):
            os.makedirs(self.dataPath)

        self.storage = DataStore(os.path.join(self.dataPath, 'desertbot.json'))
コード例 #7
0
    def __init__(self, config: Config):
        self.logger = logging.getLogger('desertbot.factory')
        self.exitStatus = 0
        self.connectionAttempts = 0

        self.bot = DesertBot(self, config)
        self.protocol = self.bot

        self.server = config['server']
        self.port = config.getWithDefault('port', 6667)
        if config.getWithDefault('tls', False):
            self.logger.info('Attempting secure connection to {}:{}...'
                             .format(self.server, self.port))
            if ssl is not None:
                reactor.connectSSL(self.server, self.port, self, ssl.ClientContextFactory())
            else:
                self.logger.error('Connection to {}:{} failed;'
                                  ' PyOpenSSL is required for secure connections.'
                                  .format(self.server, self.port))
        else:
            self.logger.info('Attempting connection to {}:{}'.format(self.server, self.port))
            reactor.connectTCP(self.server, self.port, self)
コード例 #8
0
 def onTrigger(self, message):
     """
     @type message: IRCMessage
     """
     if message.command == u"connect":
         if len(message.parameterList) == 0:
             return IRCResponse(ResponseType.PRIVMSG, u"Connect where?", message.user,
                                message.replyTo)
         for configFileName in message.parameterList:
             try:
                 if not configFileName.endswith(".yaml"):
                     config = Config("{}.yaml".format(configFileName))
                 else:
                     config = Config(configFileName)
                 if config.loadConfig():
                     message.bot.bothandler.configs[config.configFileName] = config
                     message.bot.bothandler.startBotFactory(config)
                     return IRCResponse(ResponseType.PRIVMSG,
                                        u"Using \"{}\" for new connection...".format(
                                            config.configFileName),
                                        message.user, message.replyTo)
                 else:
                     return IRCResponse(ResponseType.PRIVMSG,
                                        u"\"{}\" was not correct. Aborting.".format(
                                            config.configFileName),
                                        message.user, message.replyTo)
             except Exception as e:
                 log.err("Connecting with \"{}\" failed. ({})".format(configFileName, e))
                 return IRCResponse(ResponseType.PRIVMSG,
                                    u"Connecting with \"{}\" failed. ({})".format(
                                        configFileName, e),
                                    message.user, message.replyTo)
     if message.command == u"quit":
         if datetime.datetime.utcnow() > message.bot.startTime + datetime.timedelta(seconds=10):
             message.bot.factory.shouldReconnect = False
             message.bot.bothandler.stopBotFactory(message.bot.config.configFileName, None)
     if message.command == u"quitfrom":
         if len(message.parameterList) == 0:
             return IRCResponse(ResponseType.PRIVMSG, u"Quit from where?", message.user,
                                message.replyTo)
         for configFileName in message.parameterList:
             if not configFileName.endswith(".yaml"):
                 quitFromConfig = "{}.yaml".format(configFileName)
             else:
                 quitFromConfig = configFileName
             if quitFromConfig == message.bot.config.configFileName:
                 return IRCResponse(ResponseType.PRIVMSG, u"Can't quit from here with this!",
                                    message.user, message.replyTo)
             else:
                 quitMessage = u"Killed from \"{}\"".format(message.bot.config["server"])
                 result = message.bot.bothandler.stopBotFactory(quitFromConfig, quitMessage)
                 if result:
                     return IRCResponse(ResponseType.PRIVMSG,
                                        u"Successfully quit from \"{}\".".format(configFileName),
                                        message.user, message.replyTo)
                 else:
                     return IRCResponse(ResponseType.PRIVMSG,
                                        u"I am not on \"{}\"!".format(configFileName),
                                        message.user, message.replyTo)
     if message.command == u"restart":
         if datetime.datetime.utcnow() > message.bot.startTime + datetime.timedelta(seconds=10):
             message.bot.bothandler.restart()
     if message.command == u"shutdown":
         if datetime.datetime.utcnow() > message.bot.startTime + datetime.timedelta(seconds=10):
             message.bot.bothandler.shutdown()
コード例 #9
0
    # Modules can then just add more handlers to the root logger
    # to capture all logs to files in various ways
    rootLogger = logging.getLogger('desertbot')
    numericLevel = getattr(logging, cmdArgs.loglevel.upper(), None)
    if isinstance(numericLevel, int):
        rootLogger.setLevel(numericLevel)
    else:
        raise ValueError('Invalid log level {}'.format(cmdArgs.loglevel))

    logFormatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s', '%H:%M:%S')

    streamHandler = logging.StreamHandler(stream=sys.stdout)
    streamHandler.setFormatter(logFormatter)

    rootLogger.addHandler(streamHandler)

    observer = log.PythonLoggingObserver(loggerName='desertbot.twisted')
    observer.start()

    config = Config(cmdArgs.config)
    try:
        config.loadConfig()
    except ConfigError:
        rootLogger.exception("Failed to load configuration file {}".format(
            cmdArgs.config))
    else:
        factory = DesertBotFactory(config)
        reactor.run()
        sys.exit(factory.exitStatus)
コード例 #10
0
ファイル: bot.py プロジェクト: DesertBot/DesertBot-old
class DesertBot(object):
    def __init__(self, configFile):
        self.config = Config(configFile)
        self.connectionFactory = DesertBotFactory(self)
        self.log = None
        self.moduleHandler = ModuleHandler(self)
        self.servers = {}
        self.storage = None
        self.storageSync = None
        self.startTime = now()

    def startup(self):
        if ssl is None:
            self.log.warn(
                "The PyOpenSSL package was not found. You will not be able to connect to servers using SSL."
            )
        self.log.info("Loading configuration file...")
        self.config.loadConfig()
        self.log.info("Loading storage...")
        self.storage = shelve.open(
            self.config.itemWithDefault("storage_path", "desertbot.db"))
        self.storageSync = LoopingCall(self.storage.sync)
        self.storageSync.start(self.config.itemWithDefault(
            "storage_sync_interval", 5),
                               now=False)
        self.log.info("Loading modules...")
        self.moduleHandler.loadAllModules()
        self.log.info("Initiating connections...")
        self._initiateConnections()
        self.log.info("Starting reactor...")
        reactor.run()

    def _initiateConnections(self):
        for server in self.config["servers"].iterkeys():
            self.connectServer(server)

    def connectServer(self, host):
        if host in self.servers:
            error = "A connection to {} was requested, but already exists.".format(
                host)
            self.log.warn(error)
            return error
        if host not in self.config["servers"]:
            error = "A connection to {} was requested, but there is no config data for this server.".format(
                host)
            self.log.warn(error)
            return error
        port = int(self.config.serverItemWithDefault(host, "port", 6667))
        if self.config.serverItemWithDefault(host, "ssl", False):
            self.log.info("Attempting secure connection to {host}/{port}...",
                          host=host,
                          port=port)
            if ssl is not None:
                reactor.connectSSL(host, port, self.connectionFactory,
                                   ssl.ClientContextFactory())
            else:
                self.log.error(
                    "Can't connect to {host}/{port}; PyOpenSSL is required to allow secure connections.",
                    host=host,
                    port=port)
        else:
            self.log.info("Attempting connection to {host}/{port}...",
                          host=host,
                          port=port)
            reactor.connectTCP(host, port, self.connectionFactory)

    def disconnectServer(self, host, quitMessage="Quitting..."):
        if host not in self.servers:
            error = "A disconnect from {} was requested, but this connection doesn't exist.".format(
                host)
            self.log.warn(error)
            return error
        self.servers[host].disconnect(quitMessage, True)

    def reconnectServer(self, host, quitMessage="Reconnecting..."):
        if host not in self.servers:
            error = "A reconnect to {} was requested, but this connection doesn't exist.".format(
                host)
            self.log.warn(error)
            return error
        self.servers[host].disconnect(quitMessage)

    def shutdown(self, quitMessage="Shutting down..."):
        serversCopy = self.servers.copy()
        for server in serversCopy.itervalues():
            server.disconnect(quitMessage, True)

    def restart(self, quitMessage="Restarting..."):
        reactor.addSystemEventTrigger(
            "after", "shutdown",
            lambda: os.execl(sys.executable, sys.executable, *sys.argv))
        self.shutdown(quitMessage)

    def countConnections(self):
        if len(self.servers) == 0:
            self.log.info("No more connections alive, shutting down...")
            # If we have any connections that have been started but never finished, stop trying
            self.connectionFactory.stopTrying()
            self.log.info("Closing storage...")
            if self.storageSync.running:
                self.storageSync.stop()
            self.storage.close()
            self.log.info("Unloading modules...")
            self.moduleHandler.unloadAllModules()
            self.log.info("Stopping reactor...")
            reactor.stop()