[Otfbot-svn] r591 - in trunk: . lib plugins/ircClient services

cato at mail.berlios.de cato
So Aug 30 15:08:17 CEST 2009


Author: cato
Date: 2009-08-30 15:08:15 +0200 (Sun, 30 Aug 2009)
New Revision: 591

Removed:
   trunk/lib/log.py
Modified:
   trunk/lib/pluginSupport.py
   trunk/otfbot.tac
   trunk/plugins/ircClient/controlIRC.py
   trunk/plugins/ircClient/karma.py
   trunk/services/control.py
   trunk/services/ircClient.py
Log:
further work on control

* finally removed IPC
* added control to PluginSupport (needs more work)
* switched logging from twisted to python again

Deleted: trunk/lib/log.py
===================================================================
--- trunk/lib/log.py	2009-08-29 23:17:36 UTC (rev 590)
+++ trunk/lib/log.py	2009-08-30 13:08:15 UTC (rev 591)
@@ -1,95 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-# Copyright (c) 2001-2007 Twisted Matrix Laboratories.
-# from http://twistedmatrix.com/trac/browser/tags/releases/twisted-8.1.0/twisted/python/log.py
-import logging
-from twisted.python import log, reflect
-class PythonLoggingObserver(object):
-    """
-    Output twisted messages to Python standard library L{logging} module.
-
-    WARNING: specific logging configurations (example: network) can lead to
-    a blocking system. Nothing is done here to prevent that, so be sure to not
-    use this: code within Twisted, such as twisted.web, assumes that logging
-    does not block.
-    """
-
-    def __init__(self, loggerName="twisted"):
-        """
-        @param loggerName: identifier used for getting logger.
-        @type loggerName: C{str}
-        """
-        self.logger = logging.getLogger(loggerName)
-        self.logger.info("added twisted-logger")
-
-    def emit(self, eventDict):
-        """
-        Receive a twisted log entry, format it and bridge it to python.
-
-        By default the logging level used is info; log.err produces error
-        level, and you can customize the level by using the C{logLevel} key::
-
-        >>> log.msg('debugging', logLevel=logging.DEBUG)
-
-        """
-        if 'logLevel' in eventDict:
-            level = eventDict['logLevel']
-        elif eventDict['isError']:
-            level = logging.ERROR
-        else:
-            level = logging.INFO
-        text = self.textFromEventDict(eventDict)
-        if text is None:
-            return
-        self.logger.log(level, text)
-
-    def start(self):
-        """
-        Start observing log events.
-        """
-        log.addObserver(self.emit)
-
-    def stop(self):
-        """
-        Stop observing log events.
-        """
-        log.removeObserver(self.emit)
-    def textFromEventDict(self,eventDict):
-        """
-        Extract text from an event dict passed to a log observer. If it cannot
-        handle the dict, it returns None.
-    
-        The possible keys of eventDict are:
-         - C{message}: by default, it holds the final text. It's required, but can
-           be empty if either C{isError} or C{format} is provided (the first
-           having the priority).
-         - C{isError}: boolean indicating the nature of the event.
-         - C{failure}: L{failure.Failure} instance, required if the event is an
-           error.
-         - C{why}: if defined, used as header of the traceback in case of errors.
-         - C{format}: string format used in place of C{message} to customize
-           the event. It uses all keys present in C{eventDict} to format
-           the text.
-        Other keys will be used when applying the C{format}, or ignored.
-        """
-        edm = eventDict['message']
-        if not edm:
-            if eventDict['isError'] and 'failure' in eventDict:
-                    text = ((eventDict.get('why') or 'Unhandled Error')
-                        + '\n' + eventDict['failure'].getTraceback())
-            elif 'format' in eventDict:
-                    text = _safeFormat(eventDict['format'], eventDict)
-            else:
-                    # we don't know how to log this
-                    return
-        else:
-            text = ' '.join(map(reflect.safe_str, edm))
-        return text
\ No newline at end of file

Modified: trunk/lib/pluginSupport.py
===================================================================
--- trunk/lib/pluginSupport.py	2009-08-29 23:17:36 UTC (rev 590)
+++ trunk/lib/pluginSupport.py	2009-08-30 13:08:15 UTC (rev 591)
@@ -1,7 +1,5 @@
 import sys, traceback
 
