Example #1
0
    def depends(self, caller, deplist):
        '''\
        To be called at the top of a module.

        Allows inclusion of dependencies on other modules 
        (eg. a URL module depending on Open Graph).
        '''

        if caller in self.depends_stack:
            text = """depends: Recursive dependencies detected!
            Being called by {caller}, and is already on the stack.
            Stack is currently {stack}.""".format(caller=caller, stack=self.depends_stack)
            debug.write(text, debug.levels.Info)
            del text
            return None

        self.depends_stack.insert(0, caller)
        debug.write("depends: stack is {}".format(repr(self.depends_stack)))

        error = False
        for module in deplist:
            if not module in self.loaded:
                debug.write("depends: {module} (required by {caller}) is being loaded".format(module=module, caller=caller))
                try:
                    self.load(module)
                except:
                    debug.write("depends: couldn't load dep {module} (required by {caller})".format(module=module, caller=caller), debug.levels.Error)
                    ex = error.DependencyException(list(self.depends_stack))
                    self.depends_stack = []
                    raise

        debug.write("depends: dependencies for module {caller} satisfied".format(caller=caller))
        del self.depends_stack[0]
Example #2
0
    def load_init(self):
        '''\
        Load all the modules present in the `modules -> load` section of the configuration.
        '''

        for module in xbotpp.config['modules']['load']:
            status = self.load(module)
            debug.write('Loading module %s: %s' % (module, 'OK' if status else 'failed'), debug.levels.Info)
Example #3
0
    def constructor(r):
        # get this event handler's parent module
        parent = inspect.getmodule(r).__xbotpp_module__

        # check if we're running on an already-SID'd object
        if getattr(r, '__xbotpp_event__', None) != None:
            # we've already been run on this object, so die
            debug.write("on_event: Already been called on SID {}".format(getattr(r, '__xbotpp_event__', None)))
            return r

        # compare __name__ against parent module's existing event handlers
        # going on the assumption the module won't have two identically
        # named event handlers - which is a sane assumption to make...
        if parent in xbotpp.state.modules.loaded:
            for function in xbotpp.state.modules.loaded[parent]['events']:
                if xbotpp.state.modules.loaded[parent]['events'][function][0] == getattr(r, '__name__', None):
                    # we're the same, so bail
                    sa = "on_event: Already been called on handler with name {0} from module {1}."
                    debug.write(sa.format(getattr(r, '__name__', None), parent))
                    return r

        # assign event attribute
        setattr(r, '__xbotpp_event__', event)

        # and the SID
        sid = util.random_string()
        setattr(r, '__xbotpp_sid__', sid)

        # give it to the handler dispatch list
        handler.handlers.bind_event(event, r)

        # and put it in it's parent module table
        if parent not in xbotpp.state.modules.loaded:
            xbotpp.state.modules.create_table(parent)
        xbotpp.state.modules.loaded[parent]['events'][sid] = (getattr(r, '__name__', None), r)

        return r
Example #4
0
    def load(self, name):
        '''\
        Load the module `name`.

        Raises :exc:`error.ModuleLoadingException` on an error.
        '''

        try:
            # handle reloads right
            u = False
            if name in self.loaded:
                if 'reload' in self.loaded[name]:
                    u = True
                    debug.write("Module loaded, going to unload it first")
            if u:
                self.unload(name)

            module = importlib.import_module(name)
            imp.reload(module)

            if module.__xbotpp_module__:
                if module.__xbotpp_module__ not in self.loaded:
                    # if this module binds events, this will be done already
                    debug.write("Creating module table")
                    self.create_table(module.__xbotpp_module__)

                self.loaded[module.__xbotpp_module__]['module'] = module
                self.moddata[module.__xbotpp_module__] = xbotpp.vendor.sqliteshelf.SQLiteShelf(xbotpp.config['modules']['data_db'], module.__xbotpp_module__)

                if '_on_load' in dir(module):
                    module._on_load()
                debug.write("Loaded {} successfully.".format(module.__xbotpp_module__))
                return True
            else:
                raise error.ModuleLoadingException("Not a module: %s" % name)

        except Exception as e:
            debug.exception('Exception while loading module \'%s\'.' % name, e)
            raise error.ModuleLoadingException(e)
Example #5
0
def set_debug(e=True):
    '''Enable or disable debugging mode.'''

    debug.print_flagged = e
    debug.write('Debugging information has been %s.' % 'enabled' if e else 'disabled', debug.levels.Info)
