]> kaliko git repositories - sid.git/blobdiff - sid/sid.py
Use async method properly
[sid.git] / sid / sid.py
index 0df5478de958e31dc1f268602b604196f8a828a1..d412ac4ad65d362b0427cdafb35a2f6485e8e7bd 100644 (file)
@@ -23,9 +23,15 @@ import traceback
 
 import slixmpp
 
+from sid import __url__
+
 
 def botcmd(*args, **kwargs):
-    """Decorator for bot command functions"""
+    """Decorator for bot command functions
+
+    :param bool hidden: is the command hidden in global help
+    :param str name: command name, default to decorated function name
+    """
 
     def decorate(func, hidden=False, name=None):
         setattr(func, '_bot_command', True)
@@ -42,13 +48,25 @@ def botcmd(*args, **kwargs):
 
 
 class MUCBot(slixmpp.ClientXMPP):
-
+    """
+    :param str jid: jid to log with
+    :param str password: jid password
+    :param str room: conference room to join
+    :param str nick: Nickname to use in the room
+    """
+
+    #: Class attribute to define bot's command prefix
+    #:
+    #: Defaults to "!"
     prefix = '!'
 
     def __init__(self, jid, password, room, nick, log_file=None,
                  log_level=logging.INFO):
         super(MUCBot, self).__init__(jid, password)
 
+        # Clean sphinx autodoc for self documentation
+        # (cf. MUCBot.help)
+        self.__doc__ = None
         self.log = logging.getLogger(__package__)
         self.plugins = list()
         self.commands = dict()
@@ -56,10 +74,10 @@ class MUCBot(slixmpp.ClientXMPP):
         self.nick = nick
         self.__set_logger(log_file, log_level)
         self.__seen = dict()
-        self.register_plugin('xep_0030') # Service Discovery
-        self.register_plugin('xep_0045') # Multi-User Chat
-        self.register_plugin('xep_0071') # xhtml-im
-        self.register_plugin('xep_0199') # self Ping
+        self.register_plugin('xep_0030')  # Service Discovery
+        self.register_plugin('xep_0045')  # Multi-User Chat
+        self.register_plugin('xep_0071')  # xhtml-im
+        self.register_plugin('xep_0199')  # self Ping
 
         # The session_start event will be triggered when
         # the bot establishes its connection with the server
@@ -74,7 +92,8 @@ class MUCBot(slixmpp.ClientXMPP):
 
         # Discover bot internal command (ie. help)
         for name, value in inspect.getmembers(self):
-            if inspect.ismethod(value) and getattr(value, '_bot_command', False):
+            if inspect.ismethod(value) and \
+               getattr(value, '_bot_command', False):
                 name = getattr(value, '_bot_command_name')
                 self.log.debug('Registered command: %s', name)
                 self.commands[name] = value
@@ -92,7 +111,10 @@ class MUCBot(slixmpp.ClientXMPP):
         self.log.debug('set logger, log level : %s', log_level)
 
     def message(self, msg):
-        """Messages handler"""
+        """Messages handler
+
+        Parses message received to detect :py:obj:`prefix`
+        """
         if msg['type'] not in ('groupchat', 'chat'):
             self.log.warning('Unhandled message')
             return
@@ -117,7 +139,8 @@ class MUCBot(slixmpp.ClientXMPP):
             reply = ''.join(traceback.format_exc())
             self.log.exception('An error occurred processing: %s: %s', body, reply)
             if self.log.level < 10 and reply:
-                self.send_message(mto=msg['from'].bare, mbody=reply, mtype='groupchat')
+                self.send_message(mto=msg['from'].bare, mbody=reply,
+                                  mtype='groupchat')
 
     def _view(self, pres):
         """Track known nick"""
@@ -125,7 +148,7 @@ class MUCBot(slixmpp.ClientXMPP):
         status = (pres['type'], pres['status'])
         self.__seen.update({nick: status})
 
-    def start(self, event):
+    async def start(self, event):
         """
         Process the session_start event.
 
@@ -133,35 +156,37 @@ class MUCBot(slixmpp.ClientXMPP):
         requesting the roster and broadcasting an initial
         presence stanza.
 
-        Arguments:
-            event -- An empty dictionary. The session_start
-                     event does not provide any additional
-                     data.
+        :param dict event: An empty dictionary. The session_start
+                     event does not provide any additional data.
         """
-        self.get_roster()
+        await self.get_roster()
         self.send_presence()
         self.plugin['xep_0045'].join_muc(self.room,
-                                        self.nick,
-                                        # If a room password is needed, use:
-                                        # password=the_room_password,
-                                        wait=True)
+                                         self.nick,
+                                         # If a room password is needed, use:
+                                         # password=the_room_password,
+                                         wait=True)
+
+    def register_bot_plugin(self, plugin_cls):
+        """Registers plugin, takes a class, the method instanciates the plugin
 
-    def register_bot_plugin(self, plugin_class):
-        self.plugins.append(plugin_class(self))
+        :param `sid.plugin.Plugin` plugin_cls: A :py:obj:`sid.plugin.Plugin` class
+        """
+        self.plugins.append(plugin_cls(self))
         for name, value in inspect.getmembers(self.plugins[-1]):
-            if inspect.ismethod(value) and getattr(value, '_bot_command',
-                                                   False):
+            if inspect.ismethod(value) and \
+               getattr(value, '_bot_command', False):
                 name = getattr(value, '_bot_command_name')
                 self.log.debug('Registered command: %s', name)
                 self.commands[name] = value
 
     def foreach_plugin(self, method, *args, **kwds):
         for plugin in self.plugins:
-            self.log.debug('shuting down %s', plugin.__str__)
+            self.log.debug('calling %s for %s', method, plugin)
             getattr(plugin, method)(*args, **kwds)
 
     def shutdown_plugins(self):
-        # TODO: why can't use event session_end|disconnected?
+        # TODO: also use event session_end|disconnected?
         self.log.info('shuting down')
         for plugin in self.plugins:
             self.log.debug('shuting down %s', plugin)
@@ -173,7 +198,8 @@ class MUCBot(slixmpp.ClientXMPP):
 
         Automatically assigned to the "help" command."""
         help_cmd = ('Type {}help <command name>'.format(self.prefix) +
-                    ' to get more info about that specific command.')
+                    ' to get more info about that specific command.\n\n' +
+                    f'SRC: {__url__}')
         if not args:
             if self.__doc__:
                 description = self.__doc__.strip()
@@ -192,7 +218,8 @@ class MUCBot(slixmpp.ClientXMPP):
             text = '{}\n\n{}'.format(description, usage)
         else:
             if args[0] in self.commands.keys():
-                text = self.commands[args[0]].__doc__.strip() or 'undocumented'
+                text = self.commands[args[0]].__doc__ or 'undocumented'
+                text = inspect.cleandoc(text)
             else:
                 text = 'That command is not defined.'
         if message['type'] == 'groupchat':