-#TODO: we do not have ipc anymore, and self.network only applys to ircClientPlugins
-
 class pluginSupport:
     pluginSupportName="[UNSET]"
     pluginSupportPath="[UNSET]"
@@ -13,6 +11,16 @@
         self.plugins={}
         #XXX: the dependency should be more explicit?
         self.config = root.getNamedServices()['config']
+        
+    def register_pluginsupport_commands(self):
+        # Make sure to have this method!
+        if not "register_ctl_command" in dir(self):
+            self.register_ctl_command = lambda x, y, z: None
+        self.register_ctl_command(self.startPlugin)
+        self.register_ctl_command(self.stopPlugin)
+        self.register_ctl_command(self.restartPlugin)
+        self.register_ctl_command(lambda: self.plugins.keys(), name="listPlugins")
+
     def depends(self, dependency):
         raise self.DependencyMissing(dependency)
     def depends_on_module(self, dependency):
@@ -89,35 +97,26 @@
     def reloadPluginClass(self, pluginClass):
             self.logger.info("reloading class "+pluginClass.__name__)
             reload(pluginClass)
-    def restartPlugin(self, pluginName, network):
-        if network in self.ipc.getall() and pluginName in self.ipc[network].plugins.keys():
-            self.ipc[network].stopPlugin(pluginName)
-            c=None
-            #this is not optimal, because each plugin needs to iterate over all classes
-            for c in self.classes:
-                if c.__name__==pluginName:
-                    break
-            self.ipc[network].startPlugin(c)
 
-    def reloadPlugins(self, all=True):
+    def restartPlugin(self, pluginName):
+        if pluginName in self.plugins.keys():
+            self.stopPlugin(pluginName)
+            self.startPlugin(pluginName)
+
+    def reloadPlugins(self):
         """
             call this to reload all plugins
         """
         for chatPlugin in self.classes:
             self.reloadPluginClass(chatPlugin)
-        if all: #global
-            for network in self.ipc.getall().keys():
-                for plugin in self.ipc[network].plugins.keys():
-                    self.restartPlugin(plugin, network)
-        else:
-            for chatPlugin in self.plugins.values():
-                self.restartPlugin(chatPlugin.name, self.network)
+        for chatPlugin in self.plugins.values():
+            self.restartPlugin(chatPlugin.name)
     
     def stopPlugin(self, pluginName):
         if not pluginName in self.plugins.keys():
             return
         chatPlugin=self.plugins[pluginName]
-        self.logger.info("stopping %s for network %s"%(pluginName, self.network))
+        self.logger.info("stopping %s" % (pluginName,))
         try:
             chatPlugin.stop()
         except Exception, e:

Modified: trunk/otfbot.tac
===================================================================
--- trunk/otfbot.tac	2009-08-29 23:17:36 UTC (rev 590)
+++ trunk/otfbot.tac	2009-08-30 13:08:15 UTC (rev 591)
@@ -28,52 +28,52 @@
 
 #logging
 import logging, logging.handlers
-import lib.log as otfbotlog
 from twisted.python import log
 import logging, sys
 
 
-class pythonToTwistedLoggingHandler(logging.Handler):
-    def emit(self, record):
-        log.msg(record.getMessage())
+#class pythonToTwistedLoggingHandler(logging.Handler):
+#    def emit(self, record):
+#        log.msg(record.getMessage())
 
-# Setup Logging
-#path_log="otfbot.log"
-#path_errorlog="otfbot.err"
-# logging to logfile
-#debuglevel=0
-#filelogger = logging.handlers.RotatingFileHandler(path_log,'a',1048576,5)
-#memorylogger = logging.handlers.MemoryHandler(1000)
-#errorlogger = logging.handlers.RotatingFileHandler(path_errorlog,'a',1048576,5)
-#errorlogger.setLevel(logging.ERROR)
+logfile="otfbot.log"
+errfile="otfbot.err"
+stdout=True
+
+formatter = logging.Formatter('%(asctime)s %(name)-18s %(module)-18s %(levelname)-8s %(message)s')
+
+filelogger = logging.handlers.RotatingFileHandler(logfile,'a',1048576,5)
+filelogger.setFormatter(formatter)        
+errorlogger = logging.handlers.RotatingFileHandler(errfile,'a',1048576,5)
+errorlogger.setFormatter(formatter)
+memorylogger = logging.handlers.MemoryHandler(1000)
+memorylogger.setFormatter(formatter)
+if stdout:
+    console = logging.StreamHandler()
+    console.setFormatter(formatter)
+
 logging.getLogger('').setLevel(logging.DEBUG)
