コード例 #1
0
ファイル: fish.py プロジェクト: buzzworkers/tl
def init():
  """ Init """
  if not got: raise RequireError("PyCrypto is required for FiSH. Please install this library if you want to use this plug")
  if cfg.enable:
    inputmorphs.add(fishin)
    outputmorphs.add(fishout)
    callbacks.add("NOTICE", dh1080_exchange)
    cmnds.add("fish", handle_fish, "OPER")
    examples.add("fish", "command that handles fish enrypting over IRC", "fish help")
  else: logging.warn("fish plugin is not enabled - use fish-cfg enable 1")
コード例 #2
0
ファイル: markov.py プロジェクト: buzzworkers/tl
def init():
    """ init plugin """
    if not cfg.get("enable"):
        return 1
    callbacks.add("PRIVMSG", cb_markovtalk, cb_markovtalk_test, threaded=True)
    callbacks.add("JOIN", cb_markovjoin, threaded=True)
    callbacks.add("MESSAGE", cb_markovtalk, cb_markovtalk_test, threaded=True)
    callbacks.add("CONSOLE", cb_markovtalk, cb_markovtalk_test, threaded=True)
    start_new_thread(markovtrain, (markovlearn.data.l,))
    return 1
コード例 #3
0
ファイル: twitter.py プロジェクト: buzzworkers/tl
## tweppy imports

from tl.contrib import tweepy

## basic imports

import os
import urllib.request, urllib.error, urllib.parse
import types
import logging

## load on start

def twitterstart(bot, event): pass

callbacks.add("START", twitterstart)

## twitter callbacks

def twitterpre(bot, event):
    try:
         twittername = event.chan.data.twittername
         if twittername: return True
    except Exception as ex: pass
    return False
    
def twittercb(bot, event):
    event.dontbind = False
    event.bind(force=True)
    try: twittername = event.chan.data.twittername
    except Exception as ex: handle_exception() ; twittername = None
コード例 #4
0
ファイル: idle.py プロジェクト: buzzworkers/tl
## 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)

## callbacks

def preidle(bot, event):
    """ idle precondition aka check if it is not a command """
    if not event.iscmnd() and event.inchan and not event.isoutput: return True
        
def idlecb(bot, event):
    """ idle PRIVMSG callback .. set time for channel and nick """
    ttime = time.time()
    idle.data[event.userhost] = ttime
    idle.data[event.channel] = ttime
    idle.sync()
    global changed
    changed = True
コード例 #5
0
ファイル: seen.py プロジェクト: buzzworkers/tl
                "server": bot.cfg.server,
                "channel": ievent.channel,
                "what": "entrando na sala %s" % ievent.channel,
            }

    def size(self):
        return len(list(self.data.keys()))


## init

seen = Seen()

## callbacks and commands register

callbacks.add("PRIVMSG", seen.privmsgcb)
callbacks.add("JOIN", seen.joincb)
callbacks.add("PART", seen.partcb)
callbacks.add("QUIT", seen.quitcb)

## seen command


def handle_seen(bot, ievent):
    """ arguments: <nick> - lookup last seen information. """
    if not ievent.args:
        ievent.missing("<nick>")
        return
    if True:
        nick = ievent.args[0].lower()
        if nick not in seen.data:
コード例 #6
0
ファイル: geo.py プロジェクト: buzzworkers/tl
examples.add("geo", "do a geo lookup on ip nr", "geo 127.0.0.1")

## callbacks

def handle_geoPRE(bot, event):
    if "." in event.hostname and event.chan and event.chan.data.dogeo: return True 

def handle_geoJOIN(bot, event):
    event.reply("geo - doing query on %s" % event.hostname)
    try:
        result = querygeoipserver(host2ip(event.hostname))
        if result: event.reply("%s lives in %s, %s (%s)" % (event.nick, result['city'], result['country_name'], result['country_code']))
        else: event.reply("no result")
    except: handle_exception()

callbacks.add("JOIN", handle_geoJOIN, handle_geoPRE)

## geo-on command

def handle_geoon(bot, event):
    """ no arguments - enable geo lookup on JOIN. """
    event.chan.data.dogeo = True
    event.chan.save()
    event.done()

cmnds.add("geo-on", handle_geoon, ["OPER"])
examples.add("geo-on", "enable geo loopups.", "geo-on")

## geo-off command

def handle_geooff(bot, event):
コード例 #7
0
ファイル: ops.py プロジェクト: buzzworkers/tl
cfg.define('oponsplit', 0)

