示例#1
0
def test_get_nick_id(db):
    conn = sqlite3.connect(db_filename)
    tests = [
        [None, 'embolalia', Identifier('Embolalia')],
        # Ensures case conversion is handled properly
        [None, '[][]', Identifier('[]{}')],
        # Unicode, just in case
        [None, 'embölaliå', Identifier('EmbölaliÅ')],
    ]

    for test in tests:
        test[0] = db.get_nick_id(test[2])
        nick_id, slug, nick = test
        with conn:
            cursor = conn.cursor()
            registered = cursor.execute(
                'SELECT nick_id, slug, canonical FROM nicknames WHERE canonical IS ?',
                [nick]).fetchall()
            assert len(registered) == 1
            assert registered[0][1] == slug and registered[0][2] == nick

    # Check that each nick ended up with a different id
    assert len(set(test[0] for test in tests)) == len(tests)

    # Check that the retrieval actually is idempotent
    for test in tests:
        nick_id = test[0]
        new_id = db.get_nick_id(test[2])
        assert nick_id == new_id

    # Even if the case is different
    for test in tests:
        nick_id = test[0]
        new_id = db.get_nick_id(Identifier(test[2].upper()))
        assert nick_id == new_id
示例#2
0
def seen(bot, trigger):
    """Reports when and where the user was last seen."""
    if not trigger.group(2):
        bot.say(".seen <nick> - Reports when <nick> was last seen.")
        return
    nick = Identifier(trigger.group(2).strip())
    if nick in seen_dict:
        timestamp = seen_dict[nick]['timestamp']
        channel = seen_dict[nick]['channel']
        message = seen_dict[nick]['message']

        tz = get_timezone(bot.db, bot.config, None, trigger.nick,
                          trigger.sender)
        saw = datetime.datetime.utcfromtimestamp(timestamp)
        timestamp = format_time(bot.db, bot.config, tz, trigger.nick,
                                trigger.sender, saw)

        msg = "I last saw {} at {}".format(nick, timestamp)
        if Identifier(channel) == trigger.sender:
            msg = msg + " in here, saying " + message
        else:
            msg += " in another channel."
        bot.say(str(trigger.nick) + ': ' + msg)
    else:
        bot.say("Sorry, I haven't seen %s around." % nick)
示例#3
0
def collectlines(bot, trigger):
    """Create a temporary log of what people say"""

    # Don't log things in PM
    if trigger.is_privmsg:
        return

    # Add a log for the channel and nick, if there isn't already one
    if trigger.sender not in bot.memory['find_lines']:
        bot.memory['find_lines'][trigger.sender] = WillieMemory()
    if Identifier(
            trigger.nick) not in bot.memory['find_lines'][trigger.sender]:
        bot.memory['find_lines'][trigger.sender][Identifier(
            trigger.nick)] = list()

    # Create a temporary list of the user's lines in a channel
    templist = bot.memory['find_lines'][trigger.sender][Identifier(
        trigger.nick)]
    line = trigger.group()
    if line.startswith("s/"):  # Don't remember substitutions
        return
    elif line.startswith("\x01ACTION"):  # For /me messages
        line = line[:-1]
        templist.append(line)
    else:
        templist.append(line)

    del templist[:-10]  # Keep the log to 10 lines per person

    bot.memory['find_lines'][trigger.sender][Identifier(
        trigger.nick)] = templist