Example #6
0
    def unload(self, name):
        '''\
        Unload the module `name`.

        If the module is not loaded, raises :exc:`error.ModuleNotLoaded`.
        '''

        if name not in self.loaded:
            debug.write("Module being unloaded does not exist ({}), raising exception".format(name))
            raise error.ModuleNotLoaded(name)

        try:
            if '_on_unload' in dir(self.loaded[name]['module']):
                self.loaded[name]['module']._on_unload()
        except Exception as e:
            xbotpp.debug.exception("Running module _on_unload(), continuing anyway", e)

        if name in self.moddata:
            del self.moddata[name]

        try:
            # Remove event handlers
            for sid in self.loaded[name]['events']:
                types = [(i, e) for i, e in enumerate(handler.handlers.dispatch)]
                for e_index, e_type in types:
                    debug.write("Loop: Checking type {}".format(e_type))
                    typed = [(i, e) for i, e in enumerate(handler.handlers.dispatch[e_type])]
                    for i, e in typed:
                        debug.write("Loop: handler {0} in type {1}".format(str(handler.handlers.dispatch[e_type][i]), e_type))
                        if handler.handlers.dispatch[e_type][i] == self.loaded[name]['events'][sid][1]:
                            debug.write("Removing event handler {0} ({1})".format(sid, self.loaded[name]['events'][sid][0]))
                            del handler.handlers.dispatch[e_type][i]

            # Remove command handlers
            commands = [(i, e) for i, e in enumerate(self.commands)]
            for index, command in commands:
                if self.commands[command]['module'] == name:
                    debug.write("Removing command {}".format(command))
                    del self.commands[command]

            del self.loaded[name]

            debug.write("Unloaded {} successfully.".format(name))

        except Exception as e:
            debug.exception("Exception while unloading module '{}'.".format(name), e)
            raise
Example #7
0
    def on_message(self, event):
        '''\
        Gets message events, does the command logic with them.
        '''

        if event.message.startswith(xbotpp.config['bot']['prefix']):            
            message_information = {
                'source': event.source,
                'target': event.source if event.type == 'privmsg' or event.type == 'privnotice' else event.target
            }

            debug.write("message_information: {}".format(repr(message_information)))

            commands = []
            temp = []

            try:
                if len(event.message) > 1 and event.message[1] == xbotpp.config['bot']['prefix']:
                    debug.write("using shlex to split command")
                    splitfunc = shlex.split
                    messagetosplit = event.message[2:]
                else:
                    debug.write("using str.split to split command")
                    splitfunc = lambda x: x.split(" ")
                    messagetosplit = event.message[1:]

                if len(messagetosplit) is 0:
                    debug.write('empty message, returning')
                    return

                debug.write('starting split')
                for i in splitfunc(messagetosplit):
                    debug.write('split: {}'.format(i))
                    if i != "|":
                        debug.write('Appending argument to temp array (currently {})'.format(repr(temp)))
                        temp.append(i)
                    else:
                        debug.write('End of command: {}'.format(repr(temp)))
                        commands.append(temp)
                        temp = []
            except Exception as e:
                debug.exception("Exception while parsing command", e)
                xbotpp.state.connection.send_message(message_information['target'], "Error: {}".format(str(e)))
                return

            debug.write('End of command: {}'.format(repr(temp)))
            commands.append(temp)
            del temp

            debug.write('Command sequence: {}'.format(repr(commands)))
            
            buf = ""

            for br in commands:
                if br[0] in self.commands:
                    debug.write('Command {0} found, privlevel {1}'.format(br[0], self.commands[br[0]]['privlevel']))

                    if self.commands[br[0]]['privlevel'] >= 1:
                        if message_information['source'] != xbotpp.config['bot']['owner']:
                            buf = "{}: Not authorized.".format(br[0])
                            debug.write(buf)
                            break
                    try:
                        message_information['command_name'] = br[0]
                        buf = self.commands[br[0]]['function'](message_information, br[1:], buf)
                    except Exception as e:
                        debug.exception("Exception while handling command {}".format(br[0]), e)
                        buf = "Exception in {0}: {1}".format(br[0], e)
                    debug.write('Buffer: {}'.format(buf))
                else:
                    debug.write('Command {} not found'.format(br[0]))
                    return
            
            try:
                for line in buf.split('\n'):
                    xbotpp.state.connection.send_message(message_information['target'], line)
            except Exception as e:
                debug.exception("Exception in writing buffer to target", e)
                message = "Error [{0}]: {1}".format(e.__class__.__name__, e)
                xbotpp.state.connection.send_message(message_information['target'], message)