## onjoincb callback

def opjoincb(bot, ievent):
    """ see if we should op a user on join """
    # don't try to op the bot
    if ievent.nick == bot.nick: return
    #if bot.state.has_key('no-op') and chan in bot.state['no-op']: return
    import time
    time.sleep(1)
    if (ievent.user and 'OPER' in ievent.user.data.perms) or (ievent.chan and ievent.userhost in ievent.chan.data.ops): bot.doop(ievent.channel.lower(), ievent.nick)
    try: bot.splitted.remove(ievent.nick.lower())
    except (ValueError, AttributeError): pass

callbacks.add('JOIN', opjoincb)

## op command

def handle_op1(bot, ievent):
    """ op [<nick>] .. op an user """
    chan = ievent.channel.lower()
    #if bot.state.has_key('no-op') and chan in bot.state['no-op']:
    #    ievent.reply('opping is disabled in %s' % ievent.channel)
    #    return
    try: nick = ievent.args[0]
    except IndexError: nick = ievent.nick
    userhost = getwho(bot, nick)
    if not userhost: userhost = ievent.userhost
    if (ievent.user and 'OPER' in ievent.user.data.perms) or (ievent.chan and userhost in ievent.chan.data.ops): bot.doop(chan, nick)
    ievent.done()
コード例 #8
0
ファイル: chan.py プロジェクト: buzzworkers/tl
        return
    ievent.reply('channel mode of %s is %s' % (chan, ievent.chan.data.mode))

cmnds.add('chan-mode', handle_channelmode, 'OPER')
examples.add('chan-mode', 'show mode of channel', '1) chan-mode 2) chan-mode #test')

## mode callback

def modecb(bot, ievent):
    """ callback to detect change of channel key. """
    if ievent.postfix.find('+k') != -1:
        key = ievent.postfix.split('+k')[1]
        ievent.chan.data.key = key
        ievent.chan.save()

callbacks.add('MODE', modecb)

## chan-denyplug command

def handle_chandenyplug(bot, event):
    """ arguments: <plugname> - deny a plugin to be active in a channel. """
    if not event.rest: event.missing("<plugin name>") ; return
    if not event.rest in event.chan.data.denyplug:
        event.chan.data.denyplug.append(event.rest)
        event.chan.save()
        event.done()
    else: event.reply("%s is already being denied in channel %s" % (event.rest, event.channel))

cmnds.add("chan-denyplug", handle_chandenyplug, 'OPER')
examples.add("chan-denyplug", "deny a plugin command or callbacks to be executed in a channel", "chan-denyplug idle")
コード例 #9
0
ファイル: kickban.py プロジェクト: buzzworkers/tl
## callbacks

def handle_367(bot, ievent):
    logging.warn('kickban - 367 - %s' % str(ievent))
    channel = ievent.arguments[1].lower()
    if not bot.cfg.name in bans or not channel in bans[bot.cfg.name]:
        return # not requested by this plugin
    b = ievent.txt.split()[0]
    target = bans[bot.cfg.name][channel]
    if b not in target: target.append(b)

def handle_mode(bot, ievent):
    logging.debug('kick-ban - mode - %s' % ievent.tojson())
    # [18 Jan 2008 13:41:29] (mode) cmnd=MODE [email protected] postfix=#eth0-test +b *!*@je.moeder.ook arguments=[u'#eth0-test', u'+b', u'*!*@je.moeder.ook'] nick=maze user=wijnand [email protected] channel=#eth0-test txt= command= args=[] rest= speed=5 options={}

callbacks.add('367', handle_367)
callbacks.add('MODE', handle_mode)

## functions

def get_bans(bot, channel):
    # :ironforge.sorcery.net 367 basla #eth0 *!*@71174af5.e1d1a3cf.net.hmsk [email protected] 1200657224
    # :ironforge.sorcery.net 367 basla #eth0 *!*@6ca5f0a3.14055a38.89.123.imsk [email protected] 1200238584
    # :ironforge.sorcery.net 368 basla #eth0 :End of Channel Ban List
    if bot.type != "irc": return []
    global bans
    channel = channel.lower()
    if not bot.cfg.name in bans:
        bans[bot.cfg.name] = {}
    bans[bot.cfg.name][channel] = []
    queue368 = queue.Queue()
コード例 #10
0
ファイル: persist.py プロジェクト: buzzworkers/tl
        result = list(self.objects().values())
        result.sort(key=lambda i: i.data.created)
        return iter(result)

## PlugPersistCollection class