示例#4
0
def receive_info(bot, trigger):
    if trigger.sender != 'NickServ':
        return

    account = Identifier(trigger.group(2))
    nick = Identifier(trigger.group(1))

    try:
        bot.db.alias_nick(account, nick)
    except ValueError as e:
        try:
            bot.db.alias_nick(nick, account)
        except ValueError as e:
            if nick in force:
                bot.db.merge_nick_groups(account, nick)
                first_id = bot.db.get_nick_id(Identifier(account))
                second_id = bot.db.get_nick_id(Identifier(nick))
                bot.db.execute(
                    'UPDATE nicknames SET nick_id = ? WHERE nick_id = ?',
                    [first_id, second_id])
                bot.msg(nick, 'Merged {0} and {1}. If conflicting values were found' \
                    ' between accounts, values from {0} were used.'.format(account, nick))
                del force[nick]
            else:
                extra = ''
                if nick.lower() != account.lower():
                    extra = 'If you wish to merge data' \
                    ' from {0} to {1}, you may do so by using `.alias merge`. Please note that doing so' \
                    ' will overwrite conflicting values with those found in {0}. '.format(account, nick)
                bot.msg(nick, 'Sorry, I was unable to alias your nick' \
                    ' to your account -- it might have already been aliased. {1}({0})'.format(e.message, extra))
                return

    bot.msg(nick, 'Successfully aliased ' + nick + ' to account ' + account)
示例#5
0
def get_count(bot, user, chan):
    chan_count = bot.memory['pls_count']
    # only do something if there is conversation to work with
    if chan not in chan_count:
        return 0
    if Identifier(user) not in chan_count[chan]:
        return 0

    return chan_count[chan][Identifier(user)]
示例#6
0
    def alias_nick(self, nick, alias):
        """Create an alias for a nick.

        Raises ValueError if the alias already exists. If nick does not already
        exist, it will be added along with the alias."""
        nick = Identifier(nick)
        alias = Identifier(alias)
        nick_id = self.get_nick_id(nick)
        sql = 'INSERT INTO nicknames (nick_id, slug, canonical) VALUES (?, ?, ?)'
        values = [nick_id, alias.lower(), alias]
        try:
            self.execute(sql, values)
        except sqlite3.IntegrityError as e:
            raise ValueError('Alias already exists.')
示例#7
0
def f_remind(bot, trigger):
    """Give someone a message the next time they're seen"""
    teller = trigger.nick
    verb = trigger.group(1)

    if not trigger.group(3):
        bot.reply("%s whom?" % verb)
        return

    tellee = trigger.group(3).rstrip('.,:;')
    msg = trigger.group(2).lstrip(tellee).lstrip()

    if not msg:
        bot.reply("%s %s what?" % (verb, tellee))
        return

    tellee = Identifier(tellee)

    if not os.path.exists(bot.tell_filename):
        return

    if len(tellee) > 20:
        return bot.reply('That nickname is too long.')
    if tellee == bot.nick:
        return bot.reply("I'm here now, you can tell me whatever you want!")

    if not tellee in (Identifier(teller), bot.nick, 'me'):
        tz = willie.tools.get_timezone(bot.db, bot.config, None, tellee)
        timenow = willie.tools.format_time(bot.db, bot.config, tz, tellee)
        bot.memory['tell_lock'].acquire()
        try:
            if not tellee in bot.memory['reminders']:
                bot.memory['reminders'][tellee] = [(teller, verb, timenow, msg)
                                                   ]
            else:
                bot.memory['reminders'][tellee].append(
                    (teller, verb, timenow, msg))
        finally:
            bot.memory['tell_lock'].release()

        response = "I'll pass that on when %s is around." % tellee

        bot.reply(response)
    elif Identifier(teller) == tellee:
        bot.say('You can %s yourself that.' % verb)
    else:
        bot.say("Hey, I'm not as stupid as Monty you know!")

    dumpReminders(bot.tell_filename, bot.memory['reminders'],
                  bot.memory['tell_lock'])  # @@ tell
