def remove_aka(self, channel, name): name = callbacks.canonicalName(name, preserve_spaces=True) if sys.version_info[0] < 3 and isinstance(name, str): name = name.decode('utf8') db = self.get_db(channel) db.cursor().execute('DELETE FROM aliases WHERE name = ?', (name,)) db.commit()
def remove_aka(self, channel, name): name = callbacks.canonicalName(name, preserve_spaces=True) if sys.version_info[0] < 3 and isinstance(name, str): name = name.decode('utf8') db = self.get_db(channel) db.query(SQLAlchemyAlias).filter(SQLAlchemyAlias.name == name).delete() db.commit()
def addAlias(self, irc, name, alias, lock=False): if self._invalidCharsRe.search(name): raise AliasError, 'Names cannot contain spaces or square brackets.' if '|' in name: raise AliasError, 'Names cannot contain pipes.' realName = callbacks.canonicalName(name) if name != realName: s = format('That name isn\'t valid. Try %q instead.', realName) raise AliasError, s name = realName if self.isCommandMethod(name): if realName not in self.aliases: s = 'You can\'t overwrite commands in this plugin.' raise AliasError, s if name in self.aliases: (currentAlias, locked, _) = self.aliases[name] if locked and currentAlias != alias: raise AliasError, format('Alias %q is locked.', name) try: f = makeNewAlias(name, alias) f = new.instancemethod(f, self, Alias) except RecursiveAlias: raise AliasError, 'You can\'t define a recursive alias.' aliasGroup = self.registryValue('aliases', value=False) if name in self.aliases: # We gotta remove it so its value gets updated. aliasGroup.unregister(name) conf.registerGlobalValue(aliasGroup, name, registry.String(alias, '')) conf.registerGlobalValue(aliasGroup.get(name), 'locked', registry.Boolean(lock, '')) self.aliases[name] = [alias, lock, f]
def get_feedName(irc, msg, args, state): if ircutils.isChannel(args[0]): state.errorInvalid('feed name', args[0], 'must not be channel names.') if not registry.isValidRegistryName(args[0]): state.errorInvalid('feed name', args[0], 'Feed names must not include spaces.') state.args.append(callbacks.canonicalName(args.pop(0)))
def addAlias(self, irc, name, alias, lock=False): if not self.isValidName(name): raise AliasError('Invalid alias name.') realName = callbacks.canonicalName(name) if name != realName: s = format(_('That name isn\'t valid. Try %q instead.'), realName) raise AliasError(s) name = realName if self.isCommandMethod(name): if realName not in self.aliases: s = 'You can\'t overwrite commands in this plugin.' raise AliasError(s) if name in self.aliases: (currentAlias, locked, _) = self.aliases[name] if locked and currentAlias != alias: raise AliasError(format('Alias %q is locked.', name)) f = makeNewAlias(name, alias) f = types.MethodType(f, self) if name in self.aliases: # We gotta remove it so its value gets updated. self.aliasRegistryRemove(name) aliasGroup = self.aliasRegistryGroup(name) if needsEscaping(name): confname = escapeAlias(name) else: confname = name conf.registerGlobalValue(aliasGroup, confname, registry.String(alias, '')) conf.registerGlobalValue(aliasGroup.get(confname), 'locked', registry.Boolean(lock, '')) self.aliases[name] = [alias, lock, f]
def addAlias(self, irc, name, alias, lock=False): if self._invalidCharsRe.search(name): raise AliasError, "Names cannot contain spaces or square brackets." if "|" in name: raise AliasError, "Names cannot contain pipes." realName = callbacks.canonicalName(name) if name != realName: s = format("That name isn't valid. Try %q instead.", realName) raise AliasError, s name = realName if self.isCommandMethod(name): if realName not in self.aliases: s = "You can't overwrite commands in this plugin." raise AliasError, s if name in self.aliases: (currentAlias, locked, _) = self.aliases[name] if locked and currentAlias != alias: raise AliasError, format("Alias %q is locked.", name) try: f = makeNewAlias(name, alias) f = new.instancemethod(f, self, Alias) except RecursiveAlias: raise AliasError, "You can't define a recursive alias." if name in self.aliases: # We gotta remove it so its value gets updated. conf.supybot.plugins.Alias.aliases.unregister(name) conf.supybot.plugins.Alias.aliases.register(name, registry.String(alias, "")) conf.supybot.plugins.Alias.aliases.get(name).register("locked", registry.Boolean(lock, "")) self.aliases[name] = [alias, lock, f]
def addAlias(self, irc, name, alias, lock=False): if not self._validNameRe.search(name): raise AliasError('Names can only contain alphanumerical ' 'characters, dots, pipes, and ' 'exclamation/interrogatin marks ' '(and the first character cannot be a number).') realName = callbacks.canonicalName(name) if name != realName: s = format(_('That name isn\'t valid. Try %q instead.'), realName) raise AliasError(s) name = realName if self.isCommandMethod(name): if realName not in self.aliases: s = 'You can\'t overwrite commands in this plugin.' raise AliasError(s) if name in self.aliases: (currentAlias, locked, _) = self.aliases[name] if locked and currentAlias != alias: raise AliasError(format('Alias %q is locked.', name)) f = makeNewAlias(name, alias) f = types.MethodType(f, self) if '.' in name or '|' in name: aliasGroup = self.registryValue('escapedaliases', value=False) confname = escapeAlias(name) else: aliasGroup = self.registryValue('aliases', value=False) confname = name if name in self.aliases: # We gotta remove it so its value gets updated. aliasGroup.unregister(confname) conf.registerGlobalValue(aliasGroup, confname, registry.String(alias, '')) conf.registerGlobalValue(aliasGroup.get(confname), 'locked', registry.Boolean(lock, '')) self.aliases[name] = [alias, lock, f]
def renameCommand(cb, name, newName): assert not hasattr(cb, newName), "Cannot rename over existing attributes." assert newName == callbacks.canonicalName(newName), "newName must already be normalized." if name != newName: method = getattr(cb.__class__, name) setattr(cb.__class__, newName, method) delattr(cb.__class__, name)
def __call__(self, irc, msg): self.__parent.__call__(irc, msg) irc = callbacks.SimpleProxy(irc, msg) newFeeds = {} for channel in irc.state.channels: feeds = self.registryValue("announce", channel) for name in feeds: commandName = callbacks.canonicalName(name) if self.isCommandMethod(commandName): url = self.feedNames[commandName][0] else: url = name if self.willGetNewFeed(url): newFeeds.setdefault((url, name), []).append(channel) for ((url, name), channels) in newFeeds.iteritems(): # We check if we can acquire the lock right here because if we # don't, we'll possibly end up spawning a lot of threads to get # the feed, because this thread may run for a number of bytecodes # before it switches to a thread that'll get the lock in # _newHeadlines. if self.acquireLock(url, blocking=False): try: t = threading.Thread( target=self._newHeadlines, name=format("Fetching %u", url), args=(irc, channels, name, url) ) self.log.info("Checking for announcements at %u", url) world.threadsSpawned += 1 t.setDaemon(True) t.start() finally: self.releaseLock(url) time.sleep(0.1) # So other threads can run.
def has_aka(self, channel, name): name = callbacks.canonicalName(name, preserve_spaces=True) if sys.version_info[0] < 3 and isinstance(name, str): name = name.decode('utf8') count = self.get_db(channel).query(SQLAlchemyAlias) \ .filter(SQLAlchemyAlias.name == name) \ .count() return bool(count)
def has_aka(self, channel, name): name = callbacks.canonicalName(name, preserve_spaces=True) if sys.version_info[0] < 3 and isinstance(name, str): name = name.decode('utf8') db = self.get_db(channel) return self.get_db(channel).cursor() \ .execute("""SELECT COUNT() as count FROM aliases WHERE name = ?;""", (name,)) \ .fetchone()[0]
def get_alias(self, channel, name): name = callbacks.canonicalName(name, preserve_spaces=True) if sys.version_info[0] < 3 and isinstance(name, str): name = name.decode('utf8') try: return self.get_db(channel).query(SQLAlchemyAlias.alias) \ .filter(SQLAlchemyAlias.name == name).one()[0] except sqlalchemy.orm.exc.NoResultFound: return None
def testCanonicalName(self): self.assertEqual('foo', callbacks.canonicalName('foo')) self.assertEqual('foobar', callbacks.canonicalName('foo-bar')) self.assertEqual('foobar', callbacks.canonicalName('foo_bar')) self.assertEqual('foobar', callbacks.canonicalName('FOO-bar')) self.assertEqual('foobar', callbacks.canonicalName('FOOBAR')) self.assertEqual('foobar', callbacks.canonicalName('foo___bar')) self.assertEqual('foobar', callbacks.canonicalName('_f_o_o-b_a_r')) # The following seems to be a hack for the Karma plugin; I'm not # entirely sure that it's completely necessary anymore. self.assertEqual('foobar--', callbacks.canonicalName('foobar--'))
def get_aka_lock(self, channel, name): name = callbacks.canonicalName(name, preserve_spaces=True) if sys.version_info[0] < 3 and isinstance(name, str): name = name.decode('utf8') try: return self.get_db(channel) \ .query(SQLAlchemyAlias.locked, SQLAlchemyAlias.locked_by, SQLAlchemyAlias.locked_at)\ .filter(SQLAlchemyAlias.name == name).one() except sqlalchemy.orm.exc.NoResultFound: raise AkaError(_('This Aka does not exist.'))
def removeAlias(self, name, evenIfLocked=False): name = callbacks.canonicalName(name) if name in self.aliases and self.isCommandMethod(name): if evenIfLocked or not self.aliases[name][1]: del self.aliases[name] conf.supybot.plugins.Alias.aliases.unregister(name) else: raise AliasError, 'That alias is locked.' else: raise AliasError, 'There is no such alias.'
def removeAlias(self, name, evenIfLocked=False): name = callbacks.canonicalName(name) if name in self.aliases and self.isCommandMethod(name): if evenIfLocked or not self.aliases[name][1]: del self.aliases[name] self.aliasRegistryRemove(name) else: raise AliasError('That alias is locked.') else: raise AliasError('There is no such alias.')
def unlock_aka(self, channel, name, by): name = callbacks.canonicalName(name, preserve_spaces=True) if sys.version_info[0] < 3 and isinstance(name, str): name = name.decode('utf8') db = self.get_db(channel) cursor = db.cursor() cursor.execute("""UPDATE aliases SET locked=0, locked_at=? WHERE name = ?""", (datetime.datetime.now(), name)) if cursor.rowcount == 0: raise AkaError(_('This Aka does not exist.')) db.commit()
def add_aka(self, channel, name, alias): name = callbacks.canonicalName(name, preserve_spaces=True) if self.has_aka(channel, name): raise AkaError(_('This Aka already exists.')) if sys.version_info[0] < 3: if isinstance(name, str): name = name.decode('utf8') if isinstance(alias, str): alias = alias.decode('utf8') db = self.get_db(channel) db.add(SQLAlchemyAlias(name, alias)) db.commit()
def get_aka_lock(self, channel, name): name = callbacks.canonicalName(name, preserve_spaces=True) if sys.version_info[0] < 3 and isinstance(name, str): name = name.decode('utf8') cursor = self.get_db(channel).cursor() cursor.execute("""SELECT locked, locked_by, locked_at FROM aliases WHERE name = ?;""", (name,)) r = cursor.fetchone() if r: return (bool(r[0]), r[1], r[2]) else: raise AkaError(_('This Aka does not exist.'))
def search(self, irc, msg, args, optlist, query): """[--channel <#channel>] <query> Searches Akas defined for <channel>. If <channel> is not specified, searches all global Akas.""" query = callbacks.canonicalName(query, preserve_spaces=True) channel = 'global' for (option, arg) in optlist: if option == 'channel': if not ircutils.isChannel(arg): irc.error(_('%r is not a valid channel.') % arg, Raise=True) channel = arg aka_list = self._db.get_aka_list(channel) aka_list = [callbacks.canonicalName(k[0], preserve_spaces=True) for k in aka_list] matching = [aka for aka in aka_list if query in aka] if matching: irc.replies(matching) else: irc.error(_("No matching Akas were found."))
def TestDocumentation(self): if self.__class__ in (PluginTestCase, ChannelPluginTestCase): return for cb in self.irc.callbacks: name = cb.name() if (name in self._noTestDoc) and not name.lower() in self.__class__.__name__.lower(): continue self.failUnless(sys.modules[cb.__class__.__name__].__doc__, "%s has no module documentation." % name) if hasattr(cb, "isCommandMethod"): for attr in dir(cb): if cb.isCommandMethod(attr) and attr == callbacks.canonicalName(attr): self.failUnless(getattr(cb, attr, None).__doc__, "%s.%s has no help." % (name, attr))
def get_alias(self, channel, name): name = callbacks.canonicalName(name, preserve_spaces=True) if sys.version_info[0] < 3 and isinstance(name, str): name = name.decode('utf8') cursor = self.get_db(channel).cursor() cursor.execute("""SELECT alias FROM aliases WHERE name = ?;""", (name,)) r = cursor.fetchone() if r: return r[0] else: return None
def isCommandMethod(self, name): args = name.split(' ') if len(args) > 1 and \ callbacks.canonicalName(args[0]) != self.canonicalName(): for cb in dynamic.irc.callbacks: # including this plugin if cb.getCommand(args[0:-1]): return False if sys.version_info[0] < 3 and isinstance(name, str): name = name.decode('utf8') channel = dynamic.channel or 'global' return self._db.has_aka(channel, name) or \ self._db.has_aka('global', name) or \ self.__parent.isCommandMethod(name)
def add_aka(self, channel, name, alias): name = callbacks.canonicalName(name, preserve_spaces=True) if self.has_aka(channel, name): raise AkaError(_('This Aka already exists.')) if minisix.PY2: if isinstance(name, str): name = name.decode('utf8') if isinstance(alias, str): alias = alias.decode('utf8') db = self.get_db(channel) cursor = db.cursor() cursor.execute("""INSERT INTO aliases VALUES ( NULL, ?, ?, 0, NULL, NULL);""", (name, alias)) db.commit()
def search(self, irc, msg, args, optlist, query): """[--channel <#channel>] <query> Searches Akas defined for <channel>. If <channel> is not specified, searches all global Akas.""" query = callbacks.canonicalName(query, preserve_spaces=True) channel = 'global' for (option, arg) in optlist: if option == 'channel': if not ircutils.isChannel(arg): irc.error(_('%r is not a valid channel.') % arg, Raise=True) channel = arg aka_list = self._db.get_aka_list(channel) aka_list = [ callbacks.canonicalName(k[0], preserve_spaces=True) for k in aka_list ] matching = [aka for aka in aka_list if query in aka] if matching: irc.replies(matching) else: irc.error(_("No matching Akas were found."))
def removeAlias(self, name, evenIfLocked=False): name = callbacks.canonicalName(name) if name in self.aliases and self.isCommandMethod(name): if evenIfLocked or not self.aliases[name][1]: del self.aliases[name] if '.' in name or '|' in name: conf.supybot.plugins.Alias.escapedaliases.unregister( escapeAlias(name)) else: conf.supybot.plugins.Alias.aliases.unregister(name) else: raise AliasError('That alias is locked.') else: raise AliasError('There is no such alias.')
def add_aka(self, channel, name, alias): name = callbacks.canonicalName(name, preserve_spaces=True) if self.has_aka(channel, name): raise AkaError(_('This Aka already exists.')) if sys.version_info[0] < 3: if isinstance(name, str): name = name.decode('utf8') if isinstance(alias, str): alias = alias.decode('utf8') db = self.get_db(channel) cursor = db.cursor() cursor.execute("""INSERT INTO aliases VALUES ( NULL, ?, ?, 0, NULL, NULL);""", (name, alias)) db.commit()
def isCommandMethod(self, name): args = name.split(' ') if '|' in args: return False if len(args) > 1 and \ callbacks.canonicalName(args[0]) != self.canonicalName(): for cb in dynamic.irc.callbacks: # including this plugin if cb.isCommandMethod(' '.join(args[0:-1])): return False if minisix.PY2 and isinstance(name, str): name = name.decode('utf8') channel = dynamic.channel or 'global' return self._db.has_aka(channel, name) or \ self._db.has_aka('global', name) or \ self.__parent.isCommandMethod(name)
def testDocumentation(self): if self.__class__ in (PluginTestCase, ChannelPluginTestCase): return for cb in self.irc.callbacks: name = cb.name() if ((name in self._noTestDoc) and \ not name.lower() in self.__class__.__name__.lower()): continue self.failUnless(sys.modules[cb.__class__.__name__].__doc__, '%s has no module documentation.' % name) if hasattr(cb, 'isCommandMethod'): for attr in dir(cb): if cb.isCommandMethod(attr) and \ attr == callbacks.canonicalName(attr): self.failUnless(getattr(cb, attr, None).__doc__, '%s.%s has no help.' % (name, attr))
def unlock_aka(self, channel, name, by): name = callbacks.canonicalName(name, preserve_spaces=True) if minisix.PY2 and isinstance(name, str): name = name.decode('utf8') db = self.get_db(channel) try: aka = db.query(SQLAlchemyAlias) \ .filter(SQLAlchemyAlias.name == name).one() except sqlalchemy.orm.exc.NoResultFound: raise AkaError(_('This Aka does not exist.')) if not aka.locked: raise AkaError(_('This Aka is already unlocked.')) aka.locked = False aka.locked_by = by aka.locked_at = datetime.datetime.now() db.commit()
def lock_aka(self, channel, name, by): name = callbacks.canonicalName(name) if sys.version_info[0] < 3 and isinstance(name, str): name = name.decode('utf8') db = self.get_db(channel) try: aka = db.query(Alias) \ .filter(Alias.name == name).one() except sqlalchemy.orm.exc.NoResultFound: raise AkaError(_('This Aka does not exist')) if aka.locked: raise AkaError(_('This Aka is already locked.')) aka.locked = True aka.locked_by = by aka.locked_at = datetime.datetime.now() db.commit()
def unlock_aka(self, channel, name, by): name = callbacks.canonicalName(name, preserve_spaces=True) if sys.version_info[0] < 3 and isinstance(name, str): name = name.decode('utf8') db = self.get_db(channel) try: aka = db.query(SQLAlchemyAlias) \ .filter(SQLAlchemyAlias.name == name).one() except sqlalchemy.orm.exc.NoResultFound: raise AkaError(_('This Aka does not exist.')) if not aka.locked: raise AkaError(_('This Aka is already unlocked.')) aka.locked = False aka.locked_by = by aka.locked_at = datetime.datetime.now() db.commit()
def addAlias(self, irc, name, alias, lock=False): if not self._validNameRe.search(name): raise AliasError('Names can only contain alphanumerical ' 'characters, dots, pipes, and ' 'exclamation/interrogatin marks ' '(and the first character cannot be a number).') realName = callbacks.canonicalName(name) if name != realName: s = format(_('That name isn\'t valid. Try %q instead.'), realName) raise AliasError(s) name = realName if self.isCommandMethod(name): if realName not in self.aliases: s = 'You can\'t overwrite commands in this plugin.' raise AliasError(s) if name in self.aliases: (currentAlias, locked, _) = self.aliases[name] if locked and currentAlias != alias: raise AliasError(format('Alias %q is locked.', name)) try: f = makeNewAlias(name, alias) f = types.MethodType(f, self) except RecursiveAlias: raise AliasError('You can\'t define a recursive alias.') if '.' in name or '|' in name: aliasGroup = self.registryValue('escapedaliases', value=False) confname = escapeAlias(name) else: aliasGroup = self.registryValue('aliases', value=False) confname = name if name in self.aliases: # We gotta remove it so its value gets updated. aliasGroup.unregister(confname) conf.registerGlobalValue(aliasGroup, confname, registry.String(alias, '')) conf.registerGlobalValue(aliasGroup.get(confname), 'locked', registry.Boolean(lock, '')) self.aliases[name] = [alias, lock, f]
def getCommandName(irc, msg, args, state): if ' ' in args[0]: state.errorInvalid(_('command name'), args[0]) else: state.args.append(callbacks.canonicalName(args.pop(0)))
def registerDefaultPlugin(command, plugin): command = callbacks.canonicalName(command) conf.registerGlobalValue(conf.supybot.commands.defaultPlugins, command, registry.String(plugin, '')) # This must be set, or the quotes won't be removed. conf.supybot.commands.defaultPlugins.get(command).set(plugin)
def get_status_uri(irc, msg, args, state): if not utils.web.urlRe.match(args[0]) and not os.path.exists(args[0]): state.errorInvalid('status uri', args[0], 'Status URIs must be valid URLs or file names.') state.args.append(callbacks.canonicalName(args.pop(0)))
def getEventName(irc, msg, args, state): if not registry.isValidRegistryName(args[0]): state.errorInvalid('event name', args[0], 'Illegal event name') state.args.append(callbacks.canonicalName(args.pop(0)))
def getFeedName(irc, msg, args, state): if not registry.isValidRegistryName(args[0]): state.errorInvalid('feed name', args[0], 'Feed names must not include spaces.') state.args.append(callbacks.canonicalName(args.pop(0)))
def getFeedName(irc, msg, args, state): if not registry.isValidRegistryName(args[0]): state.errorInvalid("feed name", args[0], "Feed names must not include spaces.") state.args.append(callbacks.canonicalName(args.pop(0)))