-#formatter = logging.Formatter('%(asctime)s %(name)-18s %(module)-18s %(levelname)-8s %(message)s')
-#filelogger.setFormatter(formatter)
-#errorlogger.setFormatter(formatter)
-#memorylogger.setFormatter(formatter)
-#logging.getLogger('').addHandler(filelogger)
-#logging.getLogger('').addHandler(errorlogger)
-#logging.getLogger('').addHandler(memorylogger)
-logging.getLogger('').addHandler(pythonToTwistedLoggingHandler())
+errorlogger.setLevel(logging.ERROR)
 
-#if debuglevel > 0:
-    # logging to stdout
-#console = logging.StreamHandler()
-#logging.getLogger('').setLevel(debuglevel)
-#console.setFormatter(formatter)
-#logging.getLogger('').addHandler(console)
-#corelogger = logging.getLogger('core')
-#corelogger.info("  ___ _____ _____ ____        _   ")
-#corelogger.info(" / _ \_   _|  ___| __ )  ___ | |_ ")
-#corelogger.info("| | | || | | |_  |  _ \ / _ \| __|")
-#corelogger.info("| |_| || | |  _| | |_) | (_) | |_ ")
-#corelogger.info(" \___/ |_| |_|   |____/ \___/ \__|")
-#corelogger.info("")
-#svnrevision="$Revision$".split(" ")[1] #TODO: this is only updated, when otfbot.py is updated
-# get messages from twisted as well
-#plo=otfbotlog.PythonLoggingObserver()
-#plo.start()
+root=logging.getLogger('')
+root.addHandler(filelogger)
+root.addHandler(errorlogger)
+root.addHandler(memorylogger)
+if stdout:
+    root.addHandler(console)
 
+plo = log.PythonLoggingObserver()
+plo.start()
+
+corelogger = logging.getLogger('core')
+corelogger.info("  ___ _____ _____ ____        _   ")
+corelogger.info(" / _ \_   _|  ___| __ )  ___ | |_ ")
+corelogger.info("| | | || | | |_  |  _ \ / _ \| __|")
+corelogger.info("| |_| || | |  _| | |_) | (_) | |_ ")
+corelogger.info(" \___/ |_| |_|   |____/ \___/ \__|")
+corelogger.info("")
+svnrevision="$Revision$".split(" ")[1] #TODO: this is only updated, when otfbot.py is updated
+
 class Options(usage.Options):
         optParameters = [["config","c","otfbot.yaml","Location of configfile"]]
 
@@ -108,7 +108,7 @@
 service_classes=[]
 service_instances=[]
 for service_name in service_names:
-    print "starting Service %s"%service_name
+    log.msg("starting Service %s" % service_name)
     service_classes.append(__import__("services."+service_name, fromlist=['botService']))
     service_instances.append(service_classes[-1].botService(application, application))
     service_instances[-1].setServiceParent(application)

Modified: trunk/plugins/ircClient/controlIRC.py
===================================================================
--- trunk/plugins/ircClient/controlIRC.py	2009-08-29 23:17:36 UTC (rev 590)
+++ trunk/plugins/ircClient/controlIRC.py	2009-08-30 13:08:15 UTC (rev 591)
@@ -34,6 +34,8 @@
             self.bot.sendmsg(nick,"Entered configuration modus. type 'endcontrol' to exit")
         elif self.control.has_key(user):
             output=self.control[user].handle_command(msg)
+            if output == None:
+                output = "None"
             self.bot.sendmsg(nick, output)
     
     def command(self, user, channel, command, options):
@@ -47,7 +49,8 @@
                 cmd.insert(0,self.bot.parent.parent.name)
                 cmd.insert(0,self.network)
                 r=self.bot.root.getNamedService("control").handle_command(" ".join(cmd))