class PlugPersistCollection(PersistCollection):

    def __init__(self):
        plugname = calledfrom(sys._getframe())
        self.path =  getdatadir() + os.sep + 'plugs' + os.sep + stripname(plugname) + os.sep
        PersistCollection.__init__(self, self.path)

## TimedPersistCollection class

class TimedPersistCollection(PersistCollection):

    def __init__(self, ddir):
        plugname = calledfrom(sys._getframe())
        PersistCollection.__init__(self, ddir)

## GlobalPersistCollection class

class GlobalPersistCollection(PersistCollection):

    def __init__(self):
        self.path =  getdatadir() + os.sep + 'globals'
        GlobalCollection(self, self.path)

callbacks.add("TICK60", cleanup)
コード例 #11
0
ファイル: irccat.py プロジェクト: buzzworkers/tl
        dest = dest.split(",")
        finalDest = []
        for d in dest:
            if not d: continue
            d = d.strip().strip("@")
            finalDest.append(d)
            if d in list(cfg["aliases"].keys()):
                for alias in cfg["aliases"][d]:
                    finalDest.append(alias)
        return finalDest, message

## load on START

def irccatstart(bot, event): pass

callbacks.add("START", irccatstart)

## plugin init

def init_threaded():
    global server
    if server: logging.warn("irccat server is already running.") ; return
    if not cfg.enable: logging.warn("irccat is not enabled.") ; return 
    time.sleep(2)
    if not cfg.host or not cfg.port:
        cfg["host"] = "localhost"
        cfg["port"] = 54321
        cfg["botnames"] = ["default-sxmpp",]
        cfg["aliases"] = {}
    if not cfg.aliases: cfg.aliases = {}
    cfg.save()
コード例 #12
0
ファイル: periodical.py プロジェクト: buzzworkers/tl
    def wrapper(*args, **kw):
        job = JobInterval(3600, 0, function, *args, **kw)
        job.group = group
        job.description = whichmodule()
        logging.warn('new interval job %d running hourly' % job.id())
        periodical.jobs.append(job)

    return wrapper

def daily(function):
    """ day decorator. """
    logging.warn('@daily(%s)' % str(function))
    daily.__dict__ = function.__dict__
    group = calledfrom(sys._getframe())

    def wrapper(*args, **kw):
        job = JobInterval(86400, 0, function, *args, **kw)
        job.group =  group
        job.description = whichmodule()
        periodical.jobs.append(job)
        logging.warb('new interval job %d running daily' % job.id())

    return wrapper

periodical = Periodical()

callbacks.add("TICK", periodical.looponce)

def size():
    return periodical.size()
コード例 #13
0
ファイル: bugtracker.py プロジェクト: buzzworkers/tl
def init():
    callbacks.add('PRIVMSG', bugtrackers.cb_privmsg)
コード例 #14
0
ファイル: underauth.py プロジェクト: buzzworkers/tl
## copyright

__copyright__ = "this file is in the public domain"
__author__ = "*****@*****.**"

## tl imports

from tl.lib.callbacks import callbacks

##  pre_underauth_cb precondition


def pre_underauth_cb(bot, ievent):
    """ check if undernet auth in necessary. """
    args = ievent.arguments
    try:
        return args[0] == "AUTH" and args[-3] == "/QUOTE" and args[-2] == "PASS"
    except Exception as ex:
        return False


## underauth_cb callback


def underauth_cb(bot, ievent):
    """ Send the raw command to the server. """
    bot._raw(" ".join(ievent.arguments[-2:]))


callbacks.add("NOTICE", underauth_cb, pre_underauth_cb)
コード例 #15
0
ファイル: ask.py プロジェクト: buzzworkers/tl
                askbot.say(channel, "%s says: %s" % (event.userhost, txt))
        else:
            logging.warn("ask - can't find %s bot in fleet" % type)
            continue
        try:
            questions.data[event.userhost].remove([botname, type, userhost, channel])
            questions.save()
        except ValueError:
            pass
        done.append(channel)
        break
    if done:
        event.reply("answer sent to ", done)


callbacks.add("MESSAGE", askcallback, askprecondition)
callbacks.add("DISPATCH", askcallback, askprecondition)
callbacks.add("WEB", askcallback, askprecondition)
callbacks.add("CONVORE", askcallback, askprecondition)
callbacks.add("PRIVMSG", askcallback, askprecondition)

## ask command


def handle_ask(bot, event):
    """ 
        arguments: <subject> <question> - this command lets you ask a question that gets dispatched to jabber 
        users that have registered themselves for that particular subject. 

    """
    try:
