2014-09-28 18:03:08 +02:00
#!/usr/bin/python3
2014-09-27 03:40:27 +02:00
# -*- coding: utf-8 -*-
if ' __main__ ' == __name__ :
2014-09-28 18:03:08 +02:00
print ( ''' this is a plugin file, which is not meant to be executed ''' )
2014-09-27 03:40:27 +02:00
exit ( - 1 )
2015-02-05 00:48:02 +01:00
import time , random , unicodedata , re , sys , urllib . request , json
2015-02-05 19:00:38 +01:00
import types
2015-02-05 19:23:05 +01:00
import traceback
2015-02-06 13:19:14 +01:00
import urllib . parse
2014-12-14 03:41:57 +01:00
from local_config import conf , set_conf
2014-09-27 09:19:46 +02:00
from common import *
2015-07-19 03:03:39 +02:00
from string_constants import excuses , moin_strings_hi , moin_strings_bye , cakes
2014-11-09 16:52:22 +01:00
from urlbot import extract_title
2015-02-06 01:21:53 +01:00
from functools import wraps
2015-02-05 23:13:45 +01:00
2015-06-21 00:56:33 +02:00
ptypes_PARSE = ' parser '
ptypes_COMMAND = ' command '
2015-02-08 22:18:07 +01:00
ptypes = [ ptypes_PARSE , ptypes_COMMAND ]
2014-09-27 03:40:27 +02:00
2014-09-29 19:15:00 +02:00
joblist = [ ]
2015-02-05 23:34:44 +01:00
plugins = { p : [ ] for p in ptypes }
2014-09-27 05:32:35 +02:00
2015-06-20 14:18:50 +02:00
got_hangup = False
2015-07-03 01:19:47 +02:00
def plugin_enabled_get ( plugin ) :
2015-07-03 01:34:35 +02:00
blob = conf_load ( )
if ' plugin_conf ' in blob :
if plugin . plugin_name in blob [ ' plugin_conf ' ] :
return blob [ ' plugin_conf ' ] [ plugin . plugin_name ] . get (
' enabled ' , plugin . is_enabled
)
2015-07-03 01:19:47 +02:00
return plugin . is_enabled
def plugin_enabled_set ( plugin , enabled ) :
2015-07-03 01:34:35 +02:00
if conf ( ' persistent_locked ' ) :
log . warn ( " couldn ' t get exclusive lock " )
return False
set_conf ( ' persistent_locked ' , True )
blob = conf_load ( )
if ' plugin_conf ' not in blob :
blob [ ' plugin_conf ' ] = { }
if not plugin . plugin_name in blob [ ' plugin_conf ' ] :
blob [ ' plugin_conf ' ] [ plugin . plugin_name ] = { }
blob [ ' plugin_conf ' ] [ plugin . plugin_name ] [ ' enabled ' ] = enabled
conf_save ( blob )
set_conf ( ' persistent_locked ' , False )
return True
2015-07-03 01:19:47 +02:00
2015-02-05 23:13:45 +01:00
def pluginfunction ( name , desc , plugin_type , ratelimit_class = RATE_GLOBAL , enabled = True ) :
2015-02-09 03:46:17 +01:00
''' A decorator to make a plugin out of a function '''
2015-02-05 23:13:45 +01:00
if plugin_type not in ptypes :
2015-02-09 03:46:17 +01:00
raise TypeError ( ' Illegal plugin_type: %s ' % plugin_type )
2015-02-05 23:13:45 +01:00
def decorate ( f ) :
f . is_plugin = True
2015-02-06 12:47:27 +01:00
f . is_enabled = enabled
2015-02-05 23:13:45 +01:00
f . plugin_name = name
f . plugin_desc = desc
f . plugin_type = plugin_type
f . ratelimit_class = ratelimit_class
return f
return decorate
2014-09-29 19:15:00 +02:00
def register_event ( t , callback , args ) :
joblist . append ( ( t , callback , args ) )
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' mental_ill ' , ' parse mental illness ' , ptypes_PARSE , ratelimit_class = RATE_NO_SILENCE | RATE_GLOBAL )
2015-02-05 23:47:07 +01:00
def parse_mental_ill ( * * args ) :
2014-09-27 03:40:27 +02:00
min_ill = 3
c = 0
flag = False
# return True for min_ill '!' in a row
for d in args [ ' data ' ] :
if ' ! ' == d or ' ? ' == d :
c + = 1
else :
c = 0
if ( min_ill < = c ) :
flag = True
break
if True == flag :
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent mental illness reply ' )
2014-09-27 03:40:27 +02:00
return {
2014-09-27 05:32:35 +02:00
' msg ' : ''' Multiple exclamation/question marks are a sure sign of mental disease, with %s as a living example. ''' % args [ ' reply_user ' ]
2014-09-27 03:40:27 +02:00
}
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' debbug ' , ' parse Debian bug numbers ' , ptypes_PARSE , ratelimit_class = RATE_NO_SILENCE | RATE_GLOBAL )
2015-02-05 23:47:07 +01:00
def parse_debbug ( * * args ) :
2014-11-09 16:52:22 +01:00
bugs = re . findall ( r ' #( \ d { 4,}) ' , args [ ' data ' ] )
if not bugs :
return None
2015-06-09 14:56:29 +02:00
out = [ ]
for b in bugs :
2015-06-21 00:50:42 +02:00
log . plugin ( ' detected Debian bug # %s ' % b )
2015-06-09 14:56:29 +02:00
url = ' https://bugs.debian.org/cgi-bin/bugreport.cgi?bug= %s ' % b
status , title = extract_title ( url )
if 0 == status :
out . append ( ' Debian Bug: %s : %s ' % ( title , url ) )
elif 3 == status :
out . append ( ' error for # %s : %s ' % ( b , title ) )
else :
2015-07-19 02:07:03 +02:00
log . plugin ( ' unknown status %d ' % status )
2014-11-09 16:52:22 +01:00
return {
2015-06-09 14:56:29 +02:00
' msg ' : out
2014-11-09 16:52:22 +01:00
}
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' cve ' , ' parse a CVE handle ' , ptypes_PARSE , ratelimit_class = RATE_NO_SILENCE | RATE_GLOBAL )
2015-02-05 23:47:07 +01:00
def parse_cve ( * * args ) :
2014-12-01 17:50:24 +01:00
cves = re . findall ( r ' (CVE- \ d \ d \ d \ d- \ d+) ' , args [ ' data ' ] . upper ( ) )
if not cves :
return None
2015-06-21 00:50:42 +02:00
log . plugin ( ' detected CVE handle ' )
2014-12-01 17:50:24 +01:00
return {
2015-06-14 16:52:32 +02:00
' msg ' : [ ' https://security-tracker.debian.org/tracker/ %s ' % c for c in cves ]
2014-12-01 17:50:24 +01:00
}
2015-06-14 16:50:40 +02:00
@pluginfunction ( ' dsa ' , ' parse a DSA handle ' , ptypes_PARSE , ratelimit_class = RATE_NO_SILENCE | RATE_GLOBAL )
def parse_dsa ( * * args ) :
dsas = re . findall ( r ' (DSA- \ d \ d \ d \ d- \ d+) ' , args [ ' data ' ] . upper ( ) )
if not dsas :
return None
2015-06-21 00:50:42 +02:00
log . plugin ( ' detected DSA handle ' )
2015-06-14 16:50:40 +02:00
return {
2015-06-14 16:52:32 +02:00
' msg ' : [ ' https://security-tracker.debian.org/tracker/ %s ' % d for d in dsas ]
2015-06-14 16:50:40 +02:00
}
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' skynet ' , ' parse skynet ' , ptypes_PARSE )
2015-02-05 23:47:07 +01:00
def parse_skynet ( * * args ) :
2014-09-27 05:32:35 +02:00
if ' skynet ' in args [ ' data ' ] . lower ( ) :
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent skynet reply ' )
2014-09-27 05:32:35 +02:00
return {
' msg ' : ''' I ' m an independent bot and have nothing to do with other artificial intelligence systems! '''
}
2014-09-27 03:40:27 +02:00
2015-06-21 23:00:16 +02:00
@pluginfunction ( ' moin ' , ' parse hi/bye ' , ptypes_PARSE )
def parse_moin ( * * args ) :
for direction in [ moin_strings_hi , moin_strings_bye ] :
2015-06-17 10:53:44 +02:00
for d in direction :
2015-06-17 11:17:29 +02:00
words = re . split ( r ' \ W+ ' , args [ ' data ' ] )
# assumption: longer sentences are not greetings
if 3 < len ( args [ ' data ' ] . split ( ) ) :
continue
for w in words :
if d . lower ( ) == w . lower ( ) :
2015-06-21 01:35:56 +02:00
if args [ ' reply_user ' ] in conf ( ' moin-disabled-user ' ) :
log . plugin ( ' moin blacklist match ' )
return
2015-06-18 13:36:57 +02:00
if args [ ' reply_user ' ] in conf ( ' moin-modified-user ' ) :
2015-06-21 00:50:42 +02:00
log . plugin ( ' being " quiet " for %s ' % w )
2015-06-18 13:36:57 +02:00
return {
' msg ' : ' /me %s ' % random . choice ( [
" doesn ' t say anything at all " ,
' whistles uninterested ' ,
' just ignores this incident '
] )
}
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent %s reply for %s ' % (
2015-06-21 23:00:16 +02:00
' hi ' if direction is moin_strings_hi else ' bye ' , w
2015-06-17 11:17:29 +02:00
) )
return {
' msg ' : ''' %s , %s ''' % (
random . choice ( direction ) ,
args [ ' reply_user ' ]
)
}
2015-06-17 10:53:44 +02:00
2015-02-08 22:59:34 +01:00
@pluginfunction ( ' latex ' , r ' reacts on \ LaTeX ' , ptypes_PARSE )
2015-02-09 03:46:17 +01:00
def parse_latex ( * * args ) :
2015-02-08 22:59:34 +01:00
if r ' \ LaTeX ' in args [ ' data ' ] :
return {
' msg ' : ''' LaTeX is way too complex for me, I ' m happy with fmt(1) '''
}
2015-06-18 14:05:44 +02:00
@pluginfunction ( ' me-action ' , ' reacts to /me.* % {bot_user} ' , ptypes_PARSE )
2015-02-22 20:15:23 +01:00
def parse_slash_me ( * * args ) :
if args [ ' data ' ] . lower ( ) . startswith ( ' /me ' ) and ( conf ( ' bot_user ' ) in args [ ' data ' ] . lower ( ) ) :
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent /me reply ' )
2015-02-22 20:15:23 +01:00
me_replys = [
' are you that rude to everybody? ' ,
' oh, thank you... ' ,
' do you really think that was nice? ' ,
' that sounds very interesting... ' ,
" excuse me, but I ' m already late for an appointment "
]
return {
2015-06-18 13:51:50 +02:00
' msg ' : args [ ' reply_user ' ] + ' : %s ' % random . choice ( me_replys )
2015-02-22 20:15:23 +01:00
}
2015-02-08 22:59:34 +01:00
#@pluginfunction('dummy_parser', 'dummy_parser desc', ptypes_PARSE)
#def parse_skynet(**args):
# if 'dummy_parser' in args['data'].lower():
2015-06-21 00:50:42 +02:00
# log.plugin('dummy_parser triggered')
2015-02-08 22:59:34 +01:00
# return {
# 'msg': 'dummy_parser triggered'
# }
2014-12-13 22:46:23 +01:00
def data_parse_other ( msg_obj ) :
data = msg_obj [ ' body ' ]
reply_user = msg_obj [ ' mucnick ' ]
2014-09-27 03:40:27 +02:00
2015-02-08 22:18:07 +01:00
for p in plugins [ ptypes_PARSE ] :
2015-02-05 23:47:07 +01:00
if ratelimit_exceeded ( p . ratelimit_class ) :
2014-09-27 05:32:35 +02:00
continue
2014-09-27 03:40:27 +02:00
2015-07-03 01:19:47 +02:00
if not plugin_enabled_get ( p ) :
2015-06-18 14:02:34 +02:00
continue
2015-02-05 23:47:07 +01:00
ret = p ( reply_user = reply_user , data = data )
2014-09-27 05:32:35 +02:00
if None != ret :
2014-09-28 18:03:08 +02:00
if ' msg ' in list ( ret . keys ( ) ) :
2014-09-27 05:51:18 +02:00
ratelimit_touch ( RATE_CHAT )
2014-12-13 22:46:23 +01:00
send_reply ( ret [ ' msg ' ] , msg_obj )
2014-09-27 03:40:27 +02:00
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' help ' , ' print help for a command or all known commands ' , ptypes_COMMAND )
def command_help ( argv , * * args ) :
2015-02-06 01:21:53 +01:00
command = argv [ 0 ]
what = argv [ 1 ] if len ( argv ) > 1 else None
2015-01-03 19:04:01 +01:00
if ' help ' != command :
2014-12-16 08:48:03 +01:00
return
2014-09-27 16:15:01 +02:00
2015-01-03 19:04:01 +01:00
if None == what :
2015-06-21 00:50:42 +02:00
log . plugin ( ' empty help request, sent all commands ' )
2015-02-08 22:37:27 +01:00
commands = args [ ' cmd_list ' ]
commands . sort ( )
2015-06-18 14:02:34 +02:00
parsers = args [ ' parser_list ' ]
parsers . sort ( )
2015-01-03 19:04:01 +01:00
return {
2015-06-18 14:02:34 +02:00
' msg ' : [
' %s : known commands: %s ' % (
2015-07-02 13:55:30 +02:00
args [ ' reply_user ' ] , ' , ' . join ( commands )
2015-06-18 14:02:34 +02:00
) ,
2015-07-02 13:55:30 +02:00
' known parsers: %s ' % ' , ' . join ( parsers )
2015-06-18 14:02:34 +02:00
]
2014-09-27 05:32:35 +02:00
}
2015-06-18 14:02:34 +02:00
flag = False
2015-06-18 14:09:29 +02:00
for p in plugins [ ptypes_COMMAND ] + plugins [ ptypes_PARSE ] :
2015-02-06 01:21:53 +01:00
if what == p . plugin_name :
2015-06-18 14:02:34 +02:00
flag = True
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent help for %s ' % what )
2014-09-27 16:06:26 +02:00
return {
2015-07-02 13:55:30 +02:00
' msg ' : args [ ' reply_user ' ] + ' : help for %s %s %s : %s ' % (
2015-07-03 01:19:47 +02:00
' enabled ' if plugin_enabled_get ( p ) else ' disabled ' ,
2015-06-18 14:09:29 +02:00
' parser ' if p . plugin_type == ptypes_PARSE else ' command ' ,
2015-02-06 01:21:53 +01:00
what , p . plugin_desc
2015-01-03 19:04:01 +01:00
)
2014-09-27 16:06:26 +02:00
}
2015-06-18 14:02:34 +02:00
if not flag :
2015-06-21 00:50:42 +02:00
log . plugin ( ' no help found for %s ' % what )
2015-06-18 14:02:34 +02:00
return {
' msg ' : args [ ' reply_user ' ] + ' : no such command: %s ' % what
}
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' version ' , ' prints version ' , ptypes_COMMAND )
def command_version ( argv , * * args ) :
2015-02-06 01:21:53 +01:00
if ' version ' != argv [ 0 ] :
2014-12-16 08:48:03 +01:00
return
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent version string ' )
2014-12-16 08:48:03 +01:00
return {
' msg ' : args [ ' reply_user ' ] + ( ''' : I ' m running ''' + VERSION )
}
2014-09-27 05:32:35 +02:00
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' klammer ' , ' prints an anoying paper clip aka. Karl Klammer ' , ptypes_COMMAND )
def command_klammer ( argv , * * args ) :
2015-02-06 01:21:53 +01:00
if ' klammer ' != argv [ 0 ] :
2014-12-16 08:48:03 +01:00
return
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent karl klammer ' )
2014-12-16 08:48:03 +01:00
return {
' msg ' : (
args [ ' reply_user ' ] + ' , ' ,
r ''' _, Was moechten ''' ,
r ''' ( _ \ _ Sie tun? ''' ,
r ''' \ 0 O \ ''' ,
r ''' \ \ \ \ [ ] ja ''' ,
r ''' \ ` ' ) [ ] noe ''' ,
r ''' ` ' ' '''
)
}
2014-11-17 19:49:02 +01:00
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' unikot ' , ' prints an unicode string ' , ptypes_COMMAND )
def command_unicode ( argv , * * args ) :
2015-02-06 01:21:53 +01:00
if ' unikot ' != argv [ 0 ] :
2014-12-16 08:48:03 +01:00
return
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent some unicode ' )
2014-12-16 08:48:03 +01:00
return {
' msg ' : (
args [ ' reply_user ' ] + ''' , here ' s some ''' ,
''' ┌────────┐ ''' ,
''' │Unicode!│ ''' ,
''' └────────┘ '''
)
}
2014-09-27 03:40:27 +02:00
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' source ' , ' prints git URL ' , ptypes_COMMAND )
def command_source ( argv , * * args ) :
2015-02-06 01:21:53 +01:00
if not argv [ 0 ] in ( ' source ' , ' src ' ) :
2014-12-16 08:48:03 +01:00
return
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent source URL ' )
2014-12-16 08:48:03 +01:00
return {
' msg ' : ' My source code can be found at %s ' % conf ( ' src-url ' )
}
2014-09-27 05:32:35 +02:00
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' dice ' , ' rolls a dice, optional N times ' , ptypes_COMMAND , ratelimit_class = RATE_INTERACTIVE )
2015-02-06 01:21:53 +01:00
def command_dice ( argv , * * args ) :
if ' dice ' != argv [ 0 ] :
2014-12-16 08:48:03 +01:00
return
2014-09-27 03:40:27 +02:00
2014-12-20 17:02:26 +01:00
count = 0
try :
2015-02-06 01:21:53 +01:00
count = 1 if len ( argv ) < 2 else int ( argv [ 1 ] )
2014-12-20 17:02:26 +01:00
except ValueError as e :
return {
' msg ' : ' %s : dice: error when parsing int( %s ): %s ' % (
2015-02-06 01:21:53 +01:00
args [ ' reply_user ' ] , argv [ 1 ] , str ( e )
2014-12-20 17:02:26 +01:00
)
}
if 0 > = count or 5 < = count :
return {
' msg ' : ' %s : dice: invalid arguments (0 < N < 5) ' % args [ ' reply_user ' ]
}
2014-12-20 17:10:26 +01:00
dice_char = [ ' ◇ ' , ' ⚀ ' , ' ⚁ ' , ' ⚂ ' , ' ⚃ ' , ' ⚄ ' , ' ⚅ ' ]
msg = ' rolling %s for %s : ' % (
' a dice ' if 1 == count else ' %d dices ' % count , args [ ' reply_user ' ]
)
for i in range ( count ) :
rnd = 0
if args [ ' reply_user ' ] in conf ( ' enhanced-random-user ' ) :
rnd = 0 # this might confuse users. good.
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent random (enhanced) ' )
2014-12-20 17:10:26 +01:00
else :
rnd = random . randint ( 1 , 6 )
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent random ' )
2014-12-20 17:10:26 +01:00
2015-02-24 16:51:43 +01:00
# the \u200b chars ('ZERO WIDTH SPACE') avoid interpreting stuff as smileys
# by some strange clients
msg + = ' %s ( \u200b %d \u200b ) ' % ( dice_char [ rnd ] , rnd )
2014-12-20 17:02:26 +01:00
2014-12-16 08:48:03 +01:00
return {
2014-12-20 17:10:26 +01:00
' msg ' : msg
2014-12-16 08:48:03 +01:00
}
2014-09-27 03:40:27 +02:00
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' uptime ' , ' prints uptime ' , ptypes_COMMAND )
2015-02-06 01:21:53 +01:00
def command_uptime ( argv , * * args ) :
if ' uptime ' != argv [ 0 ] :
2014-12-16 08:48:03 +01:00
return
2014-09-27 03:40:27 +02:00
2014-12-16 08:48:03 +01:00
u = int ( conf ( ' uptime ' ) + time . time ( ) )
plural_uptime = ' s '
plural_request = ' s '
2014-09-27 03:40:27 +02:00
2014-12-16 08:48:03 +01:00
if 1 == u :
plural_uptime = ' '
if 1 == conf ( ' request_counter ' ) :
plural_request = ' '
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent statistics ' )
2014-12-16 08:48:03 +01:00
return {
' msg ' : args [ ' reply_user ' ] + ( ''' : happily serving for %d second %s , %d request %s so far. ''' % ( u , plural_uptime , conf ( ' request_counter ' ) , plural_request ) )
}
2014-09-27 03:40:27 +02:00
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' ping ' , ' sends pong ' , ptypes_COMMAND , ratelimit_class = RATE_INTERACTIVE )
2015-02-06 01:21:53 +01:00
def command_ping ( argv , * * args ) :
if ' ping ' != argv [ 0 ] :
2014-12-16 08:48:03 +01:00
return
2014-09-27 03:40:27 +02:00
2014-12-16 08:48:03 +01:00
rnd = random . randint ( 0 , 3 ) # 1:4
if 0 == rnd :
msg = args [ ' reply_user ' ] + ''' : peng (You ' re dead now.) '''
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent pong (variant) ' )
2014-12-16 08:48:03 +01:00
elif 1 == rnd :
msg = args [ ' reply_user ' ] + ''' : I don ' t like you, leave me alone. '''
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent pong (dontlike) ' )
2014-12-16 08:48:03 +01:00
else :
msg = args [ ' reply_user ' ] + ''' : pong '''
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent pong ' )
2014-12-16 08:48:03 +01:00
return {
' msg ' : msg
}
2014-09-27 03:40:27 +02:00
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' info ' , ' prints info message ' , ptypes_COMMAND )
def command_info ( argv , * * args ) :
2015-02-06 01:21:53 +01:00
if ' info ' != argv [ 0 ] :
2014-12-16 08:48:03 +01:00
return
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent long info ' )
2014-12-16 08:48:03 +01:00
return {
2015-02-05 01:16:52 +01:00
' msg ' : args [ ' reply_user ' ] + ( ''' : I ' m a bot, my job is to extract <title> tags from posted URLs. In case I ' m annoying or for further questions, please talk to my master %s . I ' m rate limited and shouldn ' t post more than %d messages per %d seconds. To make me exit immediately, highlight me with ' hangup ' in the message (emergency only, please). For other commands, highlight me with ' help ' . ''' % ( conf ( ' bot_owner ' ) , conf ( ' hist_max_count ' ) , conf ( ' hist_max_time ' ) ) )
2014-12-16 08:48:03 +01:00
}
2014-09-27 03:40:27 +02:00
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' teatimer ' , ' sets a tea timer to $1 or currently %d seconds ' % conf ( ' tea_steep_time ' ) , ptypes_COMMAND )
def command_teatimer ( argv , * * args ) :
2015-02-06 01:21:53 +01:00
if ' teatimer ' != argv [ 0 ] :
2014-12-16 08:48:03 +01:00
return
2014-10-29 13:01:32 +01:00
2014-12-16 08:48:03 +01:00
steep = conf ( ' tea_steep_time ' )
2014-09-29 19:15:00 +02:00
2015-02-06 01:21:53 +01:00
if len ( argv ) > 1 :
2014-10-29 13:12:41 +01:00
try :
2015-02-06 01:21:53 +01:00
steep = int ( argv [ 1 ] )
2014-12-16 08:48:03 +01:00
except Exception as e :
2014-10-29 13:12:41 +01:00
return {
2014-12-16 08:48:03 +01:00
' msg ' : args [ ' reply_user ' ] + ' : error when parsing int( %s ): %s ' % (
2015-02-06 01:21:53 +01:00
argv [ 1 ] , str ( e )
2014-12-16 08:48:03 +01:00
)
2014-10-29 13:12:41 +01:00
}
2014-12-16 08:48:03 +01:00
ready = time . time ( ) + steep
2014-12-02 17:01:40 +01:00
2014-12-16 08:48:03 +01:00
try :
2015-06-21 00:50:42 +02:00
log . plugin ( ' tea timer set to %s ' % time . strftime ( ' %F . % T ' , time . localtime ( ready ) ) )
2014-12-16 08:48:03 +01:00
except ValueError as e :
2014-09-29 19:15:00 +02:00
return {
2014-12-16 08:48:03 +01:00
' msg ' : args [ ' reply_user ' ] + ' : time format error: ' + str ( e )
2014-09-29 19:15:00 +02:00
}
2014-12-16 08:48:03 +01:00
register_event ( ready , send_reply , ( args [ ' reply_user ' ] + ' : Your tea is ready! ' , args [ ' msg_obj ' ] ) )
return {
' msg ' : args [ ' reply_user ' ] + ' : Tea timer set to %s ' % time . strftime (
' %F . % T ' , time . localtime ( ready )
)
}
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' decode ' , ' prints the long description of an unicode character ' , ptypes_COMMAND )
def command_decode ( argv , * * args ) :
2015-02-06 01:21:53 +01:00
if ' decode ' != argv [ 0 ] :
2014-10-13 18:23:51 +02:00
return
2015-05-31 22:02:06 +02:00
if len ( argv ) < = 1 :
2014-10-13 18:23:51 +02:00
return {
2014-12-16 08:48:03 +01:00
' msg ' : args [ ' reply_user ' ] + ' : usage: decode { single character} '
2014-10-13 18:23:51 +02:00
}
2014-12-16 08:48:03 +01:00
2015-07-07 00:02:17 +02:00
log . plugin ( ' decode called for %s ' % argv [ 1 ] )
2014-12-16 08:48:03 +01:00
2015-07-07 00:02:17 +02:00
out = [ ]
for i , char in enumerate ( argv [ 1 ] ) :
if i > 9 :
out . append ( ' ... limit reached. ' )
break
char_esc = str ( char . encode ( ' unicode_escape ' ) ) [ 3 : - 1 ]
2015-07-07 00:32:05 +02:00
if 0 == len ( char_esc ) :
char_esc = ' '
else :
char_esc = ' ( %s ) ' % char_esc
2015-07-07 00:02:17 +02:00
try :
uni_name = unicodedata . name ( char )
except Exception as e :
log . plugin ( ' decode( %s ) failed: %s ' % ( char , e ) )
2015-07-07 00:32:05 +02:00
out . append ( " can ' t decode %s %s : %s " % ( char , char_esc , e ) )
2015-07-07 00:02:17 +02:00
continue
2015-07-07 00:32:05 +02:00
out . append ( ' %s %s is called " %s " ' % ( char , char_esc , uni_name ) )
2015-07-07 00:02:17 +02:00
if 1 == len ( out ) :
2014-10-13 18:23:51 +02:00
return {
2015-07-07 00:02:17 +02:00
' msg ' : args [ ' reply_user ' ] + ' : %s ' % out [ 0 ]
}
else :
return {
' msg ' : [ args [ ' reply_user ' ] + ' : decoding %s : ' % argv [ 1 ] ] + out
2014-10-13 18:23:51 +02:00
}
2014-12-16 08:48:03 +01:00
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' show-blacklist ' , ' show the current URL blacklist, optionally filtered ' , ptypes_COMMAND )
def command_show_blacklist ( argv , * * args ) :
2015-02-06 01:21:53 +01:00
if ' show-blacklist ' != argv [ 0 ] :
2014-12-16 08:48:03 +01:00
return
2014-12-02 17:01:40 +01:00
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent URL blacklist ' )
2014-12-16 08:48:03 +01:00
2015-02-06 01:21:53 +01:00
argv1 = None if len ( argv ) < 2 else argv [ 1 ]
2014-12-16 08:48:03 +01:00
return {
2014-12-22 21:06:02 +01:00
' msg ' : [
args [ ' reply_user ' ] + ' : URL blacklist %s : ' % (
2015-02-06 01:21:53 +01:00
' ' if not argv1 else ' (limited to %s ) ' % argv1
2014-12-22 21:06:02 +01:00
)
] + [
2014-12-16 08:48:03 +01:00
b for b in conf ( ' url_blacklist ' )
2015-02-06 01:21:53 +01:00
if not argv1 or argv1 in b
2014-12-16 08:48:03 +01:00
]
}
2014-11-28 19:13:45 +01:00
2015-02-09 03:46:17 +01:00
def usersetting_get ( argv , args ) :
2014-12-14 03:41:57 +01:00
blob = conf_load ( )
arg_user = args [ ' reply_user ' ]
2015-02-06 01:21:53 +01:00
arg_key = argv [ 1 ]
2014-12-14 03:41:57 +01:00
if not arg_user in blob [ ' user_pref ' ] :
return {
' msg ' : args [ ' reply_user ' ] + ' : user key not found '
}
return {
' msg ' : args [ ' reply_user ' ] + ' : %s == %s ' % (
arg_key ,
' on ' if blob [ ' user_pref ' ] [ arg_user ] [ arg_key ] else ' off '
)
}
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' set ' , ' modify a user setting ' , ptypes_COMMAND )
def command_usersetting ( argv , * * args ) :
2015-02-06 01:21:53 +01:00
if ' set ' != argv [ 0 ] :
2014-12-14 01:27:13 +01:00
return
2014-12-14 03:41:57 +01:00
settings = [ ' spoiler ' ]
arg_user = args [ ' reply_user ' ]
2015-02-06 01:21:53 +01:00
arg_key = argv [ 1 ] if len ( argv ) > 1 else None
arg_val = argv [ 2 ] if len ( argv ) > 2 else None
2014-12-14 03:41:57 +01:00
if not arg_key in settings :
2014-12-14 01:27:13 +01:00
return {
2014-12-14 03:41:57 +01:00
' msg ' : args [ ' reply_user ' ] + ' : known settings: ' + ( ' , ' . join ( settings ) )
2014-12-14 01:27:13 +01:00
}
2014-12-14 03:41:57 +01:00
if not arg_val in [ ' on ' , ' off ' , None ] :
2014-12-14 01:27:13 +01:00
return {
2014-12-14 03:41:57 +01:00
' msg ' : args [ ' reply_user ' ] + ' : possible values for %s : on, off ' % arg_key
2014-12-14 01:27:13 +01:00
}
2014-12-14 03:41:57 +01:00
if None == arg_val :
# display current value
2015-02-06 01:21:53 +01:00
return usersetting_get ( argv , args )
2014-12-14 01:27:13 +01:00
2014-12-14 03:41:57 +01:00
if conf ( ' persistent_locked ' ) :
return {
' msg ' : args [ ' reply_user ' ] + ''' : couldn ' t get exclusive lock '''
}
set_conf ( ' persistent_locked ' , True )
blob = conf_load ( )
2015-02-05 18:38:28 +01:00
if ' user_pref ' not in blob :
blob [ ' user_pref ' ] = { }
2014-12-14 03:41:57 +01:00
if not arg_user in blob [ ' user_pref ' ] :
blob [ ' user_pref ' ] [ arg_user ] = { }
2015-02-05 18:38:28 +01:00
blob [ ' user_pref ' ] [ arg_user ] [ arg_key ] = ' on ' == arg_val
2014-12-14 03:41:57 +01:00
conf_save ( blob )
set_conf ( ' persistent_locked ' , False )
# display value written to db
2015-02-09 03:46:17 +01:00
return usersetting_get ( argv , args )
2014-12-14 01:27:13 +01:00
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' cake ' , ' displays a cake ASCII art ' , ptypes_COMMAND )
2015-02-06 01:21:53 +01:00
def command_cake ( argv , * * args ) :
if ' cake ' != argv [ 0 ] :
2014-12-16 07:58:35 +01:00
return
return {
2015-02-22 20:15:23 +01:00
' msg ' : args [ ' reply_user ' ] + ' : %s ' % ( random . sample ( cakes , 1 ) [ 0 ] )
2014-12-16 07:58:35 +01:00
}
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' remember ' , ' remembers something ' , ptypes_COMMAND )
def command_remember ( argv , * * args ) :
2015-02-06 01:21:53 +01:00
if ' remember ' != argv [ 0 ] :
2014-12-23 19:54:05 +01:00
return
2015-06-21 00:50:42 +02:00
log . plugin ( ' remember plugin called ' )
2014-12-23 19:54:05 +01:00
2015-02-06 01:21:53 +01:00
if not len ( argv ) > 1 :
2014-12-23 19:54:05 +01:00
return {
' msg ' : args [ ' reply_user ' ] + ' : invalid message '
}
2014-12-27 14:55:24 +01:00
to_remember = ' ' . join ( args [ ' data ' ] . split ( ) [ 2 : ] ) # this is a little dirty. A little lot
set_conf ( ' data_remember ' , to_remember )
2014-12-23 19:54:05 +01:00
return {
2014-12-27 14:55:24 +01:00
' msg ' : args [ ' reply_user ' ] + ' : remembering ' + to_remember
2014-12-23 19:54:05 +01:00
}
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' recall ' , " recalls something previously ' remember ' ed " , ptypes_COMMAND )
def command_recall ( argv , * * args ) :
2015-02-06 01:21:53 +01:00
if ' recall ' != argv [ 0 ] :
2014-12-23 19:54:05 +01:00
return
2015-06-21 00:50:42 +02:00
log . plugin ( ' recall plugin called ' )
2014-12-23 19:54:05 +01:00
return {
' msg ' : args [ ' reply_user ' ] + ' : recalling %s ' % conf ( ' data_remember ' )
}
2015-02-06 01:21:53 +01:00
#TODO: send a hint if someone types plugin as command
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' plugin ' , " ' disable ' or ' enable ' plugins " , ptypes_COMMAND )
def command_plugin_activation ( argv , * * args ) :
2015-02-06 01:21:53 +01:00
command = argv [ 0 ]
plugin = argv [ 1 ] if len ( argv ) > 1 else None
2015-01-03 18:00:28 +01:00
2015-01-03 18:59:44 +01:00
if not command in ( ' enable ' , ' disable ' ) :
return
2015-01-03 18:00:28 +01:00
2015-06-21 00:50:42 +02:00
log . plugin ( ' plugin activation plugin called ' )
2015-01-03 18:00:28 +01:00
if None == plugin :
return {
' msg ' : args [ ' reply_user ' ] + ' : no plugin given '
}
2015-02-06 01:21:53 +01:00
elif command_plugin_activation . plugin_name == plugin :
2015-01-03 18:42:12 +01:00
return {
' msg ' : args [ ' reply_user ' ] + ' : not allowed '
}
2015-01-03 18:00:28 +01:00
2015-06-18 14:02:34 +02:00
for p in plugins [ ptypes_COMMAND ] + plugins [ ptypes_PARSE ] :
if p . plugin_name == plugin :
2015-07-03 01:19:47 +02:00
plugin_enabled_set ( p , ' enable ' == command )
2015-01-03 18:00:28 +01:00
2015-01-03 18:59:44 +01:00
return {
2015-02-09 03:46:17 +01:00
' msg ' : args [ ' reply_user ' ] + ' : %s d %s ' % (
2015-01-03 18:59:44 +01:00
command , plugin
)
}
2015-01-03 18:00:28 +01:00
return {
2015-01-03 18:59:44 +01:00
' msg ' : args [ ' reply_user ' ] + ' : unknown plugin %s ' % plugin
2015-01-03 18:00:28 +01:00
}
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' wp-en ' , ' crawl the english Wikipedia ' , ptypes_COMMAND )
def command_wp_en ( argv , * * args ) :
2015-02-06 01:21:53 +01:00
if ' wp-en ' != argv [ 0 ] :
2015-02-05 01:16:17 +01:00
return
2015-02-06 01:21:53 +01:00
if argv [ 0 ] :
argv [ 0 ] = ' wp '
2015-02-05 01:16:17 +01:00
2015-02-09 03:46:17 +01:00
return command_wp ( argv , lang = ' en ' , * * args )
2015-02-05 01:16:17 +01:00
2015-02-09 03:46:17 +01:00
@pluginfunction ( ' wp ' , ' crawl the german Wikipedia ' , ptypes_COMMAND )
def command_wp ( argv , lang = ' de ' , * * args ) :
2015-02-06 01:21:53 +01:00
if ' wp ' != argv [ 0 ] :
2015-02-05 00:48:02 +01:00
return
2015-07-19 20:42:20 +02:00
log . plugin ( ' plugin called ' )
2015-02-05 00:48:02 +01:00
2015-02-09 03:46:17 +01:00
query = ' ' . join ( argv [ 1 : ] )
2015-02-06 01:21:53 +01:00
2015-02-09 03:46:17 +01:00
if query == ' ' :
2015-02-06 01:21:53 +01:00
return {
2015-02-09 03:46:17 +01:00
' msg ' : args [ ' reply_user ' ] + ' : no query given '
}
2015-02-06 01:21:53 +01:00
2015-02-09 03:46:17 +01:00
api = {
' action ' : ' query ' ,
' prop ' : ' extracts ' ,
' explaintext ' : ' ' ,
' redirects ' : ' ' ,
' exsentences ' : 2 ,
' continue ' : ' ' ,
' format ' : ' json ' ,
' titles ' : query
}
apiurl = ' https:// %s .wikipedia.org/w/api.php? %s ' % (
lang , urllib . parse . urlencode ( api )
)
2015-02-05 00:48:02 +01:00
2015-07-19 20:42:20 +02:00
log . plugin ( ' fetching %s ' % apiurl )
2015-02-18 00:40:18 +01:00
2015-02-05 00:48:02 +01:00
try :
2015-02-06 13:19:14 +01:00
response = urllib . request . urlopen ( apiurl )
2015-02-05 00:48:02 +01:00
buf = response . read ( BUFSIZ )
2015-02-18 00:40:18 +01:00
j = json . loads ( buf . decode ( ' utf8 ' ) )
2015-02-06 15:27:11 +01:00
2015-02-06 14:07:58 +01:00
page = next ( iter ( j [ ' query ' ] [ ' pages ' ] . values ( ) ) )
2015-02-09 03:46:17 +01:00
short = page . get ( ' extract ' , None )
linktitle = page . get ( ' title ' , query ) . replace ( ' ' , ' _ ' )
2015-02-09 04:01:35 +01:00
link = ' https:// %s .wikipedia.org/wiki/ %s ' % (
lang , urllib . parse . quote ( linktitle )
)
2015-02-05 00:48:02 +01:00
except Exception as e :
2015-06-21 00:50:42 +02:00
log . plugin ( ' wp( %s ) failed: %s , %s ' % ( query , e , traceback . format_exc ( ) ) )
2015-02-05 00:48:02 +01:00
return {
2015-02-09 03:46:17 +01:00
' msg ' : args [ ' reply_user ' ] + ' : something failed: %s ' % e
2015-02-05 00:48:02 +01:00
}
2015-02-06 14:07:58 +01:00
if short is not None :
2015-02-07 02:12:41 +01:00
return {
2015-02-08 22:04:26 +01:00
' msg ' : args [ ' reply_user ' ] + ' : %s (< %s >) ' % (
2015-02-09 03:46:17 +01:00
short if short . strip ( ) else ' (nix) ' , link
2015-02-08 22:04:26 +01:00
)
2015-02-05 00:48:02 +01:00
}
2015-02-09 03:46:17 +01:00
elif ' missing ' in page :
return {
' msg ' : ' Article " %s " not found ' % page . get ( ' title ' , query )
}
2015-02-08 22:04:26 +01:00
else :
2015-02-09 03:46:17 +01:00
return {
' msg ' : ' json data seem to be broken '
}
2015-02-05 00:48:02 +01:00
2015-02-11 01:44:21 +01:00
@pluginfunction ( ' excuse ' , ' prints BOFH style excuses ' , ptypes_COMMAND )
def command_dummy ( argv , * * args ) :
if ' excuse ' != argv [ 0 ] :
return
2015-06-21 00:50:42 +02:00
log . plugin ( ' BOFH plugin called ' )
2015-02-11 01:44:21 +01:00
excuse = random . sample ( excuses , 1 ) [ 0 ]
return {
' msg ' : args [ ' reply_user ' ] + ' : ' + excuse
}
2015-06-21 23:07:37 +02:00
@pluginfunction ( ' show-moinlist ' , ' show the current moin reply list, optionally filtered ' , ptypes_COMMAND )
def command_show_moinlist ( argv , * * args ) :
if ' show-moinlist ' != argv [ 0 ] :
return
log . plugin ( ' sent moin reply list ' )
argv1 = None if len ( argv ) < 2 else argv [ 1 ]
return {
2015-06-21 23:13:22 +02:00
' msg ' :
' %s : moin reply list %s : %s ' % (
args [ ' reply_user ' ] ,
' ' if not argv1 else ' (limited to %s ) ' % argv1 ,
' , ' . join ( [
b for b in moin_strings_hi + moin_strings_bye
if not argv1 or argv1 . lower ( ) in b . lower ( )
] )
2015-06-21 23:07:37 +02:00
)
}
2015-07-02 14:26:23 +02:00
@pluginfunction ( ' list ' , ' list plugin and parser status ' , ptypes_COMMAND )
def command_list ( argv , * * args ) :
if ' list ' != argv [ 0 ] :
return
log . plugin ( ' list plugin called ' )
if ' enabled ' in argv and ' disabled ' in argv :
return {
' msg ' : args [ ' reply_user ' ] + " : both ' enabled ' and ' disabled ' makes no sense "
}
# if not given, asume both
if not ' command ' in argv and not ' parser ' in argv :
argv . append ( ' command ' )
argv . append ( ' parser ' )
out_command = [ ]
out_parser = [ ]
if ' command ' in argv :
out_command = plugins [ ptypes_COMMAND ]
if ' parser ' in argv :
out_parser = plugins [ ptypes_PARSE ]
if ' enabled ' in argv :
2015-07-03 01:19:47 +02:00
out_command = [ p for p in out_command if plugin_enabled_get ( p ) ]
out_parser = [ p for p in out_parser if plugin_enabled_get ( p ) ]
2015-07-02 14:26:23 +02:00
if ' disabled ' in argv :
2015-07-03 01:19:47 +02:00
out_command = [ p for p in out_command if not plugin_enabled_get ( p ) ]
out_parser = [ p for p in out_parser if not plugin_enabled_get ( p ) ]
2015-07-02 14:26:23 +02:00
msg = [ args [ ' reply_user ' ] + ' : list of plugins: ' ]
if out_command :
msg . append ( ' commands: %s ' % ' , ' . join ( [ p . plugin_name for p in out_command ] ) )
if out_parser :
msg . append ( ' parsers: %s ' % ' , ' . join ( [ p . plugin_name for p in out_parser ] ) )
return { ' msg ' : msg }
2015-07-10 23:54:18 +02:00
@pluginfunction ( ' record ' , ' record a message for a now offline user ' , ptypes_COMMAND )
def command_record ( argv , * * args ) :
if ' record ' != argv [ 0 ] :
return
if 3 > len ( argv ) :
return {
' msg ' : ' %s : usage: record {user} { some message} ' % args [ ' reply_user ' ]
}
2015-07-11 11:34:18 +02:00
target_user = argv [ 1 ] . lower ( )
2015-07-11 00:27:46 +02:00
message = ' %s ( %s ): ' % ( args [ ' reply_user ' ] , time . strftime ( ' %F . % T ' ) )
2015-07-10 23:54:18 +02:00
message + = ' ' . join ( argv [ 2 : ] )
if conf ( ' persistent_locked ' ) :
return {
' msg ' : " %s : couldn ' t get exclusive lock " % args [ ' reply_user ' ]
}
set_conf ( ' persistent_locked ' , True )
blob = conf_load ( )
if ' user_records ' not in blob :
blob [ ' user_records ' ] = { }
if not target_user in blob [ ' user_records ' ] :
blob [ ' user_records ' ] [ target_user ] = [ ]
blob [ ' user_records ' ] [ target_user ] . append ( message )
conf_save ( blob )
set_conf ( ' persistent_locked ' , False )
return {
' msg ' : ' %s : message saved for %s ' % ( args [ ' reply_user ' ] , target_user )
}
2015-07-11 13:23:23 +02:00
@pluginfunction ( ' show-records ' , ' show current offline records ' , ptypes_COMMAND )
def command_show_recordlist ( argv , * * args ) :
if ' show-records ' != argv [ 0 ] :
return
log . plugin ( ' sent offline records list ' )
argv1 = None if len ( argv ) < 2 else argv [ 1 ]
return {
' msg ' :
' %s : offline records %s : %s ' % (
args [ ' reply_user ' ] ,
' ' if not argv1 else ' (limited to %s ) ' % argv1 ,
' , ' . join ( [
' %s ( %d ) ' % ( key , len ( val ) ) for key , val in conf_load ( ) . get ( ' user_records ' ) . items ( )
if not argv1 or argv1 . lower ( ) in key . lower ( )
] )
)
}
2015-07-19 01:59:10 +02:00
@pluginfunction ( ' dsa-watcher ' , ' automatically crawls for newly published Debian Security Announces ' , ptypes_COMMAND )
def command_dsa_watcher ( argv , * * args ) :
if ' dsa-watcher ' != argv [ 0 ] :
return
if 2 != len ( argv ) :
msg = ' wrong number of arguments '
log . warn ( msg )
return { ' msg ' : msg }
if ' crawl ' == argv [ 1 ] :
2015-07-19 02:19:37 +02:00
out = [ ]
2015-07-19 01:59:10 +02:00
dsa = conf_load ( ) . get ( ' plugin_conf ' , { } ) . get ( ' last_dsa ' , 1000 )
url = ' https://security-tracker.debian.org/tracker/DSA- %d -1 ' % dsa
status , title = extract_title ( url )
if 0 == status :
2015-07-19 02:22:22 +02:00
send_reply ( ' new Debian Security Announce found: %s ' % url )
2015-07-19 01:59:10 +02:00
if conf ( ' persistent_locked ' ) :
2015-07-19 02:07:03 +02:00
msg = " couldn ' t get exclusive lock "
2015-07-19 01:59:10 +02:00
log . warn ( msg )
2015-07-19 02:19:37 +02:00
out . append ( msg )
2015-07-19 01:59:10 +02:00
else :
set_conf ( ' persistent_locked ' , True )
blob = conf_load ( )
if ' plugin_conf ' not in blob :
blob [ ' plugin_conf ' ] = { }
if not ' last_dsa ' in blob [ ' plugin_conf ' ] :
blob [ ' plugin_conf ' ] [ ' last_dsa ' ] = 3308 # FIXME: fixed value
blob [ ' plugin_conf ' ] [ ' last_dsa ' ] + = 1
conf_save ( blob )
set_conf ( ' persistent_locked ' , False )
msg = ' new Debian Security Announce found: %s ' % url
log . plugin ( msg )
2015-07-19 02:19:37 +02:00
out . append ( msg )
2015-07-19 01:59:10 +02:00
elif 3 == status :
if not ' 404 ' in title :
msg = ' error for # %s : %s ' % ( url , title )
log . warn ( msg )
2015-07-19 02:19:37 +02:00
out . append ( msg )
2015-07-19 01:59:10 +02:00
2015-07-19 02:19:37 +02:00
log . plugin ( ' no dsa for %d , trying again... ' % dsa )
2015-07-19 01:59:10 +02:00
# that's good, no error, just 404 -> DSA not released yet
else :
2015-07-19 02:07:03 +02:00
log . plugin ( ' unknown status %d ' % status )
2015-07-19 01:59:10 +02:00
2015-07-19 02:09:56 +02:00
crawl_at = time . time ( ) + conf ( ' dsa_watcher_interval ' )
2015-07-19 02:19:37 +02:00
register_event ( crawl_at , command_dsa_watcher , ( [ ' dsa-watcher ' , ' crawl ' ] , ) )
2015-07-19 01:59:10 +02:00
2015-07-19 02:23:53 +02:00
msg = ' next crawl set to %s ' % time . strftime ( ' %F . % T ' , time . localtime ( crawl_at ) )
2015-07-19 01:59:10 +02:00
log . plugin ( msg )
2015-07-19 02:19:37 +02:00
out . append ( msg )
return { ' msg ' : out }
2015-07-19 01:59:10 +02:00
else :
msg = ' wrong argument '
log . warn ( msg )
return { ' msg ' : msg }
2015-02-11 01:33:48 +01:00
#@pluginfunction('dummy', 'dummy description', ptypes_COMMAND)
#def command_dummy(argv, **args):
2015-02-06 01:21:53 +01:00
# if 'dummy' != argv[0]:
2014-12-16 08:48:03 +01:00
# return
2014-12-02 17:01:40 +01:00
#
2015-06-21 00:50:42 +02:00
# log.plugin('dummy plugin called')
2014-12-16 08:48:03 +01:00
#
# return {
# 'msg': args['reply_user'] + ': dummy plugin called'
# }
2014-10-13 18:23:51 +02:00
2015-02-05 19:23:05 +01:00
def else_command ( args ) :
2015-06-21 00:50:42 +02:00
log . plugin ( ' sent short info ' )
2014-09-27 03:40:27 +02:00
return {
2014-09-27 05:32:35 +02:00
' msg ' : args [ ' reply_user ' ] + ''' : I ' m a bot (highlight me with ' info ' for more information). '''
2014-09-27 03:40:27 +02:00
}
2014-12-13 22:46:23 +01:00
def data_parse_commands ( msg_obj ) :
2015-06-20 14:18:50 +02:00
global got_hangup
2014-12-13 22:46:23 +01:00
data = msg_obj [ ' body ' ]
2015-02-06 01:21:53 +01:00
words = data . split ( )
2014-09-27 03:40:27 +02:00
2014-12-02 17:01:40 +01:00
if 2 > len ( words ) : # need at least two words
2014-09-27 03:40:27 +02:00
return None
2014-12-02 16:37:35 +01:00
# don't reply if beginning of the text matches bot_user
if not data . startswith ( conf ( ' bot_user ' ) ) :
return None
2014-09-27 03:40:27 +02:00
if ' hangup ' in data :
2015-06-21 00:50:42 +02:00
log . warn ( ' received hangup: ' + data )
2015-06-20 14:18:50 +02:00
got_hangup = True
2014-12-02 15:22:02 +01:00
sys . exit ( 1 )
2014-09-27 03:40:27 +02:00
return None
2014-12-13 22:46:23 +01:00
reply_user = msg_obj [ ' mucnick ' ]
2015-02-06 01:21:53 +01:00
2015-02-08 22:18:07 +01:00
for p in plugins [ ptypes_COMMAND ] :
2015-02-06 01:21:53 +01:00
if ratelimit_exceeded ( p . ratelimit_class ) :
2014-09-27 05:32:35 +02:00
continue
2015-07-03 01:19:47 +02:00
if not plugin_enabled_get ( p ) :
2015-01-03 18:17:54 +01:00
continue
2015-02-08 22:04:26 +01:00
ret = p (
data = data ,
2015-02-08 22:18:07 +01:00
cmd_list = [ pl . plugin_name for pl in plugins [ ptypes_COMMAND ] ] ,
2015-06-18 14:02:34 +02:00
parser_list = [ pl . plugin_name for pl in plugins [ ptypes_PARSE ] ] ,
2015-02-08 22:04:26 +01:00
reply_user = reply_user ,
msg_obj = msg_obj ,
argv = words [ 1 : ]
)
2015-02-06 01:21:53 +01:00
2014-09-27 05:32:35 +02:00
if None != ret :
2014-09-28 18:03:08 +02:00
if ' msg ' in list ( ret . keys ( ) ) :
2014-12-14 15:54:57 +01:00
ratelimit_touch ( RATE_CHAT )
if ratelimit_exceeded ( RATE_CHAT ) :
return False
2014-09-28 18:03:08 +02:00
2014-12-14 15:54:57 +01:00
send_reply ( ret [ ' msg ' ] , msg_obj )
2014-09-27 16:20:34 +02:00
2014-09-27 16:06:26 +02:00
return None
2014-09-27 03:40:27 +02:00
2015-02-05 19:23:05 +01:00
ret = else_command ( { ' reply_user ' : reply_user } )
2014-09-27 03:40:27 +02:00
if None != ret :
if ratelimit_exceeded ( RATE_GLOBAL ) :
return False
2014-09-28 18:03:08 +02:00
if ' msg ' in list ( ret . keys ( ) ) :
2014-12-14 15:54:57 +01:00
send_reply ( ret [ ' msg ' ] , msg_obj )
2014-09-27 05:32:35 +02:00
2014-09-27 09:19:46 +02:00
if debug_enabled ( ) :
2014-12-13 22:46:23 +01:00
def _send_reply ( a , msg_obj ) :
2015-06-21 01:31:55 +02:00
log . info ( ' send_reply[ %s ] ' % msg_obj , a )
2014-12-02 17:01:40 +01:00
2014-12-14 16:26:48 +01:00
def _conf ( ignored ) :
2014-12-02 17:01:40 +01:00
return ' bot '
def _ratelimit_exceeded ( ignored = None ) :
return False
def _ratelimit_touch ( ignored = None ) :
return True
try :
2014-12-13 22:46:23 +01:00
send_reply
2014-12-02 17:01:40 +01:00
except NameError :
2014-12-13 22:46:23 +01:00
send_reply = _send_reply
2014-12-02 17:01:40 +01:00
try :
conf
except NameError :
conf = _conf
try :
ratelimit_exceeded
except NameError :
ratelimit_exceeded = _ratelimit_exceeded
try :
ratelimit_touch
except NameError :
ratelimit_touch = _ratelimit_touch
2014-09-27 05:32:35 +02:00
2015-06-21 00:50:42 +02:00
log . info ( ' debugging enabled ' )
2014-09-27 16:06:26 +02:00
2015-02-05 19:00:38 +01:00
def register ( func_type ) :
2015-02-09 03:46:17 +01:00
'''
2015-02-05 19:00:38 +01:00
Register plugins .
2015-02-08 22:04:26 +01:00
2015-02-05 19:00:38 +01:00
Arguments :
2015-02-05 23:34:44 +01:00
func_type - - plugin functions with this type ( ptypes ) will be loaded
2015-02-09 03:46:17 +01:00
'''
functions = [
f for ignored , f in globals ( ) . items ( )
if
type ( f ) == types . FunctionType
and f . __dict__ . get ( ' is_plugin ' , False )
and f . plugin_type == func_type
]
2015-06-21 00:56:33 +02:00
log . info ( ' auto-reg %s : %s ' % ( func_type , ' , ' . join (
2015-02-09 03:46:17 +01:00
f . plugin_name for f in functions
) ) )
2014-09-27 05:32:35 +02:00
2015-02-05 19:00:38 +01:00
for f in functions :
register_plugin ( f , func_type )
def register_plugin ( function , func_type ) :
try :
2015-02-05 23:34:44 +01:00
plugins [ func_type ] . append ( function )
2015-02-05 19:00:38 +01:00
except Exception as e :
2015-06-21 00:50:42 +02:00
log . warn ( ' registering %s failed: %s , %s ' %
2015-02-05 19:23:05 +01:00
( function , e , traceback . format_exc ( ) ) )
2014-09-27 05:32:35 +02:00
def register_all ( ) :
2015-02-08 22:18:07 +01:00
register ( ptypes_PARSE )
register ( ptypes_COMMAND )
2014-09-29 19:15:00 +02:00
def event_trigger ( ) :
2015-06-20 14:18:50 +02:00
if got_hangup :
return False
2014-09-29 19:15:00 +02:00
if 0 == len ( joblist ) :
return
now = time . time ( )
2014-12-13 23:29:51 +01:00
for ( i , ( t , callback , args ) ) in enumerate ( joblist ) :
2014-09-29 19:15:00 +02:00
if t < now :
2014-12-13 22:57:15 +01:00
callback ( * args )
2014-09-29 19:15:00 +02:00
del ( joblist [ i ] )