示例#8
0
文件: tell_by_pm.py 项目: jcguy/ATM
def watch(bot, trigger):
    """Receive a notification when a user speaks. Use * on the end of [nick] to match multiple nicks (e.g Tell*)"""
    
    if trigger.is_privmsg is False:
        return bot.reply("This command only works in PMs.")
        
    teller = trigger.nick
    verb = trigger.group(1)
    
    if not trigger.group(3):
        bot.reply("%s whom?" % verb)
        return
        
    tellee = trigger.group(3).rstrip('.,:;')
    
    tellee = Identifier(tellee)

    if len(tellee) > 20:
        return bot.reply('That nickname is too long.')
    if tellee == bot.nick or tellee == 'Cashy':
        return bot.reply("[-_-]")

    if not tellee in (Identifier(teller), bot.nick, 'me'):
        timenow = time.time()
        bot.memory['tell_lock'].acquire()
        try:
            if not tellee in bot.memory['tell_dict']:
                bot.memory['tell_dict'][tellee] = [(teller, verb, timenow, '')]
            else:
                found = False
                for (_teller, _verb, _datetime, _msg) in bot.memory['tell_dict'][tellee]:
                    if verb.lower()=='watch':
                        if _teller == teller:
                            found = True
                            break
                if found:
                    return bot.say("You already have me watching for %s." % tellee)
                else:
                    bot.memory['tell_dict'][tellee].append((teller, verb, timenow, ''))
        finally:
            bot.memory['tell_lock'].release()

        bot.reply("I'll let you know when I see %s." % tellee)
    elif Identifier(teller) == tellee:
        bot.say('[-_-]')
    else:
        bot.say("[-_-]")

    storage.put('tell',bot.memory['tell_dict'])
示例#9
0
def check_alias(bot, trigger):
    if not trigger.group(3):
        bot.reply('alias usage: .alias <add|merge|list>')
        return

    if (trigger.group(3).lower() == 'add'):
        bot.write(['PRIVMSG', 'NickServ', ':info', trigger.nick])
        bot.reply('Fetching NickServ info... I will get back to you in a PM')

    elif (trigger.group(3).lower() == 'merge'):
        force[trigger.nick] = True
        bot.write(['PRIVMSG', 'NickServ', ':info', trigger.nick])
        bot.reply('Fetching NickServ info... I will get back to you in a PM')

    elif (trigger.group(3).lower() == 'list'):
        try:
            alias = Identifier(trigger.nick)
            nick_id = bot.db.get_nick_id(alias, False)
            nicks = bot.db.execute(
                'SELECT DISTINCT canonical FROM nicknames WHERE nick_id = ?',
                [nick_id]).fetchall()
            bot.say('{}, your aliases are: {}'.format(
                trigger.nick, ' '.join([nick[0] for nick in nicks])))
        except:
            bot.say(
                'Something went wrong, perhaps you haven\'t aliased any nicks?'
            )
示例#10
0
def seen(bot, trigger):
    """Reports when and where the user was last seen."""
    if not trigger.group(2):
        bot.say(".seen <nick> - Reports when <nick> was last seen.")
        return
    nick = trigger.group(2).strip()
    timestamp = bot.db.get_nick_value(nick, 'seen_timestamp')
    if timestamp:
        channel = bot.db.get_nick_value(nick, 'seen_channel')
        message = bot.db.get_nick_value(nick, 'seen_message')

        tz = get_timezone(bot.db, bot.config, None, trigger.nick,
                          trigger.sender)
        saw = datetime.datetime.utcfromtimestamp(timestamp)
        timestamp = format_time(bot.db, bot.config, tz, trigger.nick,
                                trigger.sender, saw)

        msg = "I last saw {} at {}".format(nick, timestamp)
        if Identifier(channel) == trigger.sender:
            msg = msg + " in here, saying " + message
        else:
            msg += " in another channel."
        bot.say(str(trigger.nick) + ': ' + msg)
    else:
        bot.say("Sorry, I haven't seen {} around.".format(nick))
示例#11
0
def kickban(bot, trigger):
    """
    This gives admins the ability to kickban a user.
    The bot must be a Channel Operator for this command to work.
    .kickban [#chan] user1 user!*@* get out of here
    """
    if bot.privileges[trigger.sender][bot.nick] < HALFOP:
        return bot.reply("I'm not a channel operator!")
    text = trigger.group().split()
    argc = len(text)
    if argc < 4:
        return
    opt = Identifier(text[1])
    nick = opt
    mask = text[2]
    reasonidx = 3
    if not opt.is_nick():
        if argc < 5:
            return
        channel = opt
        nick = text[2]
        mask = text[3]
        reasonidx = 4
    reason = ' '.join(text[reasonidx:])
    mask = configureHostMask(mask)
    if mask == '':
        return
    bot.write(['MODE', channel, '+b', mask])
    bot.write(['KICK', channel, nick, ' :', reason])