コード例 #16
0
ファイル: remind.py プロジェクト: buzzworkers/tl
## defines

remind = Remind('remind.data')
assert remind

## callbacks

def preremind(bot, ievent):
    """ remind precondition """
    return remind.wouldremind(ievent.userhost)

def remindcb(bot, ievent):
    """ remind callbacks """
    remind.remind(bot, ievent.userhost)

callbacks.add('PRIVMSG', remindcb, preremind, threaded=True)
callbacks.add('JOIN', remindcb, preremind, threaded=True)
callbacks.add('MESSAGE', remindcb, preremind, threaded=True)
callbacks.add('WEB', remindcb, preremind, threaded=True)
callbacks.add('TORNADO', remindcb, preremind, threaded=True)

## remind command

def handle_remind(bot, ievent):
    """ arguments: <nick> <txt>  - add a remind for a user, as soon as he/she gets online or says something the txt will be send. """
    try: who = ievent.args[0] ; txt = ' '.join(ievent.args[1:])
    except IndexError: ievent.missing('<nick> <txt>') ; return
    if not txt: ievent.missing('<nick> <txt>') ; return
    userhost = getwho(bot, who)
    if not userhost: ievent.reply("can't find userhost for %s" % who) ; return
    else:
コード例 #17
0
ファイル: chatlog.py プロジェクト: buzzworkers/tl
def init():
    """ called upon plugin registration. """
    global stopped
    stopped = False
    global loggers
    for (botname, channel) in cfg.get("channels"):
        enablelogging(botname, channel)  
    callbacks.add("PRIVMSG", chatlogcb, prechatlogcb)
    callbacks.add("JOIN", chatlogcb, prechatlogcb)
    callbacks.add("PART", chatlogcb, prechatlogcb)
    callbacks.add("NOTICE", chatlogcb, prechatlogcb)
    callbacks.add("QUIT", chatlogcb, prechatlogcb)
    callbacks.add("NICK", chatlogcb, prechatlogcb)
    callbacks.add("PRESENCE", chatlogcb, prechatlogcb)
    callbacks.add("MESSAGE", chatlogcb, prechatlogcb)
    callbacks.add("CONSOLE", chatlogcb, prechatlogcb)
    callbacks.add("CONVORE", chatlogcb, prechatlogcb)
    first_callbacks.add("OUTPUT", chatlogcb, prechatlogcb)
    return 1
コード例 #18
0
ファイル: infoitem.py プロジェクト: buzzworkers/tl
    """ return number of infoitems """
    return info.size()

## info callbacks

def infopre(bot, ievent):
    """ see if info callback needs to be called """
    if ievent.iscmnd() and (ievent.txt and ievent.txt[-1] == "?") and not ievent.woulddispatch(): return True

def infocb(bot, ievent):
    """ implement a !infoitem callback """
    if users.allowed(ievent.userhost, 'USER'):
        data = info.get(ievent.txt)
        if data: ievent.reply('%s is: ' % ievent.txt, data)

callbacks.add('PRIVMSG', infocb, infopre)

## info-size command

def handle_infosize(bot, ievent):
    """ info-size .. show number of information items """
    ievent.reply("we have %s infoitems" % info.size())

cmnds.add('info-size', handle_infosize, ['USER', 'WEB', 'ANON'])
examples.add('info-size', 'show number of infoitems', 'info-size')

## addinfoitem RE

def handle_addinfoitem(bot, ievent):
    """ <keyword> = <description> .. add information item """
    try: (what, description) = ievent.groups
コード例 #19
0
ファイル: nickserv.py プロジェクト: buzzworkers/tl
        self.identify(bot)
        try:
            for i in self.data[bot.cfg.name]['nickservtxt']:
                self.sendstring(bot, i)
                logging.warn('nickserv - sent %s' % i)
        except: pass

## init stuff

nsauth = NSAuth()
if not nsauth.data:
    nsauth = NSAuth()

## register callback

callbacks.add('001', nsauth.handle_001, threaded=True)

## ns-add command

def handle_nsadd(bot, ievent):
    """ arguments: <password> [<nickserv nick>] [<identify command>] - add a bot to the nickserv. """
    if bot.jabber: return
    if len(ievent.args) < 1:
        ievent.missing('<password> [<nickserv nick>] [<identify command>]')
        return
    if nsauth.has(bot): ievent.reply('replacing previous configuration')
    options = {}
    if len(ievent.args) >= 1: options.update({'password': ievent.args[0]})
    if len(ievent.args) >= 2: options.update({'nickserv': ievent.args[1]})
    if len(ievent.args) >= 3: options.update({'identify': ' '.join(ievent.args[2:])})
    nsauth.add(bot, **options)