-            self.bot.sendmsg(channel, r)
+            if r is not None:
+                self.bot.sendmsg(channel, r)
         elif command == "reload" and len(options) > 0:
             try:
                 self.bot.plugins['plugins.ircClient.'+options].reload()

Modified: trunk/plugins/ircClient/karma.py
===================================================================
--- trunk/plugins/ircClient/karma.py	2009-08-29 23:17:36 UTC (rev 590)
+++ trunk/plugins/ircClient/karma.py	2009-08-30 13:08:15 UTC (rev 591)
@@ -189,3 +189,6 @@
         for karmapath in self.karmapaths.keys():
             self.saveKarma(self.karmapaths[karmapath])
 
+    def start(self):
+        for c in self.bot.channels:
+            self.joined(c)
\ No newline at end of file

Modified: trunk/services/control.py
===================================================================
--- trunk/services/control.py	2009-08-29 23:17:36 UTC (rev 590)
+++ trunk/services/control.py	2009-08-30 13:08:15 UTC (rev 591)
@@ -95,7 +95,7 @@
                 return None
             if callable(cur[n]):
                 s.reverse()
-                self._exec(cur[n], s)
+                return self._exec(cur[n], s)
             else:
                 cur=cur[n]
                 
@@ -195,67 +195,4 @@
             elif len(args)==3:
                 return self.parent.getServiceNamed("config").get(setting, "[unset]", module, args[1], args[2], set_default=False)
         except ValueError:
-            return "Error: your setting is not in the module.setting form"
-    
-    def _cmd_network_ping(self, argument):
-        args=argument.split(" ")
-        if args[0] in self.parent.getServiceNamed("ircClient").namedServices:
-            self.parent.getServiceNamed("ircClient").getServiceNamed(args[0]).protocol.sendLine("PING %f"%time.time())
-            return "pinging network %s" % args[0]
-        else:
-            return "no network named %s known" % args[0]
-
-    def _cmd_modules_start(self, argument):
-        if len(argument)==0:
-            return "modules start module [module2] [module3] [...]"
-        mods = argument.split(" ")
-        for mod in mods:
-            for c in self.bot.classes:
-                if c.__name__==mod:
-                    for network in self.bot.ipc.getall():
-                        self.bot.ipc[network].startMod(c)
-        return "started modules"
-    def _cmd_modules_stop(self, argument):
-        if len(argument)==0:
-            return "modules stop module [module2] [module3] [...]"
-        mods = argument.split(" ")
-        for mod in mods:
-            if mod in self.bot.mods: #TODO: this does not work with different mods per network.
-                for network in self.bot.ipc.getall():
-                    self.bot.ipc[network].stopMod(mod)
-        return "stopped modules"
-    def _cmd_modules_reload(self,argument):
-        tmp = argument.split(" ")
-        if len(tmp) in [1,2]:
-            if tmp[0] in self.bot.ipc.getall().keys():
-                if len(tmp) == 1:
-                    self.bot.ipc[tmp[0]].reloadModules(False)
-                    return "Reloaded all modules of network "+tmp[0]
-                else:
-                    if tmp[1] in self.bot.mods.keys():
-                        for c in self.bot.classes:
-                            if c.__name__==tmp[1]:
-                                self.bot.reloadModuleClass(c)
-                                self.bot.restartModule(tmp[1], tmp[0])
-                                break
-            elif tmp[0]=="all":
-                if len(tmp) == 1:
-                    self.bot.reloadModules(True)
-                    return "reloaded all modules for all networks"
-                else:
-                    if tmp[1] in self.bot.mods.keys(): #any bot instance is ok, because every bot has the same mod classes
-                        for c in self.bot.classes:
-                            if c.__name__==tmp[1]:
-                                self.bot.reloadModuleClass(c)
-                                for network in self.bot.ipc.getall():
-                                    self.bot.ipc[network].restartModule(tmp[1], network)
-                                    return "restarted module %s"%tmp[1]
-                                break
-            else:
-                return "network %s not connected"%tmp[0]
-        return "Usage: [modules] reload network/all [modname]"
-    def _cmd_modules_list(self,argument):
-        module=[]
-        for mod in self.bot.mods:
-            module.append(mod.name)
-        return "The following modules are currently loaded: "+", ".join(module)
+            return "Error: your setting is not in the module.setting form"
\ No newline at end of file