示例#12
0
def kick(bot, trigger):
    """
    Kick a user from the channel.
    """
    if bot.privileges[trigger.sender][trigger.nick] < OP:
        return
    if bot.privileges[trigger.sender][bot.nick] < HALFOP:
        return bot.reply("I'm not a channel operator!")
    text = trigger.group().split()
    argc = len(text)
    if argc < 2:
        return
    opt = Identifier(text[1])
    nick = opt
    channel = trigger.sender
    reasonidx = 2
    if not opt.is_nick():
        if argc < 3:
            return
        nick = text[2]
        channel = opt
        reasonidx = 3
    reason = ' '.join(text[reasonidx:])
    if nick != bot.config.nick:
        bot.write(['KICK', channel, nick, reason])
示例#13
0
def ban(bot, trigger):
    """
    This give admins the ability to ban a user.
    The bot must be a Channel Operator for this command to work.
    """
    if bot.privileges[trigger.sender][trigger.nick] < OP:
        return
    if bot.privileges[trigger.sender][bot.nick] < HALFOP:
        return bot.reply("I'm not a channel operator!")
    text = trigger.group().split()
    argc = len(text)
    if argc < 2:
        return
    opt = Identifier(text[1])
    banmask = opt
    channel = trigger.sender
    if not opt.is_nick():
        if argc < 3:
            return
        channel = opt
        banmask = text[2]
    banmask = configureHostMask(banmask)
    if banmask == '':
        return
    bot.write(['MODE', channel, '+b', banmask])
示例#14
0
 def delete_nick_group(self, nick):
     """Removes a nickname, and all associated aliases and settings.
     """
     nick = Identifier(nick)
     nick_id = self.get_nick_id(nick, False)
     self.execute('DELETE FROM nicknames WHERE nick_id = ?', [nick_id])
     self.execute('DELETE FROM nick_values WHERE nick_id = ?', [nick_id])
示例#15
0
def test_merge_nick_groups(db):
    conn = sqlite3.connect(db_filename)
    aliases = ['Embolalia', 'Embo']
    for nick_id, alias in enumerate(aliases):
        conn.execute('INSERT INTO nicknames VALUES (?, ?, ?)',
                     [nick_id, Identifier(alias).lower(), alias])
    conn.commit()

    finals = (('foo', 'bar'), ('bar', 'blue'), ('spam', 'eggs'))

    db.set_nick_value(aliases[0], finals[0][0], finals[0][1])
    db.set_nick_value(aliases[0], finals[1][0], finals[1][1])
    db.set_nick_value(aliases[1], 'foo', 'baz')
    db.set_nick_value(aliases[1], finals[2][0], finals[2][1])

    db.merge_nick_groups(aliases[0], aliases[1])

    nick_id = conn.execute('SELECT nick_id FROM nicknames').fetchone()[0]
    alias_id = conn.execute('SELECT nick_id FROM nicknames').fetchone()[0]
    assert nick_id == alias_id

    for key, value in finals:
        found = conn.execute(
            'SELECT value FROM nick_values WHERE nick_id = ? AND key = ?',
            [nick_id, key]).fetchone()[0]
        assert json.loads(unicode(found)) == value
示例#16
0
def unquiet(bot, trigger):
    """
    This gives admins the ability to unquiet a user.
    The bot must be a Channel Operator for this command to work.
    """
    if bot.privileges[trigger.sender][trigger.nick] < OP:
        return
    if bot.privileges[trigger.sender][bot.nick] < OP:
        return bot.reply("I'm not a channel operator!")
    text = trigger.group().split()
    argc = len(text)
    if argc < 2:
        return
    opt = Identifier(text[1])
    quietmask = opt
    channel = trigger.sender
    if not opt.is_nick():
        if argc < 3:
            return
        quietmask = text[2]
        channel = opt
    quietmask = configureHostMask(quietmask)
    if quietmask == '':
        return
    bot.write(['MODE', opt, '-q', quietmask])