コード例 #20
0
ファイル: nickcapture.py プロジェクト: buzzworkers/tl
# tl/plugs/core/nickcapture.py
#
#
""" nick recapture callback. """

## tl imports

from tl.lib.callbacks import callbacks

## callbacks


def ncaptest(bot, ievent):
    """ test if user is splitted. """
    if '*.' in ievent.txt or bot.cfg.server in ievent.txt: return 0
    ievent.bind()
    if bot.cfg.wantnick and bot.cfg.wantnick.lower() == ievent.nick.lower():
        return 1
    if bot.cfg.nick.lower() == ievent.nick.lower(): return 1
    return 0


def ncap(bot, ievent):
    """ recapture the nick. """
    bot.donick(bot.cfg.wantnick or bot.cfg.nick)


callbacks.add('QUIT', ncap, ncaptest, threaded=True)
コード例 #21
0
ファイル: jira.py プロジェクト: buzzworkers/tl
    if fnd:
        ticket = fnd.group(1)
        prefix = fnd.group(2)
        if not ticket: logging.warn("ticket missing: %s" % str(fnd)) ; return
        if not prefix: logging.warn("prefix missing: %s" % str(fnd)) ; return
        logging.info("Found: %s %s" % (ticket, prefix))
        logging.info("servers: %s" % cfg.data["servers"])
        try: server = serversForPrefix[prefix]
        except KeyError: return
        logging.warn("server is %s" % server)
        msg = getJiraIssueMessage(cfg.data["servers"][server], ticket)
        for line in msg:
            bot.say(ievent.channel, line)


callbacks.add('PRIVMSG', doLookup, containsJiraTag, threaded=True)
callbacks.add('CONSOLE', doLookup, containsJiraTag, threaded=True)
callbacks.add('MESSAGE', doLookup, containsJiraTag, threaded=True)
callbacks.add('DISPATCH', doLookup, containsJiraTag, threaded=True)
callbacks.add('TORNADO', doLookup, containsJiraTag, threaded=True)

## add_jira_server command

