def __init__(self, filename): PlugPersist.__init__(self, filename) if not self.data: self.data = {} if not self.data.has_key('names'): self.data['names'] = [] if not self.data.has_key('urls'): self.data['urls'] = {} if not self.data.has_key('feeds'): self.data['feeds'] = {} self.feeds = {}
def handle_forgetchan(bot, event): """" arguments: <item> and <matchstring> - set an information item. """ if not event.rest: event.missing("<item> and <match>") return try: (what, match) = event.rest.split(" and ", 2) except ValueError: what = event.rest match = None what = what.lower() items = PlugPersist(event.channel) got = False if not items.data: items.data = LazyDict() if items.data.has_key(what): if match == None: del items.data[what] got = True else: for i in range(len(items.data[what])): if match in items.data[what][i]: del items.data[what][i] got = True break if got: items.save() event.reply("item removed from %s database" % event.channel) else: event.reply("no %s item in channel database" % what)
def __init__(self, name, default={}): PlugPersist.__init__(self, name) self.data.name = name self.data.meetings = self.data.meetings or {} self.data.meetingtimestamps = self.data.meetingtimestamps or {} self.data.meetingsubs = self.data.meetingsubs or [] self.data.opensubs = self.data.opensubs or []
def __init__(self, name, default={}): PlugPersist.__init__(self, name) self.data.name = name self.data.count = self.data.count or 0 self.data.whoup = self.data.whoup or {} self.data.whodown = self.data.whodown or {} self.data.whyup = self.data.whyup or [] self.data.whydown = self.data.whydown or []
def __init__(self, filename, host): PlugPersist.__init__(self, filename) if not self.data: self.data = LazyDict() if not self.data.has_key('names'): self.data['names'] = [] if not self.data.has_key('urls'): self.data['urls'] = {} if not self.data.has_key('feeds'): self.data['feeds'] = {} if not self.data.has_key('host'): self.data['host'] = host self.feeds = {}
def __init__(self, name, default={}): PlugPersist.__init__(self, name) self.data.name = name self.data.count = self.data.count or 0 self.data.whoup = self.data.whoup or {} self.data.whodown = self.data.whodown or {} self.data.whyup = self.data.whyup or [] self.data.whydown = self.data.whydown or []
def __init__(self, name, default={}): PlugPersist.__init__(self, name) self.data.name = name self.data.etas = self.data.etas or {} self.data.etds = self.data.etds or {} self.data.etatimestamps = self.data.etatimestamps or {} self.data.etdtimestamps = self.data.etdtimestamps or {} self.data.etasubs = self.data.etasubs or [] self.data.opensubs = self.data.opensubs or [] self.data.arrivesubs = self.data.arrivesubs or [] self.data.logintimeouts = self.data.logintimeouts or {}
def handle_learn(bot, event): """" arguments: <item> is <description> - set an information item. """ if not event.rest: event.missing("<item> is <description>") ; return try: (what, description) = event.rest.split(" is ", 1) except ValueError: event.missing("<item> is <description>") ; return what = what.lower() items = PlugPersist(event.channel) if not items.data: items.data = LazyDict() if not items.data.has_key(what): items.data[what] = [] if description not in items.data[what]: items.data[what].append(description) items.save() event.reply("%s item added to %s database" % (what, event.channel))
def handle_lte(bot, ievent): user = getuser(ievent) if not user: return ievent.reply(getmessage('unknown_nick')) item = LteItem(user) args = ievent.rest.upper().split(' ') lteusers = PlugPersist('lteusers') if not lteusers.data: lteusers.data = {} if len(ievent.args) == 3 or len(ievent.args) == 2: if args[1] == '0': dayitem = LteItem(args[0]) if user in dayitem.data.ltes.keys(): del dayitem.data.ltes[user] dayitem.save() return ievent.reply(getmessage('lte_removed') % (user, args[0])) if args[0] not in ('MO', 'DI', 'MI', 'DO', 'FR', 'SA', 'SO'): #, 'MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU'): return ievent.reply('LTE syntax: !lte MO 1900') item.data.ltes[args[0]] = args item.save() dayitem = LteItem(args[0]) eta = " ".join(args[1:]) eta = re.sub(r'(\d\d):(\d\d)',r'\1\2', eta) dayitem.data.ltes[user] = eta dayitem.save() lteusers.data[user] = time.time() lteusers.save() ievent.reply(getmessage('lte_set') % (user, eta)) elif len(ievent.args) == 1: if args[0] in ('MO', 'DI', 'MI', 'DO', 'FR', 'SA', 'SO'): dayitem = LteItem(args[0]) if len(dayitem.data.ltes.keys()) > 0: reply = 'LTEs für %s: ' % args[0] for user in dayitem.data.ltes.keys(): reply += '%s [%s] ' % (user, dayitem.data.ltes[user]) ievent.reply(reply) else: ievent.reply(getmessage('err_unknown_day') % args[0]) elif len(ievent.args) == 0: reply = [] for day in weekdays: dayitem = LteItem(day) if len(dayitem.data.ltes.keys()) > 0: #reply += '%s: %s ' % (day, ', '.join(dayitem.data.ltes.keys())) reply.append('%s: %s ' % (day, ', '.join(dayitem.data.ltes.keys()))) ievent.reply(" | ".join(reply)) else: ievent.reply(str(len(ievent.rest.split(' '))))
def handle_forget(bot, event): """" arguments: <item> and <matchstring> - set an information item. """ if not event.rest: event.missing("<item> and <match>") ; return try: (what, match) = event.rest.split(" and ", 2) except ValueError: event.missing("<item> and <match>") ; return what = what.lower() items = PlugPersist(event.channel) if not items.data: items.data = LazyDict() if items.data.has_key(what): for i in range(len(items.data[what])): if match in items.data[what][i]: del items.data[what][i] items.save() break event.reply("item removed from %s database" % event.channel)
def learncb(bot, event): event.bind(bot) items = PlugPersist(event.channel) target = event.txt[1:].lower().split('!')[0].strip() if target in items.data: event.reply("%s is " % target, items.data[target], dot=", ") event.ready()
def handle_whatis(bot, event): items = PlugPersist(event.channel) what = event.rest.lower().split('!')[0].strip() if what in items.data and items.data[what]: event.reply("%s is " % event.rest, items.data[what], dot=", ") else: event.reply("no information known about %s" % what)
def handle_learntoglobal(bot, event): """ argument: <searchtxt> - search the items the bot has learned. """ items = PlugPersist(event.channel) globalitems = GlobalPersist("learndb") for i in items.data.keys(): if not globalitems.data.has_key(i): globalitems.data[i] = [] globalitems.data[i].extend(items.data) globalitems.save() event.reply("%s items copy to the global database. " % len(items.data))
def handle_forgetchan(bot, event): """" arguments: <item> and <matchstring> - set an information item. """ if not event.rest: event.missing("<item> and <match>") ; return try: (what, match) = event.rest.split(" and ", 2) except ValueError: what = event.rest ; match = None what = what.lower() items = PlugPersist(event.channel) got = False if not items.data: items.data = LazyDict() if items.data.has_key(what): if match == None: del items.data[what] ; got = True else: for i in range(len(items.data[what])): if match in items.data[what][i]: del items.data[what][i] got = True break if got: items.save() ; event.reply("item removed from %s database" % event.channel) else: event.reply("no %s item in channel database" % what)
def handle_forget(bot, event): """" set an information item. """ if not event.rest: event.missing("<item> and <match>") return try: (what, match) = event.rest.split(" and ", 2) except ValueError: event.missing("<item> and <match>") return what = what.lower() items = PlugPersist(event.channel) if not items.data: items.data = LazyDict() if items.data.has_key(what): for i in range(len(items.data[what])): if match in items.data[what][i]: del items.data[what][i] items.save() break event.reply("item removed from %s database" % event.channel)
def handle_searchitems(bot, event): """ argument: <searchtxt> - search the items the bot has learned. """ if not event.rest: event.missing("<searchtxt>") return items = PlugPersist(event.channel).data.keys() globalitems = GlobalPersist("learndb").data.keys() got = [] for i in items + globalitems: if event.rest in i: got.append(i) event.reply("found %s items: " % len(got), got)
def learncb(bot, event): """ learn callback, is for catching ? queries. """ event.bind(bot) result = [] items = PlugPersist(event.channel) target = event.txt.lower() if target[0] == "?": target = target[1:] if target[-1] == "?": target = target[:-1] if target in items.data: result = items.data[target] globalitems = GlobalPersist("learndb") if target in globalitems.data: if not target in result: result.extend(globalitems.data[target]) if result: event.reply("%s is " % target, result, dot=", ") event.ready()
def handle_whatis(bot, event): """ arguments: <item> - show what the bot has learned about a factoid. """ if not event.rest: event.missing("<what>") return items = PlugPersist(event.channel) what = event.rest.lower().split('!')[0].strip() result = [] if what in items.data and items.data[what]: result = items.data[what] globalitems = GlobalPersist("learndb") if what in globalitems.data and globalitems.data[what]: result.extend(globalitems.data[what]) if result: event.reply("%s is " % event.rest, result, dot=", ") else: event.reply("no information known about %s" % what)
def handle_learnchan(bot, event): """" arguments: <item> is <description> - set an information item. """ if not event.rest: event.missing("<item> is <description>") return try: (what, description) = event.rest.split(" is ", 1) except ValueError: event.missing("<item> is <description>") return what = what.lower() items = PlugPersist(event.channel) if not items.data: items.data = LazyDict() if not items.data.has_key(what): items.data[what] = [] if description not in items.data[what]: items.data[what].append(description) items.save() event.reply("%s item added to %s database" % (what, event.channel))
def handle_definechan(bot, event): """" arguments: <item> <description> - set an information item. """ if not event.rest: event.missing("<item> <description>") ; return if event.rest.startswith('"'): result = re.search(r'"(.*?)" (.*)$', event.rest) else: result = re.search(r'(.*?) (.*)$', event.rest) try: what = result.group(0) description = result.group(1) except ValueError: event.missing("<item> <description>") ; return what = what.lower() items = PlugPersist(event.channel) if not items.data: items.data = LazyDict() if not items.data.has_key(what): items.data[what] = [] if description not in items.data[what]: items.data[what] = [description] items.save() event.reply("definition for %s updated" % (what, event.channel))
def __init__(self, name): PlugPersist.__init__(self, name)
from jsb.lib.commands import cmnds from jsb.lib.callbacks import callbacks from jsb.lib.examples import examples from jsb.lib.persist import PlugPersist ## basic imports import time import os import logging ## defines changed = False idle = PlugPersist('idle.data') if not idle.data: idle.data = {} ## save on shutdown def ticksave(bot, event): global idle global changed if changed: idle.save() changed = False callbacks.add("TICK60", ticksave)
from jsb.lib.commands import cmnds from jsb.lib.callbacks import callbacks from jsb.lib.persist import PlugPersist from jsb.lib.examples import examples from jsb.lib.fleet import getfleet ## basic imports import logging ## defines defaultJID = '*****@*****.**' questions = PlugPersist('questions') experts = PlugPersist('experts') subjects = PlugPersist('subjects') ## ask-precondition def askprecondition(bot, event): """ check to see whether the callback needs to be executed. """ global questions if event.userhost in questions.data and not event.iscmnd: return True ## ask-callback
TOKEN = Marker() TOKEN_BEGIN = BeginMarker() TOKEN_END = EndMarker() TOKEN_NICK = NickMarker() # Order-k, use predictate [-k:] = [word,word,] # if ORDER_K==1: { ('eggs'):['with','spam',], 'with': ['bacon','green',] } # if ORDER_K==2: { ('eat','eggs'):['with',TOKEN,), ('eggs','with'): ['bacon',] } # ... # Logical setting is often 2 or 3 ORDER_K = 2 # Maximum generation cycles MAXGEN = 500 markovlearn = PlugPersist('markovlearn') markovlearn.data.l = markovlearn.data.l or [] markovwords = {} markovwordi = [] markovchains = {} cfg.define('loud', 0) def dummycb(bot, event): pass callbacks.add('START', dummycb)
## twitter plugin imports from jsb.plugs.common.twitter import twitter_out ## basic imports import logging import copy import time import types import hmac import hashlib ## defines forward = PlugPersist("forward-core") if not forward.data.allowin: forward.data.allowin = [] if not forward.data.channels: forward.data.channels = {} if not forward.data.outs: forward.data.outs = {} if not forward.data.whitelist: forward.data.whitelist = {} cpy = copy.deepcopy ## forward-precondition def forwardoutpre(bot, event):
def __init__(self, name, default={}): PlugPersist.__init__(self, name) self.data.name = name self.data.count = self.data.count or 0
# jsb/plugs/wave/gadget.py # # ## jsb imports from jsb.lib.commands import cmnds from jsb.lib.examples import examples from jsb.lib.persist import PlugPersist ## defines gadgeturls = PlugPersist('gadgeturls') gadgeturls.data['gadget'] = 'https://jsonbot.appspot.com/gadget.xml' gadgeturls.data['poll'] = 'https://jsonbot.appspot.com/poll.xml' gadgeturls.data['iframe'] = 'https://jsonbot.appspot.com/iframe.xml' gadgeturls.data['loadiframe'] = 'https://jsonbot.appspot.com/loadiframe.xml' ## load functions def loadroot(event, url): if event.rootblip: from waveapi import element event.rootblip.append(element.Gadget(url)) return True else: event.reply("can't find root blip.") ; return False def load(event, url): if event.blip: from waveapi import element
def __init__(self, name, default={}): PlugPersist.__init__(self, name) self.data.name = name self.data.rowcount = self.data.rowcount or 0.0 self.data.hubelcount = self.data.hubelcount or 0.0
# jsb/plugs/myplugs/socket/lights.py # # Author: Petraea # from jsb.lib.commands import cmnds from jsb.lib.examples import examples from jsb.lib.persist import PlugPersist #from doorsense import currentstatus #<-- Causing some bleedover? import select, sys, os, time, string import socket, logging import json, random light_config = PlugPersist('light_config') light_data = PlugPersist('light_data') light_aliases = PlugPersist('light_aliases') light_profiles = PlugPersist('light_profiles') #Custom error for parser class ParseError(Exception): pass def connectToLB(s=None): '''Handler for connecting to the lanbox middleware.''' if s is None: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((light_config.data['host'], light_config.data['port']))
from jsb.lib.fleet import getfleet from jsb.lib.errors import NoSuchWave from jsb.utils.exception import handle_exception from jsb.utils.generic import stripcolor ## basic imports import logging from copy import deepcopy as cpy # plugin state .. this is where the relay plugin data lives. It's JSON string # put into the database with memcache in between. The data is accessible # through object.data. When data changes call object.save() # see jsb/persist/persist.py block = PlugPersist('block') relay = PlugPersist('relay') ## CALLBACKS # these are the callbacks that do the hard work of the relay plugin takes # place. The precondition is called to see whether the callback should fire # or not. It should return True or False. # see jsb/callbacks.py def relayprecondition(bot, event): """ check to see whether the callback needs to be executed. """ if event.forwarded: return splitted = event.txt.split("]") try:
def handle_items(bot, event): items = PlugPersist(event.channel).data.keys() event.reply("i know %s items: " % len(items), items)
def __init__(self, name, default={}): PlugPersist.__init__(self, name) self.data.name = name self.data.orders = self.data.orders or {} self.data.orderer = self.data.orderer or '' self.data.dealer = self.data.dealer or ''
# jsb/plugs/myplugs/wol.py # # Author: The_Niz # """ wake up workstations and manage list of mac addresses """ ## jsb imports from jsb.lib.commands import cmnds from jsb.lib.persist import PlugPersist ##basic imports import socket import struct wol_list = PlugPersist('wol_list') ## defines def sendwolpacket(send_data): #taken from http://code.activestate.com/recipes/358449-wake-on-lan/ sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) sock.sendto(send_data, ('<broadcast>', 7)) def sanitize_macaddress(macaddress): #taken from http://code.activestate.com/recipes/358449-wake-on-lan/ # Check macaddress format and try to compensate. if len(macaddress) == 12: clean_macaddress = macaddress.upper() elif len(macaddress) == 12 + 5: sep = macaddress[2]
from jsb.lib.examples import examples from jsb.plugs.common.tinyurl import get_tinyurl ## basic imports import logging import xmlrpclib import re ## defines rpc_clients = {} gitHashRule = re.compile(r'.*\b([0-9a-f]{7,40})\b.*') cfg = PlugPersist('fisheye', {}) ## getRpcClient function def getRpcClient(project): if project["name"] not in rpc_clients: base_url = "%s/api/xmlrpc" % project["url"] server = xmlrpclib.ServerProxy(base_url) auth = server.login(project["username"], project["password"]) logging.info("Created new RPC client for %s with auth token: %s" % (project["name"], auth)) rpc_clients[project["name"]] = (server, auth) return rpc_clients[project["name"]] def containsHash(bot, ievent): if ievent.how == "backgound": return 0
def __init__(self, name, default={}): PlugPersist.__init__(self, name) self.data.name = name self.data.ltes = self.data.ltes or {}
from jsb.lib.persist import Persist, PlugPersist from jsb.lib.persistconfig import PersistConfig from jsb.lib.plugins import plugs as plugins ## basic imports import urllib import urllib2 import urlparse import copy import re import socket ## defines cfg = PlugPersist('snarf.cfg') pcfg = PersistConfig() pcfg.define('allow', ['text/plain', 'text/html', 'application/xml']) re_html_title = re.compile(u'<title>(.*?)</title>', re.I | re.M | re.S) re_url_match = re.compile(u'((?:http|https)://\S+)') re_html_valid = { 'result': re.compile('(Failed validation, \d+ errors?|Passed validation)', re.I | re.M), 'modified': re.compile('<th>Modified:</th><td colspan="2">([^<]+)</td>', re.I | re.M), 'server': re.compile('<th>Server:</th><td colspan="2">([^<]+)</td>', re.I | re.M),
from jsb.lib.persist import PlugPersist from jsb.lib.examples import examples from jsb.plugs.common.tinyurl import get_tinyurl from jsb.lib.persistconfig import PersistConfig ## basic import import re import urlparse import xmlrpclib import socket import logging ## defines cfg = PlugPersist('urlinfo', {}) plugcfg = PersistConfig() plugcfg.define("showpictures", 1) ## sanitize function def sanitize(text): """ Remove non-urls word by word. """ text = text.strip() text = re.sub('\s\s+', ' ', text) tmp = '' for i in text.split(' '): if len(i) >= 5: if i.find('www.') != -1 or i.find('http') != -1: tmp += i + ' ' tmp = tmp.strip()
from jsb.lib.examples import examples from jsb.lib.fleet import getfleet from jsb.utils.exception import handle_exception from jsb.utils.generic import stripcolor ## basic imports import logging from copy import deepcopy as cpy # plugin state .. this is where the relay plugin data lives. It's JSON string # put into the database with memcache in between. The data is accessible # through object.data. When data changes call object.save() # see jsb/persist/persist.py block = PlugPersist('block') relay = PlugPersist('relay') ## CALLBACKS # these are the callbacks that do the hard work of the relay plugin takes # place. The precondition is called to see whether the callback should fire # or not. It should return True or False. # see jsb/callbacks.py def relayprecondition(bot, event): """ precondition to check whether the callback needs to be executed. """ if event.how == "background": return False if event.isrelayed: logging.info("%s already relayed" % bot.cfg.name)
def __init__(self, filename): PlugPersist.__init__(self, filename) self.data.channels = self.data.channels or {} self.data.whitelist = self.data.whitelist or [] self.data.descriptions = self.data.descriptions or {}
def handle_items(bot, event): """ no arguments - show what items the bot has learned. """ items = PlugPersist(event.channel).data.keys() globalitems = GlobalPersist("learndb").data.keys() result = items + globalitems event.reply("i know %s items: " % len(result), result)
from jsb.lib.callbacks import callbacks from jsb.lib.threadloop import ThreadLoop ## basic imports import logging import time import SocketServer from SocketServer import ThreadingMixIn, StreamRequestHandler ## defines cfg = PlugPersist("irccat", { "botnames": ["default-sxmpp",], "host": "localhost", "port": "54321", "aliases": {}, "enable": False, }) shared_data = {} server = None outputthread = None ## irccat_output function def irccat_output(msg): fleet = getfleet() dest, msg = splitMsg(msg) for chan in dest:
from jsb.lib.examples import examples from jsb.plugs.common.tinyurl import get_tinyurl ## basic imports import logging import xmlrpclib import re import time #import modules.activecollab ## defines rpc_clients = {} cfg = PlugPersist('confluence', {}) ## fetRpcClient function def getRpcClient(sInfo): if sInfo["name"] not in rpc_clients: base_url = "%s/rpc/xmlrpc" % sInfo["url"] server = xmlrpclib.ServerProxy(base_url).confluence1 username, password = sInfo["username"], sInfo["password"] auth = server.login(username, password) rpc_clients[sInfo["name"]] = (server, auth) return rpc_clients[sInfo["name"]]
from jsb.lib.commands import cmnds from jsb.lib.persist import PlugPersist from jsb.lib.examples import examples from jsb.plugs.common.tinyurl import get_tinyurl import logging import re gitHashRule = re.compile(r'.*\b([0-9a-f]{7,40})\b.*') try: from github2.client import Github gh = Github() gotit = True except ImportError: gotit = False ; logging.warn("github2 is not installed. see https://github.com/ask/python-github2") cfg = PlugPersist('github', {}) def f_find_github_commit(phenny, input): print "Searching for commit...", input query = input.group(1) _find_github_commit(phenny, query) def _find_github_commit(phenny, query): pass def containsHash(bot, ievent): if ievent.how == "backgound": return 0 if cfg.data.has_key(ievent.channel) and len(cfg.data[ievent.channel]): if gitHashRule.match(ievent.txt): return 1 return 0
from jsb.plugs.common.tinyurl import get_tinyurl ## basic imports import logging import xmlrpclib import re import time #import modules.activecollab ## defines recent_tickets = {} min_age = 60 * 5 rpc_clients = {} cfg = PlugPersist('jira', {}) ## getServerInfo function def getServerInfo(server, auth): try: server_statuses = server.jira1.getStatuses(auth) statusMap = {} for status in server_statuses: statusMap[status['id']] = status['name'] server_priorities = server.jira1.getPriorities(auth) priorityMap = {} for priority in server_priorities: priorityMap[priority['id']] = priority['name']
def __init__(self, name): PlugPersist.__init__(self, name)
import logging import time import os import socket import SocketServer from SocketServer import ThreadingMixIn, StreamRequestHandler ## defines testing = False ACCEPTABLEUNITS = [u'\N{DEGREE SIGN}C',u'\N{DEGREE SIGN}F', 'K' ,u'\N{DEGREE SIGN}De', u'\N{DEGREE SIGN}N',u'\N{DEGREE SIGN}R',u'\N{DEGREE SIGN}R\N{LATIN SMALL LETTER E WITH ACUTE}', u'\N{DEGREE SIGN}R\N{LATIN SMALL LETTER O WITH STROKE}'] tcppassword = PlugPersist('tcppassword') APIFILE = '/mnt/spaceapi/status.json' cfg = PlugPersist("doorsense") sensorlist = PlugPersist('sensorlist', { #sensorlist.data = { 'door_locked':[ {'value':None,'location':'front_door','name':"front_door",'description':""}, {'value':None,'location':'back_door','name':"back_door",'description':""} ], 'temperature':[], 'barometer':[], 'humidity':[], 'beverage_supply':[],
# """ manage quotes. """ ## jsb imports from jsb.lib.commands import cmnds from jsb.lib.examples import examples from jsb.lib.persist import PlugPersist ## basic imports import random ## defines quotes = PlugPersist('quotes.data') if not quotes.data.index: quotes.data.index = 0 def handle_quoteadd(bot, event): """ add a quote. """ quotes.data.index += 1 quotes.data[quotes.data.index] = event.rest quotes.save() event.reply("quote %s added" % quotes.data.index) cmnds.add('quote-add', handle_quoteadd, ['USER', 'GUEST']) examples.add('quote-add', 'add a quote to the bot', 'quote-add blablabla')
from jsb.utils.timeutils import elapsedstring from jsb.utils.generic import getwho from jsb.lib.commands import cmnds from jsb.lib.callbacks import callbacks from jsb.lib.examples import examples from jsb.lib.persist import PlugPersist ## basic imports import time import os import logging ## defines idle = PlugPersist('idle.data') if not idle.data: idle.data = {} ## save on shutdown def shutdown(): global idle idle.save() ## callbacks def preidle(bot, event): """ idle precondition aka check if it is not a command """ if not event.iscmnd(): return True if bot.isgae and event.userhost in bot.cfg.followlist: return True