示例#17
0
 def set_nick_value(self, nick, key, value):
     """Sets the value for a given key to be associated with the nick."""
     nick = Identifier(nick)
     value = json.dumps(value, ensure_ascii=False)
     nick_id = self.get_nick_id(nick)
     self.execute('INSERT OR REPLACE INTO nick_values VALUES (?, ?, ?)',
                  [nick_id, key, value])
示例#18
0
 def get_nick_or_channel_value(self, name, key):
     """Gets the value `key` associated to the nick or channel  `name`.
     """
     name = Identifier(name)
     if name.is_nick():
         return self.get_nick_value(name, key)
     else:
         return self.get_channel_value(name, key)
示例#19
0
文件: tell_by_pm.py 项目: jcguy/ATM
def tell(bot, trigger):
    """Give someone a message the next time they're seen. Use * on the end of [recipient] to match multiple nicks (e.g Tell*)"""
    
    if trigger.is_privmsg is False:
        return bot.reply("This command only works in PMs.")

    teller = trigger.nick
    verb = trigger.group(1)

    if not trigger.group(3):
        bot.reply("%s whom?" % verb)
        return

    tellee = trigger.group(3).rstrip('.,:;')
    msg = trigger.group(2).lstrip(tellee).lstrip()

    if not msg:
        bot.reply("%s %s what?" % (verb, tellee))
        return

    tellee = Identifier(tellee)

    if len(tellee) > 20:
        return bot.reply('That nickname is too long.')
    if tellee == bot.nick or tellee == 'Cashy':
        return bot.reply("I'm right here.")

    if not tellee in (Identifier(teller), bot.nick, 'me'):
        timenow = time.time()
        bot.memory['tell_lock'].acquire()
        try:
            if not tellee in bot.memory['tell_dict']:
                bot.memory['tell_dict'][tellee] = [(teller, verb, timenow, msg)]
            else:
                bot.memory['tell_dict'][tellee].append((teller, verb, timenow, msg))
        finally:
            bot.memory['tell_lock'].release()

        bot.reply("I'll pass that on when %s is around." % tellee)
    elif Identifier(teller) == tellee:
        bot.say('You can %s yourself that.' % verb)
    else:
        bot.say("[-_-]")

    storage.put('tell',bot.memory['tell_dict'])
示例#20
0
文件: db.py 项目: dkg/willie
 def get_nick_value(self, nick, key):
     """Retrieves the value for a given key associated with a nick."""
     nick = Identifier(nick)
     result = self.execute(
         'SELECT value FROM nicknames, nick_values WHERE slug = ? AND key = ?',
         [nick.lower(), key]).fetchone()
     if result is not None:
         result = result[0]
     return _deserialize(result)
示例#21
0
 def get_channel_value(self, channel, key):
     """Retrieves the value for a given key associated with a channel."""
     channel = Identifier(channel).lower()
     result = self.execute(
         'SELECT value FROM channel_values WHERE channel = ? AND key = ?',
         [channel, key]).fetchone()
     if result is not None:
         result = result[0]
     return _deserialize(result)
示例#22
0
def promote_karma(bot, trigger):
    """
    Update karma status for specify IRC user if get '++' message.
    """
    if (trigger.is_privmsg):
        return bot.say('People like it when you tell them good things.')
    if (bot.db.get_nick_id(Identifier(trigger.group(1))) == bot.db.get_nick_id(
            Identifier(trigger.nick))):
        return bot.say('You may not give yourself karma!')
    current_karma = bot.db.get_nick_value(trigger.group(1), 'karma')
    if not current_karma:
        current_karma = 0
    else:
        current_karma = int(current_karma)
    current_karma += 1

    bot.db.set_nick_value(trigger.group(1), 'karma', current_karma)
    bot.say(trigger.group(1) + ' == ' + str(current_karma))