def handle_add_jira_server(bot, ievent):
    """ configure a new jira server; syntax: add_jira_server [server name] [url] [username] [password] """
    if len(ievent.args) != 4:
        ievent.reply("syntax: add_jira_server [server name] [url] [username] [password]")
        return

    server = {
        "name": ievent.args[0],
コード例 #22
0
ファイル: urlinfo.py プロジェクト: buzzworkers/tl
## callbacks

def catchHasUrls(bot, ievent):
    """ catch channel chat for possible URLs. """
    if ievent.how == "background": return 0
    if ievent.channel in cfg.data and cfg.data[ievent.channel]:
        if len(ievent.txt) >= 5:
            if (ievent.txt.find('www.') != -1) or (ievent.txt.find('http') != -1): return 1
    return 0  


def catchUrls(bot, ievent):
    """ the urlinfo callback. """
    bot.say(ievent.channel, getUrlInfo(ievent.txt))

callbacks.add('PRIVMSG', catchUrls, catchHasUrls, threaded=True)
callbacks.add('CONSOLE', catchUrls, catchHasUrls, threaded=True)
callbacks.add('MESSAGE', catchUrls, catchHasUrls, threaded=True)
callbacks.add('DISPATCH', catchUrls, catchHasUrls, threaded=True)
callbacks.add('TORNADO', catchUrls, catchHasUrls, threaded=True)

## urlinfo-enable command

def handle_urlinfo_enable(bot, ievent):
    """ no arguments - enable urlinfo in a channel. """
    cfg.data[ievent.channel] = True
    cfg.save()
    ievent.reply('urlinfo enabled')

cmnds.add('urlinfo-enable', handle_urlinfo_enable, ['OPER'])
examples.add('urlinfo-enable', 'enable urlinfo in the channel', 'urlinfo-enable')
コード例 #23
0
ファイル: autovoice.py プロジェクト: buzzworkers/tl
## autovoice callbacks

def preautovoice(bot, ievent):
    if ievent.forwarded or ievent.relayed: return False
    return True

def cbautovoice(bot, ievent):
    """ autovoice callback """
    chandata = 0
    if not ievent.chan: ievent.bind(bot, force=True)
    try: chandata = ievent.chan.data.autovoice
    except KeyError: return
    if chandata: bot.voice(ievent.channel, ievent.nick)

callbacks.add('JOIN', cbautovoice, preautovoice)

## autovoice-on command

def handle_autovoiceon(bot, ievent):
    """ autovoice-on .. enable autovoice for channel the command was given in """
    try: ievent.chan.data.autovoice  = 1
    except TypeError: ievent.reply('no %s in channel database' % ievent.channel) ; return
    ievent.reply('autovoice enabled on %s' % ievent.channel)

cmnds.add('autovoice-on', handle_autovoiceon, 'OPER')
examples.add('autovoice-on', 'enable autovoice on channel in which the command is given', 'autovoice-on')

## autovoice-off command

def handle_autovoiceoff(bot, ievent):
コード例 #24
0
ファイル: runner.py プロジェクト: buzzworkers/tl
        
## global runners

cmndrunner = defaultrunner = Runners("cmnd", 75, BotEventRunner) 
longrunner = Runners("long", 50, LongRunner)
callbackrunner = Runners("callback", 20, BotEventRunner)
waitrunner = Runners("wait", 20, BotEventRunner)
apirunner = Runners("api", 10, BotEventRunner)
threadrunner = Runners("thread", 50, Runner)
urlrunner = Runners("url", 50, Runner)
speechrunner = Runners("speech", 20, BotEventRunner)

allrunners = [speechrunner, cmndrunner, longrunner, callbackrunner, waitrunner, apirunner, threadrunner, urlrunner]

## cleanup 

def runnercleanup(bot, event):
    speechrunner.cleanup()
    cmndrunner.cleanup()
    longrunner.cleanup()
    callbackrunner.cleanup()
    waitrunner.cleanup()
    apirunner.cleanup()
    threadrunner.cleanup()
    urlrunner.cleanup()

callbacks.add("TICK10", runnercleanup)

def size():
    return "cmnd: %s - callback: %s - wait: %s - long: %s - api: %s - thread: %s" % (cmndrunner.size(), callbackrunner.size(), waitrunner.size(), longrunner.size(), apirunner.size(), threadrunner.size())
コード例 #25
0
ファイル: overflow.py プロジェクト: buzzworkers/tl
def init_threaded():
    try:
        if cfg.enable: sync() ; scan()
    except URLNotEnabled: logging.error("URL fetching is not enabled")

## plugin shutdown

def shutdown():
    periodical.kill()

## make sure plugin gets autoloaded on start

def dummycb(bot, event): pass

callbacks.add("START", dummycb)


## geturls function

def geturls(txt):
    result = []
    if "http://" in txt or "https://" in txt:
        for item in re_url_match.findall(txt):
            logging.debug("web - raw - found url - %s" % item)
            try: txt = txt.replace(item, '')
            except ValueError:  logging.error("web - invalid url - %s" % url)
            i = item
            if i.endswith('"'): i = i[:-1]
            if i.endswith('")'): i = i[:-2]
            result.append(i)
コード例 #26
0
ファイル: url.py プロジェクト: buzzworkers/tl
def urlcb(bot, ievent):
    if not state: return 
    try:
        test_urls = re_url_match.findall(ievent.txt)
        for i in test_urls:
            if bot.cfg.name not in state['urls']:
                state['urls'][bot.cfg.name] = {}
            if ievent.channel not in state['urls'][bot.cfg.name]:
                state['urls'][bot.cfg.name][ievent.channel] = []
            if not i in state['urls'][bot.cfg.name][ievent.channel]:
                state['urls'][bot.cfg.name][ievent.channel].append(i)  
        state.save()
        logging.warn("added url from %s" % ievent.auth)
    except Exception as ex: handle_exception()

callbacks.add('CONSOLE', urlcb, urlpre, threaded=True)
callbacks.add('PRIVMSG', urlcb, urlpre, threaded=True)
callbacks.add('MESSAGE', urlcb, urlpre, threaded=True)
callbacks.add('TORNADO', urlcb, urlpre, threaded=True)

## url-search command

def handle_urlsearch(bot, ievent):
    """ arguments: <searchtxt> - search the per channel url database for a search term. """
    if not state: ievent.reply('rss state not initialized') ; return
    if not ievent.rest: ievent.missing('<searchtxt>') ; return
    result = []
    try:
        for i in state['urls'][bot.cfg.name][ievent.channel]:
            if ievent.rest in i: result.append(i)
    except KeyError: ievent.reply('no urls known for channel %s' % ievent.channel) ; return