watch channels. channels events can be of remote origin.
Bases: fbf.lib.persist.PlugPersist
Watched object contains channels and subscribers.
check if channel is on whitelist.
return channels on whitelist.
check if channel has subscribers.
remove channel from whitelist.
add channel to whitelist.
unsubscribe a jid from a channel.
subscrive a jid to a channel.
get all subscribers of a channel.
unsubscribe a jid from a channel.
no arguments - see what channels we are watching.
no arguments - reset all watcher for a channel.
arguments: [<channel>] - start watching a target (channel/wave).
arguments: [<channel>] - stop watching a channel.
” no arguments - show channels that are watching us.
watch callback precondition.
the watcher callback, see if channels are followed and if so send data.
output the watched event to the channel.
# fbf/plugs/common/watcher.py # # """ watch channels. channels events can be of remote origin. """
from fbf.lib.commands import cmnds from fbf.lib.callbacks import callbacks, remote_callbacks, last_callbacks, first_callbacks from fbf.lib.persist import PlugPersist from fbf.lib.fleet import getfleet from fbf.utils.exception import handle_exception from fbf.lib.examples import examples from fbf.utils.locking import locked from fbf.utils.generic import stripcolor from fbf.lib.eventbase import EventBase
from fbf.utils.format import formatevent
import copy import logging
cpy = copy.deepcopy
class Watched(PlugPersist): """ Watched object contains channels and subscribers. """ 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 subscribe(self, botname, type, channel, jid): """ subscrive a jid to a channel. """ channel = channel.lower() jid = str(jid) if channel not in self.data.channels: self.data.channels[channel] = [] if not [botname, type, jid] in self.data.channels[channel]: self.data.channels[channel].append([botname, type, jid]) self.save() return True def unsubscribe(self, botname, type, channel, jid): """ unsubscribe a jid from a channel. """ channel = channel.lower() self.data.channels[channel].remove([botname, type, str(jid)]) self.save() return True def reset(self, channel): """ unsubscribe a jid from a channel. """ channel = channel.lower() self.data.channels[channel] = [] self.save() return True def subscribers(self, channel): """ get all subscribers of a channel. """ channel = channel.lower() try: return self.data.channels[channel] except KeyError: return [] def check(self, channel): """ check if channel has subscribers. """ channel = channel.lower() return channel in self.data.channels def enable(self, channel): """ add channel to whitelist. """ channel = channel.lower() if not channel in self.data.whitelist: self.data.whitelist.append(channel) self.save() def disable(self, channel): """ remove channel from whitelist. """ channel = channel.lower() try: self.data.whitelist.remove(channel) except ValueError: return False self.save() return True def available(self, channel): """ check if channel is on whitelist. """ channel = channel.lower() return channel in self.data.whitelist def channels(self, channel): """ return channels on whitelist. """ channel = channel.lower() res = [] for chan, targets in self.data.channels.items(): if channel in str(targets): res.append(chan) return res
watched = Watched('channels')
bots = {} def writeout(botname, type, channel, txt, eventjson): """ output the watched event to the channel. """ event = EventBase().load(eventjson) global bots watchbot = None if botname in bots: watchbot = bots[botname] if not watchbot: watchbot = getfleet().byname(botname) if not watchbot: watchbot = getfleet().makebot(type, botname) if watchbot: if not botname in bots: bots[botname] = watchbot txt = watchbot.normalize(txt) txt = stripcolor(txt) watchbot.outnocb(channel, txt, event=event)
def prewatchcallback(bot, event): """ watch callback precondition. """ if event.isdcc: return False logging.debug("watcher - checking %s - %s" % (event.channel, event.userhost)) if not event.channel: return False if not event.txt: return return watched.check(str(event.channel)) and event.how != "background" and event.forwarded def watchcallback(bot, event): """ the watcher callback, see if channels are followed and if so send data. """ #if not event.allowwatch: logging.warn("watch - allowwatch is not set - ignoring %s" % event.userhost) ; return subscribers = watched.subscribers(event.channel) watched.data.descriptions[event.channel.lower()] = event.title logging.info("watcher - %s - %s" % (event.channel, str(subscribers))) for item in subscribers: try: try: (botname, type, channel) = item except ValueError: continue if not event.allowatch: pass elif channel not in event.allowwatch: logging.warn("watcher - allowwatch denied %s - %s" % (channel, event.allowwatch)) ; continue m = formatevent(bot, event, subscribers, True) if event.cbtype in ['OUTPUT', 'JOIN', 'PART', 'QUIT', 'NICK']: txt = "[!] %s" % m.txt else: txt = "[%s] %s" % (m.nick or event.nick or event.auth, m.txt) if txt.count('] [') > 2: logging.debug("watcher - %s - skipping %s" % (type, txt)) ; continue logging.warn("watcher - forwarding to %s" % channel) writeout(botname, type, channel, txt, event.tojson()) except Exception as ex: handle_exception() first_callbacks.add('BLIP_SUBMITTED', watchcallback, prewatchcallback) first_callbacks.add('PRIVMSG', watchcallback, prewatchcallback) first_callbacks.add('JOIN', watchcallback, prewatchcallback) first_callbacks.add('PART', watchcallback, prewatchcallback) first_callbacks.add('QUIT', watchcallback, prewatchcallback) first_callbacks.add('NICK', watchcallback, prewatchcallback) first_callbacks.add('OUTPUT', watchcallback, prewatchcallback) first_callbacks.add('MESSAGE', watchcallback, prewatchcallback) first_callbacks.add('CONSOLE', watchcallback, prewatchcallback) first_callbacks.add('WEB', watchcallback, prewatchcallback) first_callbacks.add('DISPATCH', watchcallback, prewatchcallback) first_callbacks.add('TORNADO', watchcallback, prewatchcallback)
def handle_watcherstart(bot, event): """ arguments: [<channel>] - start watching a target (channel/wave). """ target = event.rest or event.channel watched.subscribe(bot.cfg.name, bot.type, target, event.channel) if not target in event.chan.data.watched: event.chan.data.watched.append(target) event.chan.save() event.done() cmnds.add('watcher-start', handle_watcherstart, 'OPER') cmnds.add('watch', handle_watcherstart, 'USER') examples.add('watcher-start', 'start watching a channel. ', 'watcher-start <channel>')
def handle_watcherreset(bot, event): """ no arguments - reset all watcher for a channel. """ watched.reset(event.channel) event.done() cmnds.add('watcher-reset', handle_watcherreset, ['OPER', 'USER', 'GUEST']) examples.add('watcher-reset', 'stop watching', 'watcher-reset')
def handle_watcherstop(bot, event): """ arguments: [<channel>] - stop watching a channel. """ if not event.rest: target = event.origin else: target = event.rest.strip() try: watched.unsubscribe(bot.cfg.name, bot.type, target, event.channel) except Exception as ex: event.reply("error removing watcher: %s" % str(ex)) ; return if target in event.chan.data.watched: event.chan.data.watched.remove(target) event.chan.save() event.done() cmnds.add('watcher-stop', handle_watcherstop, ['OPER', 'USER', 'GUEST']) examples.add('watcher-stop', 'stop watching a channel', 'watcher-stop #dunkbots')
def handle_watcherlist(bot, event): """ no arguments - see what channels we are watching. """ chans = watched.channels(event.channel) if chans: res = [] for chan in chans: try: res.append(chan) except KeyError: res.append(chan) event.reply("channels watched on %s: " % event.channel, res) cmnds.add('watcher-list', handle_watcherlist, ['OPER', 'USER', 'GUEST']) examples.add('watcher-list', 'show what channels we are watching', 'watcher-list')
def handle_watchersubscribers(bot, event): """" no arguments - show channels that are watching us. """ event.reply("watchers for %s: " % event.channel, watched.subscribers(event.channel)) cmnds.add('watcher-subscribers', handle_watchersubscribers, ['OPER', 'USER', 'GUEST']) examples.add('watcher-subscribers', 'show channels that are watching us. ', 'watcher-list')