more user/channel tracking

This commit is contained in:
deathbybandaid 2019-07-01 10:28:23 -04:00
parent 0e69768a96
commit 71f395fd9d
5 changed files with 154 additions and 1 deletions

View File

@ -26,7 +26,7 @@ class BotChannels():
"""This Logs all channels known to the server""" """This Logs all channels known to the server"""
def __init__(self): def __init__(self):
self.setup_channels() self.setup_channels()
self.who_reqs = {}
self.lock = threading.Lock() self.lock = threading.Lock()
self.channel_lock = False self.channel_lock = False
self.channels = [] self.channels = []
@ -254,6 +254,38 @@ class BotChannels():
def mode(self, bot, trigger): def mode(self, bot, trigger):
return return
def rpl_names(self, 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(r'(#\S*)', trigger.raw)
if not channels:
return
channel = Identifier(channels.group(1))
self.add_channel(channel)
mapping = {'+': sopel.module.VOICE,
'%': sopel.module.HALFOP,
'@': sopel.module.OP,
'&': sopel.module.ADMIN,
'~': sopel.module.OWNER}
for name in names:
nick = Identifier(name.lstrip(''.join(mapping.keys())))
self.add_to_channel(channel, nick)
def rpl_who(self, bot, trigger):
if len(trigger.args) < 2 or trigger.args[1] not in self.who_reqs:
# Ignored, some module probably called WHO
return
if len(trigger.args) != 8:
return
_, _, channel, user, host, nick, status, account = trigger.args
nick = Identifier(nick)
channel = Identifier(channel)
self.add_to_channel(channel, nick)
def check_channel_bot(self, channel, allchan=False): def check_channel_bot(self, channel, allchan=False):
if str(channel).lower() in self.channels: if str(channel).lower() in self.channels:
return True return True

View File

@ -35,6 +35,8 @@ class BotEvents(object):
def __init__(self): def __init__(self):
self.lock = threading.Lock() self.lock = threading.Lock()
self.RPL_WELCOME = '001' # This is a defined IRC event self.RPL_WELCOME = '001' # This is a defined IRC event
self.RPL_NAMREPLY = '353' # This is a defined IRC event
self.RPL_WHOREPLY = '352' # This is a defined IRC event
self.BOT_UPTIME = time.time() self.BOT_UPTIME = time.time()
self.BOT_WELCOME = '1001' self.BOT_WELCOME = '1001'
self.BOT_READY = '1002' self.BOT_READY = '1002'

View File

@ -2,6 +2,7 @@
from __future__ import unicode_literals, absolute_import, division, print_function from __future__ import unicode_literals, absolute_import, division, print_function
"""A way to track users""" """A way to track users"""
import sopel
from sopel.tools import Identifier from sopel.tools import Identifier
from .Database import db as botdb from .Database import db as botdb
@ -10,6 +11,7 @@ from .Tools import is_number, inlist, similar, array_arrangesort
import spicemanip import spicemanip
import threading import threading
import re
# TODO timestamp for new .seen # TODO timestamp for new .seen
@ -261,6 +263,83 @@ class BotUsers():
def mode(self, bot, trigger): def mode(self, bot, trigger):
return return
def rpl_names(self, 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(r'(#\S*)', trigger.raw)
if not channels:
return
channel = Identifier(channels.group(1))
mapping = {'+': sopel.module.VOICE,
'%': sopel.module.HALFOP,
'@': sopel.module.OP,
'&': sopel.module.ADMIN,
'~': sopel.module.OWNER}
for name in names:
nick = Identifier(name.lstrip(''.join(mapping.keys())))
# Identify
nick_id = self.whois_ident(nick)
# Verify nick is in the all list
self.add_to_all(nick, nick_id)
# Verify nick is in the all list
self.add_to_current(nick, nick_id)
# set current nick
self.mark_current_nick(nick, nick_id)
# add joined channel to nick list
self.add_channel(channel, nick_id)
# mark user as online
self.mark_user_online(nick_id)
def rpl_who(self, bot, trigger):
if len(trigger.args) < 2 or trigger.args[1] not in self.who_reqs:
# Ignored, some module probably called WHO
return
if len(trigger.args) != 8:
return
_, _, channel, user, host, nick, status, account = trigger.args
nick = Identifier(nick)
channel = Identifier(channel)
# Identify
nick_id = self.whois_ident(nick)
# Verify nick is in the all list
self.add_to_all(nick, nick_id)
# Verify nick is in the all list
self.add_to_current(nick, nick_id)
# set current nick
self.mark_current_nick(nick, nick_id)
# add joined channel to nick list
self.add_channel(channel, nick_id)
# mark user as online
self.mark_user_online(nick_id)
def account(self, bot, trigger):
# Identify
nick_id = self.whois_ident(trigger.nick)
# Verify nick is in the all list
self.add_to_all(trigger.nick, nick_id)
# Verify nick is in the all list
self.add_to_current(trigger.nick, nick_id)
# set current nick
self.mark_current_nick(trigger.nick, nick_id)
# mark user as online
self.mark_user_online(nick_id)
def track_notify(self, bot, trigger):
# Identify
nick_id = self.whois_ident(trigger.nick)
# Verify nick is in the all list
self.add_to_all(trigger.nick, nick_id)
# Verify nick is in the all list
self.add_to_current(trigger.nick, nick_id)
# set current nick
self.mark_current_nick(trigger.nick, nick_id)
# mark user as online
self.mark_user_online(nick_id)
def nick_actual(self, nick, altlist=None): def nick_actual(self, nick, altlist=None):
nick_id = self.whois_ident(nick) nick_id = self.whois_ident(nick)
nick_actual = self.ID(nick_id) nick_actual = self.ID(nick_id)

View File

@ -139,3 +139,17 @@ def channels_users_mode(bot, trigger):
def bot_channelscan(bot, trigger): def bot_channelscan(bot, trigger):
while True: while True:
SpiceBot.channels.channel_scan(bot) SpiceBot.channels.channel_scan(bot)
@sopel.module.event(SpiceBot.events.RPL_NAMREPLY)
@sopel.module.rule('(.*)')
def handle_names(bot, trigger):
SpiceBot.channels.rpl_names(bot, trigger)
@sopel.module.event(SpiceBot.events.RPL_WHOREPLY)
@sopel.module.rule('.*')
@sopel.module.priority('high')
@sopel.module.unblockable
def recv_who(bot, trigger):
SpiceBot.channels.rpl_who(bot, trigger)

View File

@ -54,3 +54,29 @@ def bot_channelscan_users(bot, trigger):
@sopel.module.rule('.*') @sopel.module.rule('.*')
def bot_users_chat(bot, trigger): def bot_users_chat(bot, trigger):
SpiceBot.users.chat(bot, trigger) SpiceBot.users.chat(bot, trigger)
@sopel.module.event(SpiceBot.events.RPL_NAMREPLY)
@sopel.module.rule('(.*)')
def handle_names(bot, trigger):
SpiceBot.users.rpl_names(bot, trigger)
@sopel.module.event(SpiceBot.events.RPL_WHOREPLY)
@sopel.module.rule('.*')
@sopel.module.priority('high')
@sopel.module.unblockable
def recv_who(bot, trigger):
SpiceBot.users.rpl_who(bot, trigger)
@sopel.module.event('ACCOUNT')
@sopel.module.rule('.*')
def account_notify(bot, trigger):
SpiceBot.users.account(bot, trigger)
@sopel.module.event('AWAY')
@sopel.module.rule('.*')
def track_notify(bot, trigger):
SpiceBot.users.track_notify(bot, trigger)