Modified: trunk/services/ircClient.py
===================================================================
--- trunk/services/ircClient.py	2009-08-29 23:17:36 UTC (rev 590)
+++ trunk/services/ircClient.py	2009-08-30 13:08:15 UTC (rev 591)
@@ -24,8 +24,7 @@
 from twisted.words.protocols import irc
 
 import logging
-import logging.handlers
-import sys, traceback, string, time, os, glob
+import string, time
 
 from lib.pluginSupport import pluginSupport
 from lib.User import IrcUser
@@ -38,14 +37,14 @@
         self.parent=parent
         service.MultiService.__init__(self)
         self.controlservice=self.root.getNamedService('control')
+        self.logger=logging.getLogger(self.name)
         if not self.controlservice:
-            # TODO: turn into a logging-call
-            print "cannot register control-commands as no control-service is available"        
-            return
-        self.register_ctl_command(self.connect)
-        self.register_ctl_command(self.disconnect)
-        self.register_ctl_command(lambda : self.namedServices.keys(), name="list")
-        
+            logger.warning("cannot register control-commands as no control-service is available")
+        else:
+            self.register_ctl_command(self.connect)
+            self.register_ctl_command(self.disconnect)
+            self.register_ctl_command(lambda : self.namedServices.keys(), name="list")
+    
     def startService(self):
         self.config=self.root.getNamedServices()['config']
         for network in self.config.getNetworks():
@@ -84,21 +83,6 @@
             namespace.insert(0, self.name)
             self.controlservice.register_command(f, namespace, name)
             
-
-class legacyIPC:
-    def __init__(self, root):
-        self.root=root
-        self.logger=logging.getLogger('legacyIPC')
-    def __getitem__(self, item):
-        self.logger.warn("legacy __getitem__ used")
-        return self.root.getNamedServices()['ircClient'].namedServices[item].args[2].protocol
-    def get(self, item):
-        self.logger.warn("legacy get used")
-        return self.__getitem__(item)
-    def getall(self):
-        self.logger.warn("legacy getall used")
-        return self.root.getNamedServices()['ircClient'].namedServices.keys()
-
 class Bot(pluginSupport, irc.IRCClient):
     """ The Protocol of our IRC-Bot
         @ivar plugins: contains references to all plugins, which are loaded
@@ -119,13 +103,13 @@
         self.logger.debug("deprecated call to %s with args %s"%(str(method), str(args)))
         #XXX: use bot.config.method instead
         return method(*args, **kwargs)
+
     def __init__(self, root, parent):
         pluginSupport.__init__(self, root, parent)
         self.config=root.getNamedServices()['config']
         self.network=self.parent.network
         self.ircClient=self.parent.parent
         self.logger = logging.getLogger(self.network)
-        self.ipc=legacyIPC(self.root)
         if self.config.getBool('answerToCTCPVersion', True, 'main', self.network):
             self.versionName="OTFBot"
             self.versionNum="svn "+"$Revision: 177 $".split(" ")[1]
@@ -164,6 +148,7 @@
 
         self.startPlugins()
         self.register_my_commands()
+        self.register_pluginsupport_commands()
     
     def register_ctl_command(self, f, namespace=None, name=None):
         if namespace is None:
@@ -182,6 +167,7 @@
         self.register_ctl_command(lambda : self.channels, name="listchannels" )
         self.register_ctl_command(self.kick)
         self.register_ctl_command(self.sendmsg, name="say")
+        self.register_ctl_command(self.ping)
     
     def startPlugin(self, pluginName):
         plugin=pluginSupport.startPlugin(self, pluginName)
@@ -589,10 +575,13 @@
         self._apirunner("sendLine",{"line":line})
         irc.IRCClient.sendLine(self, line)
 
+    def ping(self):
+        self.sendLine("PING %f"%time.time())
+    
     def disconnect(self):
         """disconnects cleanly from the current network"""
         self._apirunner("stop")
-        self.quit('Bye')        
+        self.quit('Bye')
         
 class BotFactory(protocol.ReconnectingClientFactory):
     """The Factory for the Bot"""




Mehr Informationen über die Mailingliste Otfbot-dev