示例#23
0
def demote_karma(bot, trigger):
    """
    Update karma status for specify IRC user if get '--' message.
    """
    if (trigger.is_privmsg):
        return bot.say('Say it to their face!')
    if (bot.db.get_nick_id(Identifier(trigger.group(1))) == bot.db.get_nick_id(
            Identifier(trigger.nick))):
        return bot.say('You may not reduce your own karma!')
    current_karma = bot.db.get_nick_value(trigger.group(1), 'karma')
    if not current_karma:
        current_karma = 0
    else:
        current_karma = int(current_karma)
    current_karma -= 1

    bot.db.set_nick_value(trigger.group(1), 'karma', current_karma)
    bot.say(trigger.group(1) + ' == ' + str(current_karma))
示例#24
0
def track_modes(bot, trigger):
    """Track usermode changes and keep our lists of ops up to date."""
    # Mode message format: <channel> *( ( "-" / "+" ) *<modes> *<modeparams> )
    channel = Identifier(trigger.args[0])
    line = trigger.args[1:]

    # If the first character of where the mode is being set isn't a #
    # then it's a user mode, not a channel mode, so we'll ignore it.
    if channel.is_nick():
        return

    mapping = {
        'v': willie.module.VOICE,
        'h': willie.module.HALFOP,
        'o': willie.module.OP,
        'a': willie.module.ADMIN,
        'q': willie.module.OWNER
    }

    modes = []
    for arg in line:
        if len(arg) == 0:
            continue
        if arg[0] in '+-':
            # There was a comment claiming IRC allows e.g. MODE +aB-c foo, but
            # I don't see it in any RFCs. Leaving in the extra parsing for now.
            sign = ''
            modes = []
            for char in arg:
                if char == '+' or char == '-':
                    sign = char
                else:
                    modes.append(sign + char)
        else:
            arg = Identifier(arg)
            for mode in modes:
                priv = bot.privileges[channel].get(arg, 0)
                value = mapping.get(mode[1])
                if value is not None:
                    if mode[0] == '+':
                        priv = priv | value
                    else:
                        priv = priv & ~value
                    bot.privileges[channel][arg] = priv
示例#25
0
 def _nick_blocked(self, nick):
     bad_nicks = self.config.core.get_list('nick_blocks')
     for bad_nick in bad_nicks:
         bad_nick = bad_nick.strip()
         if not bad_nick:
             continue
         if (re.match(bad_nick + '$', nick, re.IGNORECASE)
                 or Identifier(bad_nick) == nick):
             return True
     return False
示例#26
0
def test_unalias_nick(db):
    conn = sqlite3.connect(db_filename)
    nick = 'Embolalia'
    nick_id = 42
    conn.execute('INSERT INTO nicknames VALUES (?, ?, ?)',
                 [nick_id, Identifier(nick).lower(), nick])
    aliases = ['EmbölaliÅ', 'Embo`work', 'Embo']
    for alias in aliases:
        conn.execute('INSERT INTO nicknames VALUES (?, ?, ?)',
                     [nick_id, Identifier(alias).lower(), alias])
    conn.commit()

    for alias in aliases:
        db.unalias_nick(alias)

    for alias in aliases:
        found = conn.execute('SELECT * FROM nicknames WHERE nick_id = ?',
                             [nick_id]).fetchall()
        assert len(found) == 1
示例#27
0
    def merge_nick_groups(self, first_nick, second_nick):
        """Merges the nick groups for the specified nicks.

        Takes two nicks, which may or may not be registered.  Unregistered
        nicks will be registered. Keys which are set for only one of the given
        nicks will be preserved. Where multiple nicks have values for a given
        key, the value set for the first nick will be used.

        Note that merging of data only applies to the native key-value store.
        If modules define their own tables which rely on the nick table, they
        will need to have their merging done separately."""
        first_id = self.get_nick_id(Identifier(first_nick))
        second_id = self.get_nick_id(Identifier(second_nick))
        self.execute(
            'UPDATE OR IGNORE nick_values SET nick_id = ? WHERE nick_id = ?',
            [first_id, second_id])
        self.execute('DELETE FROM nick_values WHERE nick_id = ?', [second_id])
        self.execute('UPDATE nicknames SET nick_id = ? WHERE nick_id = ?',
                     [first_id, second_id])
示例#28
0
def format_count(bot, trigger):
    if trigger.is_privmsg:
        return

    user = Identifier(trigger.group(2) or trigger.nick)

    user = Identifier(user.strip())

    count = get_count(bot, user, trigger.sender)
    since = bot.memory['pls_count_time']

    timezone = get_timezone(bot.db, bot.config, None, trigger.nick)
    if not timezone:
        timezone = 'UTC'
    time = format_time(bot.db, bot.config, timezone, trigger.nick,
                       trigger.sender, datetime.datetime.fromtimestamp(since))

    bot.say('{} has said pls in {} {} time(s) since {}'.format(
        user, trigger.sender, count, time))
示例#29
0
def handle_names(bot, trigger):
    """Handle NAMES response, happens when joining to channels."""
    names = trigger.split()

    #TODO specific to one channel type. See issue 281.
    channels = re.search('(#\S*)', trigger.raw)
    if not channels:
        return
    channel = Identifier(channels.group(1))
    if channel not in bot.privileges:
        bot.privileges[channel] = dict()
    bot.init_ops_list(channel)

    # This could probably be made flexible in the future, but I don't think
    # it'd be worth it.
    mapping = {
        '+': willie.module.VOICE,
        '%': willie.module.HALFOP,
        '@': willie.module.OP,
        '&': willie.module.ADMIN,
        '~': willie.module.OWNER
    }

    for name in names:
        priv = 0
        for prefix, value in iteritems(mapping):
            if prefix in name:
                priv = priv | value
        nick = Identifier(name.lstrip(''.join(mapping.keys())))
        bot.privileges[channel][nick] = priv

        # Old op list maintenance is down here, and should be removed at some
        # point
        if '@' in name or '~' in name or '&' in name:
            bot.add_op(channel, name.lstrip('@&%+~'))
            bot.add_halfop(channel, name.lstrip('@&%+~'))
            bot.add_voice(channel, name.lstrip('@&%+~'))
        elif '%' in name:
            bot.add_halfop(channel, name.lstrip('@&%+~'))
            bot.add_voice(channel, name.lstrip('@&%+~'))
        elif '+' in name:
            bot.add_voice(channel, name.lstrip('@&%+~'))
示例#30
0
def track_nicks(bot, trigger):
    """Track nickname changes and maintain our chanops list accordingly."""
    old = trigger.nick
    new = Identifier(trigger)

    # Give debug mssage, and PM the owner, if the bot's own nick changes.
    if old == bot.nick:
        privmsg = ("Hi, I'm your bot, %s."
                   "Something has made my nick change. "
                   "This can cause some problems for me, "
                   "and make me do weird things. "
                   "You'll probably want to restart me, "
                   "and figure out what made that happen "
                   "so you can stop it happening again. "
                   "(Usually, it means you tried to give me a nick "
                   "that's protected by NickServ.)") % bot.nick
        debug_msg = (
            "Nick changed by server. "
            "This can cause unexpected behavior. Please restart the bot.")
        LOGGER.critical(debug_msg)
        bot.msg(bot.config.core.owner, privmsg)
        return

    for channel in bot.privileges:
        channel = Identifier(channel)
        if old in bot.privileges[channel]:
            value = bot.privileges[channel].pop(old)
            bot.privileges[channel][new] = value

    # Old privilege maintenance
    for channel in bot.halfplus:
        if old in bot.halfplus[channel]:
            bot.del_halfop(channel, old)
            bot.add_halfop(channel, new)
    for channel in bot.ops:
        if old in bot.ops[channel]:
            bot.del_op(channel, old)
            bot.add_op(channel, new)
    for channel in bot.voices:
        if old in bot.voices[channel]:
            bot.del_voice(channel, old)
            bot.add_voice(channel, new)