add: initial AI support
This commit is contained in:
369
plugins/acl.py
Normal file
369
plugins/acl.py
Normal file
@@ -0,0 +1,369 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
acl_acts = ['msg','prs','prs_change','prs_join','role','role_change','role_join','aff','aff_change','aff_join',
|
||||
'nick','nick_change','nick_join','all','all_change','all_join','jid','jidfull','res','age','ver','vcard']
|
||||
acl_actions = ['show','del','clear'] + acl_acts
|
||||
|
||||
acl_ver_tmp = {}
|
||||
acl_vcard_tmp = {}
|
||||
|
||||
acl_actions.sort()
|
||||
|
||||
def acl_show(jid,nick,text):
|
||||
a = cur_execute_fetchall('select * from acl where jid=%s and action ilike %s order by level,action',(jid,text))
|
||||
if len(a):
|
||||
msg = L('Acl:','%s/%s'%(jid,nick))
|
||||
for tmp in a:
|
||||
if text == '%': t4 = tmp[4].replace('\n',' // ')
|
||||
else: t4 = tmp[4].replace('\n','\n ')
|
||||
if tmp[6] == 9:
|
||||
if tmp[5]: st,tp = '\n[%s] %s %s %s -> %s', (disp_time(tmp[5],'%s/%s'%(jid,nick)),) + tmp[1:4] + (t4,)
|
||||
else: st,tp = '\n%s %s %s -> %s', tmp[1:4] + (t4,)
|
||||
else:
|
||||
if tmp[5]: st,tp = '\n%s | [%s] %s %s %s -> %s', (L(unlevl[tmp[6]],'%s/%s'%(jid,nick)),disp_time(tmp[5],'%s/%s'%(jid,nick)),) + tmp[1:4] + (t4,)
|
||||
else: st,tp = '\n%s | %s %s %s -> %s', (L(unlevl[tmp[6]],'%s/%s'%(jid,nick)),) + tmp[1:4] + (t4,)
|
||||
msg += st % tp
|
||||
else: msg = L('Acl not found','%s/%s'%(jid,nick))
|
||||
return msg
|
||||
|
||||
def acl_add_del(jid,nick,text,flag):
|
||||
global conn
|
||||
time_mass,atime = {'s':1,'m':60,'h':3600,'d':86400,'w':604800,'M':2592000,'y':31536000},0
|
||||
silent,level = False,9
|
||||
try:
|
||||
while text[0][0] == '/':
|
||||
if text[0] == '/silent': silent = True
|
||||
else:
|
||||
try: atime = int(time.time()) + int(text[0][1:-1]) * time_mass[text[0][-1:]]
|
||||
except: return L('Time format error!','%s/%s'%(jid,nick))
|
||||
text = text[1:]
|
||||
except: return L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
if text[0].isdigit():
|
||||
level = int(text[0])
|
||||
if level <= 0: level = 9
|
||||
elif level > 9: level = 9
|
||||
text = text[1:]
|
||||
ttext = ' '.join(text)
|
||||
if operator.xor(ttext.count('${EXP}') <= 1,ttext.count('${/EXP}') <= 1) and flag: return L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
elif ttext.find('${EXP}',ttext.find('${/EXP}')) > 0 and flag: return L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
elif '${EXP}' in ttext and '${/EXP}' in ttext:
|
||||
try: re.compile(ttext.split('${EXP}',1)[1].split('${/EXP}',1)[0].replace('%20','\ ').replace('*','*?'))
|
||||
except: return L('Error in RegExp!','%s/%s'%(jid,nick))
|
||||
try:
|
||||
acl_cmd = text[0]
|
||||
text = text[1:]
|
||||
except: return L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
if not acl_cmd in acl_acts: msg = L('Items: %s','%s/%s'%(jid,nick)) % ', '.join(acl_acts)
|
||||
else:
|
||||
try:
|
||||
if text[0].lower() in ['sub','!sub','exp','!exp','cexp','!cexp','=','!=','<','>','<=','>=']: acl_sub_act,text = text[0].lower(),text[1:]
|
||||
else: acl_sub_act = '='
|
||||
except: return L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
if acl_cmd != 'age' and acl_sub_act in ['<','>','<=','>=']: return L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
if acl_sub_act in ['=','!=','sub','!sub']: text[0] = text[0].replace('%20',' ')
|
||||
else: text[0] = text[0].replace('%20','\ ')
|
||||
if acl_cmd == 'age' and not text[0].isdigit(): return L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
if acl_sub_act in ['exp','!exp','cexp','!cexp']:
|
||||
try: re.compile(text[0].replace('*','*?'))
|
||||
except: return L('Error in RegExp!','%s/%s'%(jid,nick))
|
||||
if flag and len(text) >= 2:
|
||||
no_command = True
|
||||
for tmp in comms:
|
||||
if tmp[1] == text[1]:
|
||||
no_command = False
|
||||
break
|
||||
if no_command: return L('Unknown command: %s','%s/%s'%(jid,nick)) % text[1]
|
||||
tmp = cur_execute_fetchall('select * from acl where jid=%s and action=%s and type=%s and text=%s and level=%s',(jid,acl_cmd, acl_sub_act, text[0], level))
|
||||
if tmp:
|
||||
cur_execute('delete from acl where jid=%s and action=%s and type=%s and text=%s and level=%s',(jid,acl_cmd, acl_sub_act, text[0], level))
|
||||
msg = [L('Removed:','%s/%s'%(jid,nick)),L('Updated:','%s/%s'%(jid,nick))][flag]
|
||||
else: msg = [L('Not found:','%s/%s'%(jid,nick)),L('Added:','%s/%s'%(jid,nick))][flag]
|
||||
if flag: cur_execute('insert into acl values (%s,%s,%s,%s,%s,%s,%s)', (jid, acl_cmd, acl_sub_act, text[0], ' '.join(text[1:]).replace('%20','\ '), atime, level))
|
||||
if level == 9:
|
||||
if atime: msg += ' [%s] %s %s %s -> %s' % (disp_time(atime,'%s/%s'%(jid,nick)),acl_cmd, acl_sub_act, text[0], ' '.join(text[1:]).replace('%20','\ ').replace('\n',' // '))
|
||||
else: msg += ' %s %s %s -> %s' % (acl_cmd, acl_sub_act, text[0], ' '.join(text[1:]).replace('%20','\ ').replace('\n',' // '))
|
||||
else:
|
||||
if atime: msg += ' %s | [%s] %s %s %s -> %s' % (L(unlevl[level],'%s/%s'%(jid,nick)), disp_time(atime,'%s/%s'%(jid,nick)),acl_cmd, acl_sub_act, text[0], ' '.join(text[1:]).replace('%20','\ ').replace('\n',' // '))
|
||||
else: msg += ' %s | %s %s %s -> %s' % (L(unlevl[level],'%s/%s'%(jid,nick)), acl_cmd, acl_sub_act, text[0], ' '.join(text[1:]).replace('%20','\ ').replace('\n',' // '))
|
||||
if not reduce_spaces_all(msg).split('->',1)[1]: msg = msg.split('->',1)[0]
|
||||
if flag and acl_cmd != 'msg':
|
||||
mb = [t[1:] for t in megabase if t[0] == jid and getRoom(t[4]) != getRoom(Settings['jid'])]
|
||||
a = [(acl_cmd, acl_sub_act, text[0], ' '.join(text[1:]).replace('%20','\ '), 0, level)]
|
||||
was_joined = True
|
||||
for t in mb:
|
||||
room, realjid, nick = jid, t[3], t[0]
|
||||
mass = cur_execute_fetchone('select message from age where jid=%s and room=%s and nick=%s',(getRoom(realjid),room,nick))[0].split('\n',4)
|
||||
mass = (mass[4], mass[0], mass[1])
|
||||
acl_selector(a,room,realjid,nick,mass,was_joined)
|
||||
if silent: return L('done','%s/%s'%(jid,nick))
|
||||
else: return msg
|
||||
|
||||
def acl_add(jid,nick,text): return acl_add_del(jid,nick,text,True)
|
||||
|
||||
def acl_del(jid,nick,text): return acl_add_del(jid,nick,text,False)
|
||||
|
||||
def acl_clear(room,nick):
|
||||
if get_level(room,nick)[0] < 8: return L('You have no rights to do it!','%s/%s'%(room,nick))
|
||||
acl_back = cur_execute_fetchall('select * from acl where jid=%s',(room,))
|
||||
if acl_back:
|
||||
fname = back_folder % '%s_%s.acl' % (unicode(room),''.join(['%02d' % t for t in time.localtime()[:6]]))
|
||||
writefile(fname,json.dumps(acl_back))
|
||||
cur_execute('delete from acl where jid=%s',(room,))
|
||||
return L('ACL cleared. Removed %s action(s).','%s/%s'%(room,nick)) % len(acl_back)
|
||||
|
||||
def muc_acl(type, jid, nick, text):
|
||||
text = text.replace('\ ','%20').replace(' // ','\n').replace(' \/\/ ',' // ').split(' ')
|
||||
if len(text) >= 3 and text[2] == '->': text[2] = ''
|
||||
elif len(text) >= 4 and text[3] == '->': text[3] = ''
|
||||
elif text[0].isdigit() and len(text) >= 5 and text[4] == '->': text[4] = ''
|
||||
elif text[0].lower() == 'del' and len(text) >= 5 and text[4] == '->': text[4] = ''
|
||||
while '' in text: text.remove('')
|
||||
if len(text): acl_cmd = text[0]
|
||||
else: acl_cmd = '!'
|
||||
if not acl_cmd in acl_actions and acl_cmd[0] != '/' and not acl_cmd.isdigit(): msg = L('Items: %s','%s/%s'%(jid,nick)) % ', '.join(acl_actions)
|
||||
elif acl_cmd == 'clear': msg = acl_clear(jid,nick)
|
||||
elif acl_cmd == 'show':
|
||||
try: t = text[1]
|
||||
except: t = '%'
|
||||
msg = acl_show(jid,nick,t)
|
||||
elif acl_cmd == 'del': msg = acl_del(jid,nick,text[1:])
|
||||
else: msg = acl_add(jid,nick,text)
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def acl_action(cmd,nick,jid,room,text):
|
||||
global last_command
|
||||
if len(last_command):
|
||||
if last_command[6] == Settings['jid']: last_command = []
|
||||
cmd = cmd.replace('${NICK}',nick).replace('${JID}',jid).replace('${SERVER}',getServer(jid))
|
||||
if text and '${EXP}' in cmd and '${/EXP}' in cmd:
|
||||
regex = cmd.split('${EXP}',1)[1].split('${/EXP}',1)[0]
|
||||
mt = re.findall(regex, text, re.S|re.I|re.U)
|
||||
if mt != []: txt = ''.join(mt[0])
|
||||
else: txt = ''
|
||||
cmd = cmd.split('${EXP}',1)[0] + txt + cmd.split('${/EXP}',1)[1]
|
||||
nowname = get_xnick(room)
|
||||
return com_parser(7, nowname, 'groupchat', room, nick, cmd, Settings['jid'])
|
||||
|
||||
def acl_message(room,jid,nick,type,text):
|
||||
global conn
|
||||
#if not no_comm: return
|
||||
lvl = get_level(room,nick)[0]
|
||||
if lvl < 0: return
|
||||
if getRoom(jid) == getRoom(Settings['jid']): return
|
||||
a = cur_execute_fetchall('select action,type,text,command,time,level from acl where jid=%s and (action=%s or action ilike %s) order by level',(room,'msg','all%'))
|
||||
no_comm = True
|
||||
if a:
|
||||
acl_ma = get_config(room,'acl_multiaction')
|
||||
for tmp in a:
|
||||
if tmp[5] == 9 or lvl == tmp[5]:
|
||||
if tmp[4] <= time.time() and tmp[4]: cur_execute('delete from acl where jid=%s and action=%s and type=%s and text=%s',(room,tmp[0],tmp[1],tmp[2]))
|
||||
was_match = False
|
||||
if tmp[1] in ['exp','!exp']:
|
||||
if tmp[1][0] == '!' and not re.findall(tmp[2].replace('*','*?'),text,re.S|re.I|re.U): was_match = True
|
||||
elif re.findall(tmp[2].replace('*','*?'),text,re.S|re.I|re.U): was_match = True
|
||||
elif tmp[1] in ['cexp','!cexp']:
|
||||
if tmp[1][0] == '!' and not re.findall(tmp[2].replace('*','*?'),text,re.S|re.U): was_match = True
|
||||
elif re.findall(tmp[2].replace('*','*?'),text,re.S|re.U): was_match = True
|
||||
elif tmp[1] in ['sub','!sub']:
|
||||
if tmp[1][0] == '!' and not tmp[2].lower() in text.lower(): was_match = True
|
||||
elif tmp[2].lower() in text.lower(): was_match = True
|
||||
elif tmp[1] in ['=','!=']:
|
||||
if tmp[1][0] == '!' and text.lower() != tmp[2].lower(): was_match = True
|
||||
elif text.lower() == tmp[2].lower(): was_match = True
|
||||
if was_match:
|
||||
no_comm = acl_action(tmp[3],nick,jid,room,text)
|
||||
if not acl_ma: break
|
||||
|
||||
return not no_comm
|
||||
|
||||
def bool_compare(a,b,c):
|
||||
a,c = int(a),int(c)
|
||||
return (b == '=' and a == c)\
|
||||
or (b == '<' and a < c)\
|
||||
or (b == '>' and a > c)\
|
||||
or (b == '<=' and a >= c)\
|
||||
or (b == '>=' and a >= c)
|
||||
|
||||
def acl_presence(room,jid,nick,type,mass):
|
||||
global iq_request,acl_ver_tmp,acl_vcard_tmp
|
||||
#if get_level(room,nick)[0] < 0: return
|
||||
if getRoom(jid) == getRoom(Settings['jid']): return
|
||||
was_joined = not mass[7] or is_start
|
||||
if type == 'error': return
|
||||
elif type == 'unavailable':
|
||||
try: acl_ver_tmp.pop('%s/%s' % (room,nick))
|
||||
except: pass
|
||||
try: acl_vcard_tmp.pop('%s/%s' % (room,nick))
|
||||
except: pass
|
||||
return
|
||||
# actions only on joins
|
||||
#if was_joined: return
|
||||
a = cur_execute_fetchall('select action,type,text,command,time,level from acl where jid=%s and (action ilike %s or action ilike %s or action ilike %s or action ilike %s or action ilike %s or action ilike %s or action=%s or action=%s or action=%s or action=%s or action=%s) order by level',(room,'prs%','nick%','all%','role%','aff%','jid','jidfull','res','age','ver','vcard'))
|
||||
if a: acl_selector(a,room,jid,nick,mass,was_joined)
|
||||
|
||||
def acl_selector(a,room,jid,nick,mass,was_joined):
|
||||
global iq_request,acl_ver_tmp,acl_vcard_tmp
|
||||
lvl = get_level(room,nick)[0]
|
||||
for tmp in a:
|
||||
if (tmp[5] == 9 or lvl == tmp[5]) and tmp[0] == 'age':
|
||||
r_age = cur_execute_fetchone('select sum(%s-time+age) from age where room=%s and jid=%s',(int(time.time()),room,getRoom(jid)))[0]
|
||||
if not r_age: r_age = 0
|
||||
break
|
||||
|
||||
r_ver,r_vcard = None,None
|
||||
|
||||
for tmp in a:
|
||||
if (tmp[5] == 9 or lvl == tmp[5]) and tmp[0] == 'ver' and was_joined:
|
||||
try:
|
||||
r_ver = acl_ver_tmp['%s/%s' % (room,nick)]
|
||||
break
|
||||
except:
|
||||
iqid,who = get_id(), '%s/%s' % (room,nick)
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':who}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_VERSION},[])])
|
||||
iq_request[iqid]=(time.time(),acl_version_async,[a, nick, jid, room, mass[0], lvl],xmpp.NS_VERSION)
|
||||
sender(i)
|
||||
pprint('*** ACL version request for [%s] %s/%s' % (tmp[5],room,nick),'purple')
|
||||
break
|
||||
|
||||
for tmp in a:
|
||||
if (tmp[5] == 9 or lvl == tmp[5]) and tmp[0] == 'vcard' and was_joined:
|
||||
try:
|
||||
r_vcard = acl_vcard_tmp['%s/%s' % (room,nick)]
|
||||
break
|
||||
except:
|
||||
iqid,who = get_id(), '%s/%s' % (room,nick)
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':who}, payload = [xmpp.Node('vCard', {'xmlns': xmpp.NS_VCARD},[])])
|
||||
iq_request[iqid]=(time.time(),acl_vcard_async,[a, nick, jid, room, mass[0], lvl],xmpp.NS_VCARD)
|
||||
sender(i)
|
||||
pprint('*** ACL vcard request for [%s] %s/%s' % (tmp[5],room,nick),'purple')
|
||||
break
|
||||
|
||||
acl_ma = get_config(room,'acl_multiaction')
|
||||
for tmp in a:
|
||||
if tmp[5] == 9 or lvl == tmp[5]:
|
||||
itm = ''
|
||||
if tmp[4] <= time.time() and tmp[4]: cur_execute('delete from acl where jid=%s and action=%s and type=%s and text=%s',(room,tmp[0],tmp[1],tmp[2]))
|
||||
if tmp[0].split('_')[0] == 'prs' and (('_join' in tmp[0] and was_joined) or ('_change' in tmp[0] and not was_joined) or ('_join' not in tmp[0] and '_change' not in tmp[0])): itm = mass[0]
|
||||
elif tmp[0].split('_')[0] == 'nick' and (('_join' in tmp[0] and was_joined) or ('_change' in tmp[0] and not was_joined) or ('_join' not in tmp[0] and '_change' not in tmp[0])): itm = nick
|
||||
elif tmp[0].split('_')[0] == 'role' and (('_join' in tmp[0] and was_joined) or ('_change' in tmp[0] and not was_joined) or ('_join' not in tmp[0] and '_change' not in tmp[0])): itm = mass[1]
|
||||
elif tmp[0].split('_')[0] == 'aff' and (('_join' in tmp[0] and was_joined) or ('_change' in tmp[0] and not was_joined) or ('_join' not in tmp[0] and '_change' not in tmp[0])): itm = mass[2]
|
||||
elif tmp[0].split('_')[0] == 'all' and (('_join' in tmp[0] and was_joined) or ('_change' in tmp[0] and not was_joined) or ('_join' not in tmp[0] and '_change' not in tmp[0])): itm = '|'.join((jid,nick,mass[0],mass[1],mass[2]))
|
||||
elif tmp[0] == 'jid' and was_joined: itm = getRoom(jid)
|
||||
elif tmp[0] == 'jidfull' and was_joined: itm = jid
|
||||
elif tmp[0] == 'res' and was_joined: itm = getResourse(jid)
|
||||
elif tmp[0] == 'ver' and was_joined and r_ver: itm = r_ver
|
||||
elif tmp[0] == 'vcard' and was_joined and r_vcard: itm = r_vcard
|
||||
elif tmp[0] == 'age' and was_joined and bool_compare(r_age,tmp[1],tmp[2]):
|
||||
acl_action(tmp[3],nick,jid,room,None)
|
||||
if not acl_ma: break
|
||||
if itm:
|
||||
was_match = False
|
||||
if tmp[1] in ['exp','!exp']:
|
||||
if tmp[1][0] == '!' and not re.findall(tmp[2].replace('*','*?'),itm,re.S|re.I|re.U): was_match = True
|
||||
elif re.findall(tmp[2].replace('*','*?'),itm,re.S|re.I|re.U): was_match = True
|
||||
elif tmp[1] in ['cexp','!cexp']:
|
||||
if tmp[1][0] == '!' and not re.findall(tmp[2].replace('*','*?'),itm,re.S|re.U): was_match = True
|
||||
elif re.findall(tmp[2].replace('*','*?'),itm,re.S|re.U): was_match = True
|
||||
elif tmp[1] in ['sub','!sub']:
|
||||
if tmp[1][0] == '!' and tmp[2].lower() not in itm.lower(): was_match = True
|
||||
elif tmp[2].lower() in itm.lower(): was_match = True
|
||||
elif tmp[1] in ['=','!=']:
|
||||
if tmp[1][0] == '!' and not (itm.lower() == tmp[2].lower() or (tmp[0] == 'all' and tmp[2].lower() in (jid.lower(),nick.lower(),mass[0].lower()))): was_match = True
|
||||
elif itm.lower() == tmp[2].lower() or (tmp[0] == 'all' and tmp[2].lower() in (jid.lower(),nick.lower(),mass[0].lower())): was_match = True
|
||||
if was_match:
|
||||
acl_action(tmp[3],nick,jid,room,None)
|
||||
if not acl_ma: break
|
||||
|
||||
def acl_version_async(a, nick, jid, room, mass, lvl, is_answ):
|
||||
global acl_ver_tmp
|
||||
itm = is_answ[1][0]
|
||||
acl_ver_tmp['%s/%s' % (room,nick)] = itm.replace('\r','[LF]').replace('\n','[CR]').replace('\t','[TAB]')
|
||||
for tmp in a:
|
||||
if tmp[0] == 'ver' and (tmp[5] == 9 or lvl == tmp[5]):
|
||||
was_match = False
|
||||
if tmp[1] in ['exp','!exp']:
|
||||
if tmp[1][0] == '!' and not re.findall(tmp[2].replace('*','*?'),itm,re.S|re.I|re.U): was_match = True
|
||||
elif re.findall(tmp[2].replace('*','*?'),itm,re.S|re.I|re.U): was_match = True
|
||||
elif tmp[1] in ['cexp','!cexp']:
|
||||
if tmp[1][0] == '!' and not re.findall(tmp[2].replace('*','*?'),itm,re.S|re.U): was_match = True
|
||||
elif re.findall(tmp[2].replace('*','*?'),itm,re.S|re.U): was_match = True
|
||||
elif tmp[1] in ['sub','!sub']:
|
||||
if tmp[1][0] == '!' and tmp[2].lower() not in itm.lower(): was_match = True
|
||||
elif tmp[2].lower() in itm.lower(): was_match = True
|
||||
elif tmp[1] in ['=','!=']:
|
||||
if tmp[1][0] == '!' and (itm.lower() != tmp[2].lower() or tmp[0] == 'all' and tmp[2].lower() not in (jid.lower(),nick.lower(),'\n'.join(mass).lower())): was_match = True
|
||||
elif itm.lower() == tmp[2].lower() or (tmp[0] == 'all' and tmp[2].lower() in (jid.lower(),nick.lower(),'\n'.join(mass).lower())): was_match = True
|
||||
if was_match: acl_action(tmp[3],nick,jid,room,None)
|
||||
|
||||
def acl_vcard_async(a, nick, jid, room, mass, lvl, is_answ):
|
||||
global acl_vcard_tmp
|
||||
try: vc,err = is_answ[1][1].getTag('vCard',namespace=xmpp.NS_VCARD),False
|
||||
except: vc,err = is_answ[1][0],True
|
||||
if not vc or unicode(vc) == '<vCard xmlns="vcard-temp" />': itm = 'empty'
|
||||
elif err: itm = vc[:VCARD_LIMIT_LONG]
|
||||
else:
|
||||
data = []
|
||||
for t in vc.getChildren():
|
||||
if t.getChildren():
|
||||
cm = []
|
||||
for r in t.getChildren():
|
||||
if r.getData(): cm.append(('%s.%s' % (t.getName(),r.getName()),unicode(r.getData())))
|
||||
data += cm
|
||||
elif t.getData(): data.append((t.getName(),t.getData()))
|
||||
if data:
|
||||
try:
|
||||
photo_size = sys.getsizeof(get_value_from_array2(data,'PHOTO.BINVAL').decode('base64'))
|
||||
photo_type = get_value_from_array2(data,'PHOTO.TYPE')
|
||||
data_photo = '%s, %s' % (photo_type,get_size_human(photo_size))
|
||||
data = [t for t in list(data) if t[0] not in ['PHOTO.BINVAL','PHOTO.TYPE']]
|
||||
data.append(('PHOTO',data_photo))
|
||||
except: pass
|
||||
data.sort()
|
||||
itm = '\n'.join(['%s:%s' % (t[0],t[1].replace('\r','[LF]').replace('\n','[CR]').replace('\t','[TAB]')) for t in data])
|
||||
else: itm = 'empty'
|
||||
|
||||
acl_vcard_tmp['%s/%s' % (room,nick)] = itm
|
||||
for tmp in a:
|
||||
if tmp[0] == 'vcard' and (tmp[5] == 9 or lvl == tmp[5]):
|
||||
was_match = False
|
||||
if tmp[1] in ['exp','!exp']:
|
||||
if tmp[1][0] == '!' and not re.findall(tmp[2].replace('*','*?'),itm,re.S|re.I|re.U): was_match = True
|
||||
elif re.findall(tmp[2].replace('*','*?'),itm,re.S|re.I|re.U): was_match = True
|
||||
elif tmp[1] in ['cexp','!cexp']:
|
||||
if tmp[1][0] == '!' and not re.findall(tmp[2].replace('*','*?'),itm,re.S|re.U): was_match = True
|
||||
elif re.findall(tmp[2].replace('*','*?'),itm,re.S|re.U): was_match = True
|
||||
elif tmp[1] in ['sub','!sub']:
|
||||
if tmp[1][0] == '!' and tmp[2].lower() not in itm.lower(): was_match = True
|
||||
elif tmp[2].lower() in itm.lower(): was_match = True
|
||||
elif tmp[1] in ['=','!=']:
|
||||
if tmp[1][0] == '!' and (itm.lower() != tmp[2].lower() or tmp[0] == 'all' and tmp[2].lower() not in (jid.lower(),nick.lower(),'\n'.join(mass).lower())): was_match = True
|
||||
elif itm.lower() == tmp[2].lower() or (tmp[0] == 'all' and tmp[2].lower() in (jid.lower(),nick.lower(),'\n'.join(mass).lower())): was_match = True
|
||||
if was_match: acl_action(tmp[3],nick,jid,room,None)
|
||||
|
||||
global execute, presence_control, message_act_control
|
||||
|
||||
presence_control = [acl_presence]
|
||||
message_act_control = [acl_message]
|
||||
|
||||
execute = [(7, 'acl', muc_acl, 2, 'Actions list.\nacl show - show list\nacl del [/silent] item - remove item from list\nacl [/time] [/silent] msg|prs|role|aff|nick|jid|jidfull|res|age|ver|vcard|all [sub|exp|cexp] pattern command - execute command by condition\nallowed variables in commands: ${NICK}, ${JID}, ${SERVER}, ${EXP} and ${/EXP}\nsub = substring, exp = regular expression, cexp = case sensitive regular expression\ntime format is /number+identificator. s = sec, m = min, d = day, w = week, M = month, y = year. only one identificator allowed!')]
|
||||
49
plugins/adminmail.py
Normal file
49
plugins/adminmail.py
Normal file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# Copyright (C) dr.Schmurge <dr.schmurge@isida-bot.com> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def adminmail(type, jid, nick, text):
|
||||
if len(text):
|
||||
if len(text) > GT('amsg_limit_size'): text = text[:GT('amsg_limit_size')]+u'[…]'
|
||||
ga = get_level(jid, nick)
|
||||
fjid = getRoom(ga[1])
|
||||
tmp_lim = GT('amsg_limit')[ga[0]]
|
||||
am = cur_execute_fetchone('select time from saytoowner where jid=%s;',(fjid,))
|
||||
if am:
|
||||
wt = int(am[0]-time.time())
|
||||
if wt >= 0:
|
||||
send_msg(type, jid, nick, L('Time limit exceeded. Wait: %s','%s/%s'%(jid,nick)) % un_unix(wt,'%s/%s'%(jid,nick)))
|
||||
return None
|
||||
else: cur_execute('delete from saytoowner where jid=%s;',(fjid,))
|
||||
cur_execute('insert into saytoowner values (%s,%s)',(fjid,int(time.time())+tmp_lim))
|
||||
msg = L('User %s (%s) from %s at %s send massage to you: %s','%s/%s'%(jid,nick)) % (nick,fjid,jid,time.strftime("%H:%M %d.%m.%y", time.localtime (time.time())),text)
|
||||
own = cur_execute_fetchall('select * from bot_owner;')
|
||||
if own:
|
||||
for ajid in own: send_msg('chat', ajid[0], '', msg)
|
||||
send_msg(type, jid, nick, L('Sent','%s/%s'%(jid,nick)))
|
||||
else: send_msg(type, jid, nick, L('Owner list is empty!','%s/%s'%(jid,nick)))
|
||||
else: send_msg(type, jid, nick, L('What?','%s/%s'%(jid,nick)))
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(4, 'msgtoadmin', adminmail, 2, 'Send message to bot\'s owner\nmsgtoadmin text')]
|
||||
221
plugins/age.py
Normal file
221
plugins/age.py
Normal file
@@ -0,0 +1,221 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
AGE_DEFAULT_LIMIT = 10
|
||||
AGE_MAX_LIMIT = 100
|
||||
TIME_OF_LOGGING_JOINS = 1357231720
|
||||
|
||||
def join_time_stat(type, jid, nick, text):
|
||||
text = text.strip()
|
||||
if text and text.isdigit(): llim = int(text)
|
||||
else:
|
||||
try: llim = GT('age_default_limit')
|
||||
except: llim = AGE_DEFAULT_LIMIT
|
||||
if llim not in range(1,AGE_MAX_LIMIT): llim = AGE_DEFAULT_LIMIT
|
||||
t_age_tmp = cur_execute_fetchall(' select jid,time from first_join where room=%s and jid in (select jid from age where room=%s and status=0 order by time) order by time limit %s;',(jid,jid,llim))
|
||||
t_age = []
|
||||
for t in t_age_tmp:
|
||||
tmp = cur_execute_fetchone('select nick from age where room=%s and jid=%s order by status,-time',(jid,t[0]))
|
||||
t_age.append((tmp[0],t[1]))
|
||||
msg = L('Joins statistic:\n%s','%s/%s'%(jid,nick)) % '\n'.join(['%s\t %s%s' % (t[0],['','~'][t[1]<TIME_OF_LOGGING_JOINS],nice_time(t[1],'%s/%s'%(jid,nick))[2].split(', GMT',1)[0]) for t in t_age])
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def join_time(type, jid, nick, text):
|
||||
if not text: text = nick
|
||||
lvl,r_jid = get_level(jid,text)
|
||||
if lvl != -2:
|
||||
j_time = cur_execute_fetchone('select time from first_join where room=%s and jid=%s;',(jid,getRoom(r_jid)))[0]
|
||||
msg = L('First %s\'s join is %s%s (%s ago)','%s/%s'%(jid,nick)) % (text,['','~'][j_time<TIME_OF_LOGGING_JOINS],nice_time(j_time,'%s/%s'%(jid,nick))[2],un_unix(int(time.time())-j_time,'%s/%s'%(jid,nick)))
|
||||
else: msg = L('Not found!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def true_age_stat(type, jid, nick, text):
|
||||
text = text.strip()
|
||||
if text and text.isdigit(): llim = int(text)
|
||||
else:
|
||||
try: llim = GT('age_default_limit')
|
||||
except: llim = AGE_DEFAULT_LIMIT
|
||||
if llim not in range(1,AGE_MAX_LIMIT): llim = AGE_DEFAULT_LIMIT
|
||||
if base_type == 'pgsql': reqv = 'select jid,sum(age+(status = 0)::boolean::int*(%s-time)) as sum_age from age where room=%s group by jid order by sum_age desc limit %s;'
|
||||
elif base_type in ['sqlite3','mysql']: reqv = 'select jid,sum(age+(status = 0)*(%s-time)) as sum_age from age where room=%s group by jid order by sum_age desc limit %s;'
|
||||
else: return
|
||||
t_age_tmp = cur_execute_fetchall(reqv,(int(time.time()),jid,llim))
|
||||
t_age = []
|
||||
for t in t_age_tmp:
|
||||
tmp = cur_execute_fetchone('select nick from age where room=%s and jid=%s order by status,-time',(jid,t[0]))
|
||||
t_age.append((tmp[0],t[1]))
|
||||
msg = L('Age statistic:\n%s','%s/%s'%(jid,nick)) % '\n'.join(['%s\t%s' % (t[0],un_unix(t[1],'%s/%s'%(jid,nick))) for t in t_age])
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def true_age_split(type, jid, nick, text):
|
||||
true_age_raw(type, jid, nick, text, True)
|
||||
|
||||
def true_age(type, jid, nick, text):
|
||||
true_age_raw(type, jid, nick, text, None)
|
||||
|
||||
def true_age_raw(type, jid, nick, text, xtype):
|
||||
text = text.rstrip().split('\n')
|
||||
llim = 10
|
||||
if len(text) > 1:
|
||||
try: llim = int(text[1])
|
||||
except: llim = GT('age_default_limit')
|
||||
text = text[0]
|
||||
if not text: text = nick
|
||||
if llim > GT('age_max_limit'): llim = GT('age_max_limit')
|
||||
real_jid = cur_execute_fetchone('select jid from age where room=%s and (nick=%s or jid=%s) order by -time,status',(jid,text,text.lower()))
|
||||
if not real_jid:
|
||||
text = '%%%s%%' % text.lower()
|
||||
real_jid = cur_execute_fetchone('select jid from age where room=%s and (no_case_nick ilike %s or jid ilike %s) order by -time,status',(jid,text,text))
|
||||
try:
|
||||
if xtype: sbody = cur_execute_fetchall('select * from age where room=%s and jid=%s order by -time,status limit %s',(jid,real_jid[0],llim))
|
||||
else:
|
||||
t_age = cur_execute_fetchone('select sum(age) from age where room=%s and jid=%s',(jid,real_jid[0]))
|
||||
sbody = cur_execute_fetchone('select * from age where room=%s and jid=%s order by -time,status',(jid,real_jid[0]))
|
||||
sbody = [sbody[:4] + t_age + sbody[5:]]
|
||||
except: sbody = None
|
||||
if sbody:
|
||||
msg = L('I see:','%s/%s'%(jid,nick))
|
||||
for cnt, tmp in enumerate(sbody):
|
||||
if tmp[5]: r_age = tmp[4]
|
||||
else: r_age = int(time.time()) - tmp[3] + tmp[4]
|
||||
if xtype: msg += '\n%s. %s' % (cnt + 1, tmp[1])
|
||||
else: msg += ' %s' % tmp[1]
|
||||
msg += '\t%s, ' % un_unix(r_age,'%s/%s'%(jid,nick))
|
||||
if tmp[5]:
|
||||
if tmp[6]: msg += L('%s %s ago','%s/%s'%(jid,nick)) % (tmp[6], un_unix(int(time.time() - tmp[3]),'%s/%s'%(jid,nick)))
|
||||
else: msg += L('Leave %s ago','%s/%s'%(jid,nick)) % un_unix(int(time.time() - tmp[3]),'%s/%s'%(jid,nick))
|
||||
t7sp = tmp[7].split('\r')[0]
|
||||
if t7sp.count('\n') > 3:
|
||||
stat = t7sp.split('\n', 4)[4]
|
||||
if stat: msg += ' (%s)' % stat
|
||||
elif t7sp: msg += ' (%s)' % t7sp
|
||||
if '\r' in tmp[7]: msg += ', %s %s' % (L('Client:','%s/%s'%(jid,nick)),' // '.join(tmp[7].split('\r')[-1].split(' // ')[:-1]))
|
||||
else: msg += L('Is here: %s','%s/%s'%(jid,nick)) % un_unix(int(time.time() - tmp[3]),'%s/%s'%(jid,nick))
|
||||
if not xtype: msg = msg.replace('\t', ' - ')
|
||||
else: msg = L('Not found!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def seen(type, jid, nick, text):
|
||||
seen_raw(type, jid, nick, text, None)
|
||||
|
||||
def seen_split(type, jid, nick, text):
|
||||
seen_raw(type, jid, nick, text, True)
|
||||
|
||||
def seen_raw(type, jid, nick, text, xtype):
|
||||
text = text.rstrip().split('\n')
|
||||
llim = GT('age_default_limit')
|
||||
if len(text)>1:
|
||||
try: llim = int(text[1])
|
||||
except: llim = GT('age_default_limit')
|
||||
text = text[0]
|
||||
if not text: text = nick
|
||||
if llim > GT('age_max_limit'): llim = GT('age_max_limit')
|
||||
real_jid = cur_execute_fetchone('select jid from age where room=%s and (nick=%s or jid=%s) order by status,-time',(jid,text,text.lower()))
|
||||
if not real_jid:
|
||||
textt = '%%%s%%' % text.lower()
|
||||
real_jid = cur_execute_fetchone('select jid from age where room=%s and (no_case_nick ilike %s or jid ilike %s) order by status,-time',(jid,textt,textt))
|
||||
if real_jid:
|
||||
if xtype: sbody = cur_execute_fetchall('select * from age where room=%s and jid=%s order by status,-time limit %s',(jid,real_jid[0],llim))
|
||||
else: sbody = [cur_execute_fetchone('select * from age where room=%s and jid=%s order by status,-time',(jid,real_jid[0]))]
|
||||
else: sbody = None
|
||||
if sbody:
|
||||
msg = L('I see:','%s/%s'%(jid,nick))
|
||||
for cnt, tmp in enumerate(sbody):
|
||||
if xtype: msg += '\n%s. ' % (cnt+1)
|
||||
else: msg += ' '
|
||||
if text != tmp[1]: msg += L('%s (with nick: %s)','%s/%s'%(jid,nick)) % (text,tmp[1])
|
||||
else: msg += tmp[1]
|
||||
if tmp[5]:
|
||||
if tmp[6]: msg += ' - ' + L('%s %s ago','%s/%s'%(jid,nick)) % (tmp[6], un_unix(int(time.time() - tmp[3]),'%s/%s'%(jid,nick)))
|
||||
else: msg += ' - ' + L('Leave %s ago','%s/%s'%(jid,nick)) % un_unix(int(time.time() - tmp[3]),'%s/%s'%(jid,nick))
|
||||
t7sp = tmp[7].split('\r')[0]
|
||||
if t7sp.count('\n') > 3:
|
||||
stat = t7sp.split('\n',4)[4]
|
||||
if stat: msg += ' (%s)' % stat
|
||||
elif t7sp: msg += ' (%s)' % t7sp
|
||||
if '\r' in tmp[7]: msg += ', %s %s' % (L('Client:','%s/%s'%(jid,nick)),' // '.join(tmp[7].split('\r')[-1].split(' // ')[:-1]))
|
||||
else: msg += ' - '+ L('Is here: %s','%s/%s'%(jid,nick)) % un_unix(int(time.time()-tmp[3]),'%s/%s'%(jid,nick))
|
||||
else: msg = L('Not found!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def seenjid(type, jid, nick, text):
|
||||
seenjid_raw(type, jid, nick, text, None)
|
||||
|
||||
def seenjid_split(type, jid, nick, text):
|
||||
seenjid_raw(type, jid, nick, text, True)
|
||||
|
||||
def seenjid_raw(type, jid, nick, text, xtype):
|
||||
text = text.rstrip().split('\n')
|
||||
llim = GT('age_default_limit')
|
||||
if len(text)>1:
|
||||
try: llim = int(text[1])
|
||||
except: llim = GT('age_default_limit')
|
||||
text = text[0]
|
||||
ztype = None
|
||||
if not text: text = nick
|
||||
if llim > GT('age_max_limit'): llim = GT('age_max_limit')
|
||||
real_jid = cur_execute_fetchall('select jid from age where room=%s and (nick ilike %s or jid ilike %s) group by jid,status,time order by status,-time',(jid,text,text.lower()))
|
||||
if not real_jid:
|
||||
txt = '%%%s%%' % text.lower()
|
||||
real_jid = cur_execute_fetchall('select jid from age where room=%s and (no_case_nick ilike %s or jid ilike %s) group by jid,status,time order by status,-time',(jid,txt,txt))
|
||||
sbody = []
|
||||
if real_jid:
|
||||
for rj in real_jid:
|
||||
if xtype: tmpbody = cur_execute_fetchall('select * from age where room=%s and jid=%s order by status, jid limit %s',(jid,rj[0],llim))
|
||||
else: tmpbody = [cur_execute_fetchone('select * from age where room=%s and jid=%s order by status',(jid,rj[0]))]
|
||||
if tmpbody:
|
||||
for t in tmpbody:
|
||||
if t not in sbody: sbody.append(t)
|
||||
if sbody:
|
||||
ztype = True
|
||||
msg = L('I saw %s:','%s/%s'%(jid,nick)) % text
|
||||
for cnt, tmp in enumerate(sbody):
|
||||
msg += '\n%s. %s (%s)' % (cnt + 1, tmp[1], tmp[2])
|
||||
if tmp[5]:
|
||||
if tmp[6]: msg += '\t' + L('%s %s ago','%s/%s'%(jid,nick)) % (tmp[6], un_unix(int(time.time() - tmp[3]),'%s/%s'%(jid,nick)))
|
||||
else: msg += '\t' + L('Leave %s ago','%s/%s'%(jid,nick)) % un_unix(int(time.time() - tmp[3]),'%s/%s'%(jid,nick))
|
||||
t7sp = tmp[7].split('\r')[0]
|
||||
if t7sp.count('\n') > 3:
|
||||
stat = t7sp.split('\n', 4)[4]
|
||||
if stat: msg += ' (%s)' % stat
|
||||
elif t7sp: msg += ' (%s)' % t7sp
|
||||
if '\r' in tmp[7]: msg += ', %s %s' % (L('Client:','%s/%s'%(jid,nick)), tmp[7].split('\r')[-1])
|
||||
else: msg += '\t' + L('Is here: %s','%s/%s'%(jid,nick)) % un_unix(int(time.time() - tmp[3]),'%s/%s'%(jid,nick))
|
||||
if not xtype: msg = msg.replace('\t', ' - ')
|
||||
else: msg = L('Not found!','%s/%s'%(jid,nick))
|
||||
if type == 'groupchat' and ztype:
|
||||
send_msg(type, jid, nick, L('Send for you in private','%s/%s'%(jid,nick)))
|
||||
send_msg('chat', jid, nick, msg)
|
||||
else: send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'age', true_age, 2, 'Show age of jid in conference.'),
|
||||
(3, 'age_split', true_age_split, 2, 'Show age of jid in conference splitted by nicks.'),
|
||||
(3, 'seen', seen, 2, 'Show time of join/leave.'),
|
||||
(3, 'seen_split', seen_split, 2, 'Show time of join/leave splitted by nicks.'),
|
||||
(3, 'agestat', true_age_stat, 2, 'Show age statistic for conference.'),
|
||||
(7, 'seenjid', seenjid, 2, 'Show time of join/leave + jid.'),
|
||||
(7, 'seenjid_split', seenjid_split, 2, 'Show time of join/leave + jid splitted by nicks.'),
|
||||
(3, 'when', join_time, 2, 'Show time of first join into room.'),
|
||||
(3, 'whenstat', join_time_stat, 2, 'Show statistic for time of first join into room.')]
|
||||
108
plugins/ai.py
Normal file
108
plugins/ai.py
Normal file
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
# [u'devel@conference.jabber.ru', u'sulci', u'moderator', u'admin', u'sulci@jabber.ru/Ocaml']
|
||||
|
||||
AI_PREV = {}
|
||||
AI_PHRASES_FOLDER = data_folder % 'ai/%s'
|
||||
AI_PHRASES_FILES = [t for t in os.listdir(AI_PHRASES_FOLDER % '') if t.endswith('.txt') and os.path.isfile(AI_PHRASES_FOLDER % t)]
|
||||
AI_PHRASES = {}
|
||||
|
||||
for PH_LANG in AI_PHRASES_FILES:
|
||||
PH_L = PH_LANG.split('.',1)[0]
|
||||
PHRASES = readfile(AI_PHRASES_FOLDER % PH_LANG).decode('utf-8').replace('\r','').split('\n')
|
||||
for LINE in PHRASES:
|
||||
if LINE.strip() and not LINE.strip().startswith('#') and '\t' in LINE:
|
||||
if not AI_PHRASES.has_key(PH_L): AI_PHRASES[PH_L] = [LINE.split('\t',1)]
|
||||
else: AI_PHRASES[PH_L].append(LINE.split('\t',1))
|
||||
|
||||
def AI_PARSE(room, jid, nick, type, text):
|
||||
if not get_config(room,'ai'): return
|
||||
LOC = get_L_('%s/%s' % (room,nick))
|
||||
TEXT = ' %s ' % text.lower()
|
||||
SCORE, CMD = 1.0, []
|
||||
for PHRASES in AI_PHRASES[LOC]:
|
||||
CUR_SCORE = AI_RATING(PHRASES[1].split('||')[0], TEXT, room)
|
||||
if CUR_SCORE > SCORE: SCORE, CMD = CUR_SCORE, [PHRASES]
|
||||
elif CUR_SCORE == SCORE: CMD.append(PHRASES)
|
||||
if not CMD: return
|
||||
pprint('AI score %s|%s|%s' % (SCORE, '|'.join([t[0] for t in CMD]), text),'cyan')
|
||||
CMD = random.choice(CMD)
|
||||
CMD_RAW = CMD[0].split()[0]
|
||||
pprint('AI selected %s' % CMD_RAW,'cyan')
|
||||
|
||||
nowname = getResourse(cur_execute_fetchone('select room from conference where room ilike %s',('%s/%%'%room,))[0])
|
||||
access_mode = get_level(room,nick)[0]
|
||||
if cur_execute_fetchone('select * from commonoff where room=%s and cmd=%s',(room,CMD_RAW)): return
|
||||
ptype = ''
|
||||
for t in comms:
|
||||
if t[1] == CMD_RAW:
|
||||
ptype = t[-1]
|
||||
break
|
||||
if 'nick' in ptype and '||' in CMD[1]:
|
||||
for t in CMD[1].split('||')[1].split('|'):
|
||||
text = text.replace(t,nick)
|
||||
PRM = AI_PARAMETER(text, ptype, room)
|
||||
|
||||
if 'nick' in ptype:
|
||||
PP = None
|
||||
for t in PRM:
|
||||
if t:
|
||||
PP = True
|
||||
break
|
||||
if not PP: PRM.append(nick)
|
||||
|
||||
for PARAM in PRM:
|
||||
if PARAM:
|
||||
COMMAND = CMD[0].replace('{PAR}',PARAM)
|
||||
print COMMAND
|
||||
com_parser(access_mode, nowname, type, room, nick, COMMAND, jid)
|
||||
|
||||
def AI_RATING(s, text, room):
|
||||
r,s = 0.0,s.split('|')
|
||||
for k in s:
|
||||
if k in text: r += 0.5
|
||||
if k in AI_PREV.get(room, ''): r += 0.34
|
||||
return r
|
||||
|
||||
def AI_PARAMETER(body, type, room):
|
||||
P_NICK, P_JID, P_SERVER = None, None, None
|
||||
|
||||
if 'nick' in type:
|
||||
NICKS = [t[1] for t in megabase if t[0]==room]
|
||||
for NICK in NICKS:
|
||||
if NICK in body:
|
||||
P_NICK = NICK
|
||||
break
|
||||
|
||||
if 'jid' in type:
|
||||
JID = re.findall(u'[-a-z0-9а-яё_]+@[-0-9a-z\.]+',body,re.S|re.I|re.U)
|
||||
if JID: P_JID = JID[0]
|
||||
|
||||
if 'server' in type:
|
||||
SERVER = re.findall(u'[-0-9a-zа-яё\.]+\.[-a-zа-я]{2,}',body,re.S|re.I|re.U)
|
||||
if SERVER: P_SERVER = SERVER[0]
|
||||
|
||||
return [P_NICK, P_JID, P_SERVER]
|
||||
|
||||
gmessage.append(AI_PARSE)
|
||||
44
plugins/anek.py
Normal file
44
plugins/anek.py
Normal file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) ferym <ferym@jabbim.org.ru> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def anek(type, jid, nick):
|
||||
try:
|
||||
target = load_page('http://anekdot.odessa.ua/rand-anekdot.php')
|
||||
od = re.search('background-color:#FFFFFF\'>',target)
|
||||
message = target[od.end():]
|
||||
message = message[:re.search('<br>',message).start()]
|
||||
message = message.replace('<br />','')
|
||||
message = message.strip()
|
||||
message = rss_replace(unicode(message,'windows-1251'))
|
||||
if type=='groupchat':
|
||||
if len(message) < GT('anek_private_limit'): send_msg(type, jid, nick, message)
|
||||
else:
|
||||
send_msg(type, jid, nick, L('Send for you in private','%s/%s'%(jid,nick)))
|
||||
send_msg('chat', jid, nick, message)
|
||||
return
|
||||
else: send_msg(type, jid, nick, message)
|
||||
except: send_msg(type, jid, nick, L('Something broken.','%s/%s'%(jid,nick)))
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'anek', anek, 1, 'Show random anecdote | Author: ferym')]
|
||||
54
plugins/answers.py
Normal file
54
plugins/answers.py
Normal file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def answers_ie(type, jid, nick, text):
|
||||
if text.lower().strip().split(' ',1)[0] == 'export':
|
||||
try: fname = text.lower().split(' ',1)[1]
|
||||
except: fname = answers_file
|
||||
base_size = len(cur_execute_fetchall('select * from answer'))
|
||||
fnd = cur_execute_fetchall('select body from answer where body ilike %s group by body order by body',('%',))
|
||||
answer = ''
|
||||
msg = L('Export to file: %s | Total records: %s | Unique records: %s','%s/%s'%(jid,nick)) % (fname,base_size,len(fnd))
|
||||
for i in fnd:
|
||||
if i[0] != '': answer += i[0].strip() +'\n'
|
||||
writefile(fname,answer.encode('utf-8'))
|
||||
elif text.lower().strip().split(' ',1)[0] == 'import':
|
||||
try: fname = text.lower().split(' ',1)[1]
|
||||
except: fname = answers_file
|
||||
if os.path.isfile(fname):
|
||||
answer = readfile(fname).decode('utf-8')
|
||||
answer = answer.split('\n')
|
||||
cur_execute('delete from answer where body ilike %s',('%',))
|
||||
msg = L('Import from file: %s | Total records: %s','%s/%s'%(jid,nick)) % (fname,len(answer))
|
||||
idx = 1
|
||||
for i in answer:
|
||||
if i != '':
|
||||
cur_execute('insert into answer values (%s,%s)', (idx,unicode(i.strip())))
|
||||
idx += 1
|
||||
else: msg = L('File %s not found!','%s/%s'%(jid,nick)) % fname
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(9, 'answers', answers_ie, 2, 'Import/Export answers base.\nanswers import [filename] - import from file\nanswers export [filename] - export to file')]
|
||||
45
plugins/antitroll.py
Normal file
45
plugins/antitroll.py
Normal file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def troll(type, jid, nick, text):
|
||||
text = text.split('\n')
|
||||
r = unicode(text[0])
|
||||
try: count = int(text[2])
|
||||
except: count = GT('troll_default_limit')
|
||||
if count > GT('troll_max_limit'): count = GT('troll_max_limit')
|
||||
otake = xmpp.JID(node=getName(jid), domain=getServer(jid), resource=r)
|
||||
otake = unicode(otake)
|
||||
if len(text)>1: message = text[1]
|
||||
else: message = L('You troll!','%s/%s'%(jid,nick))
|
||||
tst = GT('troll_sleep_time')
|
||||
while count != 0:
|
||||
sender(xmpp.Message(otake, message, "chat"))
|
||||
time.sleep(tst)
|
||||
count -= 1
|
||||
send_msg(type, jid, nick, L('Done','%s/%s'%(jid,nick)))
|
||||
|
||||
global execute, timer
|
||||
|
||||
timer = []
|
||||
|
||||
execute = [(9, 'troll', troll, 2, 'Repeat message to private.\ntroll nick\n[text]\n[number]')]
|
||||
166
plugins/backup.py
Normal file
166
plugins/backup.py
Normal file
@@ -0,0 +1,166 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
backup_async = {}
|
||||
|
||||
def getMucItems(jid,affil,ns,back_id):
|
||||
iqid = get_id()
|
||||
if ns == xmpp.NS_MUC_ADMIN: i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':getRoom(jid)}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'affiliation':affil})])])
|
||||
else: i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':getRoom(jid)}, payload = [xmpp.Node('query', {'xmlns': ns},[])])
|
||||
iq_request[iqid]=(time.time(),getMucItems_async,[ns,affil,back_id],ns)
|
||||
sender(i)
|
||||
|
||||
def getMucItems_async(ns,affil,back_id,iq_stanza):
|
||||
global backup_async
|
||||
iq_stanza = iq_stanza[1][0]
|
||||
if ns == xmpp.NS_MUC_ADMIN: backup_async[back_id][affil] = [[tmp.getAttr('jid'),['',tmp.getTagData('reason')][tmp.getTagData('reason') != None]] for tmp in iq_stanza.getTag('query',namespace=xmpp.NS_MUC_ADMIN).getTags('item')]
|
||||
else: backup_async[back_id]['room_config'] = [[tmp.getAttr('var'),tmp.getAttr('type'),tmp.getTagData('value')] for tmp in iq_stanza.getTag('query',namespace=xmpp.NS_MUC_OWNER).getTag('x',namespace=xmpp.NS_DATA).getTags('field')]
|
||||
|
||||
def make_stanzas_array(raw_back,jid,affil):
|
||||
stanza_array = []
|
||||
try: make_stanza_jid_count = get_config_int(jid,'make_stanza_jid_count')
|
||||
except: make_stanza_jid_count = 1
|
||||
for tmp in range(0,len(raw_back),make_stanza_jid_count):
|
||||
i = xmpp.Iq(typ='set',to=jid,xmlns=xmpp.NS_CLIENT)
|
||||
i.setTag('query',namespace=xmpp.NS_MUC_ADMIN)
|
||||
for t in raw_back[tmp:tmp+make_stanza_jid_count]:
|
||||
i.getTag('query',namespace=xmpp.NS_MUC_ADMIN).\
|
||||
setTag('item',attrs={'affiliation':affil,'jid':t[0]}).\
|
||||
setTagData('reason',t[1])
|
||||
stanza_array.append(i)
|
||||
return stanza_array
|
||||
|
||||
def conf_backup(type, jid, nick, text):
|
||||
global backup_async,conn
|
||||
if len(text):
|
||||
text = text.split(' ')
|
||||
mode = text[0]
|
||||
|
||||
if mode == 'show':
|
||||
a = os.listdir(back_folder % '')
|
||||
b = []
|
||||
for c in a:
|
||||
if not c.endswith('.txt') and not c.endswith('.back'): b.append((c,os.path.getmtime(back_folder % c)))
|
||||
if len(b): msg = '%s %s' % (L('Available copies:','%s/%s'%(jid,nick)), ', '.join(['%s (%s)' % (c[0],disp_time(c[1],'%s/%s'%(jid,nick))) for c in b]))
|
||||
else: msg = L('Backup copies not found.','%s/%s'%(jid,nick))
|
||||
elif mode == 'now':
|
||||
|
||||
if get_xtype(jid) != 'owner': msg = L('I need an owner affiliation for backup settings!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
back_id = get_id()
|
||||
backup_async[back_id] = {}
|
||||
getMucItems(jid,'outcast',xmpp.NS_MUC_ADMIN,back_id)
|
||||
getMucItems(jid,'member',xmpp.NS_MUC_ADMIN,back_id)
|
||||
getMucItems(jid,'admin',xmpp.NS_MUC_ADMIN,back_id)
|
||||
getMucItems(jid,'owner',xmpp.NS_MUC_ADMIN,back_id)
|
||||
getMucItems(jid,'',xmpp.NS_MUC_OWNER,back_id)
|
||||
bst = GT('backup_sleep_time')
|
||||
while len(backup_async[back_id]) != 5 and not game_over: time.sleep(bst)
|
||||
iqid = get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'set', 'to':jid}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'affiliation':'admin', 'jid':getRoom(str(selfjid))},[])])])
|
||||
sender(i)
|
||||
backup_async[back_id]['alias'] = cur_execute_fetchall('select match ,cmd from alias where room=%s',(jid,))
|
||||
backup_async[back_id]['bot_config'] = cur_execute_fetchall('select option ,value from config_conf where room=%s',(jid,))
|
||||
backup_async[back_id]['acl'] = cur_execute_fetchall('select action,type,text,command,time,level from acl where jid=%s',(jid,))
|
||||
backup_async[back_id]['rss'] = cur_execute_fetchall('select url, update ,type,time,hash from feed where room=%s',(jid,))
|
||||
|
||||
msg = L('Copying completed!','%s/%s'%(jid,nick))
|
||||
msg += L('\nOwners: %s | Admins: %s | Members: %s | Banned: %s','%s/%s'%(jid,nick)) % (\
|
||||
len(backup_async[back_id]['owner'])-1,\
|
||||
len(backup_async[back_id]['admin'])+1,\
|
||||
len(backup_async[back_id]['member']),\
|
||||
len(backup_async[back_id]['outcast']))
|
||||
|
||||
msg += L('\nRoom config: %s | Bot config: %s | Aliases: %s | Acl\'s: %s | RSS: %s','%s/%s'%(jid,nick)) % (\
|
||||
len(backup_async[back_id]['room_config']),\
|
||||
len(backup_async[back_id]['bot_config']),\
|
||||
len(backup_async[back_id]['alias']),\
|
||||
len(backup_async[back_id]['acl']),\
|
||||
len(backup_async[back_id]['rss']))
|
||||
|
||||
writefile(back_folder % unicode(jid),json.dumps(backup_async[back_id]))
|
||||
|
||||
elif mode == 'restore':
|
||||
if len(text)>1:
|
||||
if text[1] in os.listdir(back_folder % ''):
|
||||
if text[1].endswith('.acl'):
|
||||
raw_back = json.loads(readfile(back_folder % unicode(text[1])))
|
||||
cnt = 0
|
||||
for tmp in raw_back:
|
||||
isit = cur_execute_fetchall('select action,type,text,command,time from acl where jid=%s and action=%s and type=%s and text=%s and level=%s',(jid,tmp[0],tmp[1],tmp[2],tmp[5]))
|
||||
if not isit:
|
||||
cur_execute('insert into acl values (%s,%s,%s,%s,%s,%s,%s)', tmp)
|
||||
cnt += 1
|
||||
msg = L('Restored %s action(s).','%s/%s'%(jid,nick)) % cnt
|
||||
elif get_xtype(jid) != 'owner': msg = L('I need an owner affiliation for restore settings!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
bst = GT('backup_sleep_time')
|
||||
raw_back=json.loads(readfile(back_folder % unicode(text[1])))
|
||||
for tmp in ['outcast','member','admin','owner']:
|
||||
for t in make_stanzas_array(raw_back[tmp],jid,tmp):
|
||||
sender(t)
|
||||
time.sleep(bst)
|
||||
i = xmpp.Iq(typ='set',to=jid,xmlns=xmpp.NS_CLIENT)
|
||||
i.setTag('query',namespace=xmpp.NS_MUC_OWNER)
|
||||
i.getTag('query',namespace=xmpp.NS_MUC_OWNER).setTag('x',namespace=xmpp.NS_DATA).setAttr('type','submit')
|
||||
for tmp in raw_back['room_config']:
|
||||
i.getTag('query',namespace=xmpp.NS_MUC_OWNER).getTag('x',namespace=xmpp.NS_DATA).\
|
||||
setTag('field',attrs={'var':tmp[0],'type':tmp[1]}).\
|
||||
setTagData('value',tmp[2])
|
||||
sender(i)
|
||||
time.sleep(bst)
|
||||
sender(xmpp.Node('iq', {'id': get_id(), 'type': 'set', 'to':jid}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'affiliation':'admin', 'jid':getRoom(unicode(selfjid))},[])])]))
|
||||
time.sleep(bst)
|
||||
cur_execute_fetchall('delete from config_conf where room=%s',(jid,))
|
||||
for tmp in raw_back['bot_config']: cur_execute('insert into config_conf (room, option ,value) values (%s,%s,%s)',(jid,tmp[0],tmp[1]))
|
||||
for tmp in raw_back['alias']:
|
||||
cur_execute('delete from alias where room=%s and match =%s',(jid,tmp[0]))
|
||||
cur_execute('insert into alias (room, match ,cmd) values (%s,%s,%s)',(jid,tmp[0],tmp[1]))
|
||||
for tmp in raw_back['acl']:
|
||||
isit = cur_execute_fetchall('select action,type,text,command,time from acl where jid=%s and action=%s and type=%s and text=%s and level=%s',(jid,tmp[0],tmp[1],tmp[2],tmp[5]))
|
||||
if not isit: cur_execute('insert into acl values (%s,%s,%s,%s,%s,%s,%s)', tuple([jid]+list(tmp)))
|
||||
for tmp in raw_back['rss']:
|
||||
isit = cur_execute_fetchone('select * from feed where room=%s and url=%s',(jid,tmp[0]))
|
||||
if not isit: cur_execute('insert into feeed (url, update ,type,time,room,hash) values (%s,%s,%s,%s,%s,%s)',(tmp[0],tmp[1],tmp[2],tmp[3],jid,tmp[4]))
|
||||
msg = L('Restore completed.','%s/%s'%(jid,nick))
|
||||
msg += L('\nOwners: %s | Admins: %s | Members: %s | Banned: %s','%s/%s'%(jid,nick)) % (\
|
||||
len(raw_back['owner'])-1,\
|
||||
len(raw_back['admin'])+1,\
|
||||
len(raw_back['member']),\
|
||||
len(raw_back['outcast']))
|
||||
|
||||
msg += L('\nRoom config: %s | Bot config: %s | Aliases: %s | Acl\'s: %s | RSS: %s','%s/%s'%(jid,nick)) % (\
|
||||
len(raw_back['room_config']),\
|
||||
len(raw_back['bot_config']),\
|
||||
len(raw_back['alias']),\
|
||||
len(raw_back['acl']),\
|
||||
len(raw_back['rss']))
|
||||
else: msg = L('Copy not found. Use key "show" for lisen available copies.','%s/%s'%(jid,nick))
|
||||
else: msg = L('What do you want to restore?','%s/%s'%(jid,nick))
|
||||
else: msg = L('Unknown item!','%s/%s'%(jid,nick))
|
||||
else: msg = 'backup now|show|restore'
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(8, 'backup', conf_backup, 2, 'Backup/restore conference settings.\nbackup show|now|restore\nshow - show available copies\nnow - backup current conference\nrestore name_conference - restore settings name_conference in current conference')]
|
||||
51
plugins/bash.py
Normal file
51
plugins/bash.py
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def bash_org_ru(type, jid, nick, text):
|
||||
text = text.strip()
|
||||
if not text: url = 'http://bash.org.ru/random'
|
||||
elif re.match('\d+$', text): url = 'http://bash.org.ru/quote/%s' % text
|
||||
else: url = 'http://bash.org.ru/?text=%s' % urllib.quote(text.encode('cp1251'))
|
||||
body = html_encode(load_page(url))
|
||||
body = re.findall('<span class="date">(.*?)</span>.*?class="id">(.*?)</a>.*?<div class="text">(.*?)</div>',body,re.S|re.I|re.U)
|
||||
try: msg = rss_del_nn(rss_replace('%s %s\n%s' % body[0]))
|
||||
except: msg = L('Quote not found!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def ibash_org_ru(type, jid, nick, text):
|
||||
reg_title = '<div class="quothead">.*?<b>#(.*?)</b>'
|
||||
reg_body = '<div class="quotbody">(.*?)</div>'
|
||||
url_id = 'http://ibash.org.ru/quote.php?id='
|
||||
try: url = url_id+str(int(text))
|
||||
except: url = 'http://ibash.org.ru/random.php'
|
||||
body = html_encode(load_page(url))
|
||||
msg = url_id + re.findall(reg_title, body, re.S)[0]
|
||||
if msg[-3:] == '???': msg = L('Quote not found!','%s/%s'%(jid,nick))
|
||||
else: msg += '\n'+rss_replace(re.findall(reg_body, body, re.S)[0])
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'bash', bash_org_ru, 2, 'Quote from bash.org.ru\nbash [number]'),
|
||||
(3, 'ibash', ibash_org_ru, 2, 'Quote from ibash.org.ru\nibash [number]')]
|
||||
|
||||
75
plugins/bing.py
Normal file
75
plugins/bing.py
Normal file
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def bing_translate(type, jid, nick, text):
|
||||
text = text.strip()
|
||||
trlang = {'id':L('Indonesian','%s/%s'%(jid,nick)), 'it':L('Italian','%s/%s'%(jid,nick)), 'ar':L('Arabic','%s/%s'%(jid,nick)),
|
||||
'ja':L('Japanese','%s/%s'%(jid,nick)), 'bg':L('Bulgarian','%s/%s'%(jid,nick)), 'ko':L('Korean','%s/%s'%(jid,nick)),
|
||||
'ca':L('Catalan','%s/%s'%(jid,nick)), 'lv':L('Latvian','%s/%s'%(jid,nick)), 'zh-chs':L('Chinese Simplified','%s/%s'%(jid,nick)),
|
||||
'lt':L('Lithuanian','%s/%s'%(jid,nick)), 'zh-cht':L('Chinese Traditional','%s/%s'%(jid,nick)), 'no':L('Norwegian','%s/%s'%(jid,nick)),
|
||||
'cs':L('Czech','%s/%s'%(jid,nick)), 'pl':L('Polish','%s/%s'%(jid,nick)), 'da':L('Danish','%s/%s'%(jid,nick)),
|
||||
'pt':L('Portuguese','%s/%s'%(jid,nick)), 'nl':L('Dutch','%s/%s'%(jid,nick)), 'ro':L('Romanian','%s/%s'%(jid,nick)),
|
||||
'en':L('English','%s/%s'%(jid,nick)), 'ru':L('Russian','%s/%s'%(jid,nick)), 'et':L('Estonian','%s/%s'%(jid,nick)),
|
||||
'sk':L('Slovak','%s/%s'%(jid,nick)), 'fi':L('Finnish','%s/%s'%(jid,nick)), 'sl':L('Slovenian','%s/%s'%(jid,nick)),
|
||||
'fr':L('French','%s/%s'%(jid,nick)), 'es':L('Spanish','%s/%s'%(jid,nick)), 'de':L('German','%s/%s'%(jid,nick)),
|
||||
'sv':L('Swedish','%s/%s'%(jid,nick)), 'el':L('Greek','%s/%s'%(jid,nick)), 'th':L('Thai','%s/%s'%(jid,nick)),
|
||||
'ht':L('Haitian Creole','%s/%s'%(jid,nick)), 'tr':L('Turkish','%s/%s'%(jid,nick)), 'he':L('Hebrew','%s/%s'%(jid,nick)),
|
||||
'uk':L('Ukrainian','%s/%s'%(jid,nick)), 'hi':L('Hindi','%s/%s'%(jid,nick)), 'vi':L('Vietnamese','%s/%s'%(jid,nick)),
|
||||
'hu':L('Hungarian','%s/%s'%(jid,nick))}
|
||||
if text.lower() == 'list': msg = L('Available languages for translate:','%s/%s'%(jid,nick)) + ' ' + ', '.join(sorted(trlang.keys()))
|
||||
elif text[:5].lower() == 'info ':
|
||||
text = text.lower().split(' ')
|
||||
msg = ''
|
||||
for tmp in text:
|
||||
if tmp in trlang: msg += '%s - %s, ' % (tmp,trlang[tmp])
|
||||
if len(msg): msg = L('Available languages: %s','%s/%s'%(jid,nick)) % msg[:-2]
|
||||
else: msg = L('I don\'t know this language','%s/%s'%(jid,nick))
|
||||
elif text[:5].lower() == 'lang ' and text.count(' ')==1:
|
||||
text = text.lower().split(' ')[1]
|
||||
msg = ', '.join(['%s - %s' % (k,trlang[k]) for k in trlang.keys() if text in trlang[k].lower()])
|
||||
if len(msg): msg = L('Available languages: %s','%s/%s'%(jid,nick)) % msg
|
||||
else: msg = L('I don\'t know this language','%s/%s'%(jid,nick))
|
||||
else:
|
||||
if ' ' in text:
|
||||
text = text.split(' ',2)
|
||||
url = 'http://api.microsofttranslator.com/V2/Ajax.svc/Translate?'
|
||||
bing_api = GT('bing_api_key')
|
||||
if bing_api == 'no api': msg = L('Not found Api-key for Bing translator','%s/%s'%(jid,nick))
|
||||
elif len(text)>1 and trlang.has_key(text[0].lower()):
|
||||
if len(text)>2 and trlang.has_key(text[1].lower()): lfrom,lto,tr_text = text[0].lower(),text[1].lower(),text[2]
|
||||
else: lfrom,lto,tr_text = '',text[0].lower(),' '.join(text[1:])
|
||||
translate_results = html_encode(load_page(url, {'oncomplete':'responseData',\
|
||||
'appId':bing_api,\
|
||||
'text':tr_text.encode("utf-8"),\
|
||||
'from':lfrom,\
|
||||
'to':lto}))
|
||||
try: msg = re.findall('responseData\(\"(.*?)\"\)\;$',unicode(translate_results),re.S|re.I|re.U)[0]
|
||||
except: msg = L('I can\'t translate it!','%s/%s'%(jid,nick))
|
||||
else: msg = L('Incorrect language settings for translate. bt list - available languages.','%s/%s'%(jid,nick))
|
||||
else: msg = L('Command\'s format: bt [from] to text','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'bt', bing_translate, 2, 'Bing translator.\nbt [from_language] to_language text - translate text\nbt list - list for available languages for translate\nbt info <reduction> - get info about language reduction\nbt lang <expression> - get languages by expression')]
|
||||
|
||||
67
plugins/blacklist.py
Normal file
67
plugins/blacklist.py
Normal file
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def leave_room(rjid, reason):
|
||||
msg = ''
|
||||
cnf = cur_execute_fetchone('select room from conference where room ilike %s',('%s/%%'%rjid,))
|
||||
if cnf:
|
||||
cur_execute('delete from conference where room ilike %s;', ('%s/%%'%rjid,))
|
||||
leave(rjid, reason)
|
||||
msg = L('Leave conference %s\n') % rjid
|
||||
return msg
|
||||
|
||||
def blacklist(type, jid, nick, text):
|
||||
text, msg = unicode(text.lower()), ''
|
||||
reason = L('Conference was added in blacklist','%s/%s'%(jid,nick))
|
||||
|
||||
try: cmd,room = text.split(' ',1)
|
||||
except: cmd,room = text,''
|
||||
if room and '@' not in room: room = '%s@%s' % (room,lastserver)
|
||||
|
||||
if cmd == 'show':
|
||||
bl = cur_execute_fetchall('select room from blacklist;')
|
||||
if not bl: msg = L('List is empty.','%s/%s'%(jid,nick))
|
||||
else: msg = '%s%s' % (L('List of conferences:\n','%s/%s'%(jid,nick)),'\n'.join(['%s. %s' % (t[0]+1,t[1][0]) for t in enumerate(bl)]))
|
||||
elif cmd == 'clear':
|
||||
msg = L('Cleared.','%s/%s'%(jid,nick))
|
||||
cur_execute('delete from blacklist;')
|
||||
elif room and cmd == 'add':
|
||||
if cur_execute_fetchone('select * from blacklist where room=%s', (room,)): msg = L('This conference already exist in blacklist.','%s/%s'%(jid,nick))
|
||||
elif cur_execute_fetchone('select count(*) from conference;')[0]==1 and getRoom(cur_execute_fetchone('select room from conference;')[0]) == room:
|
||||
msg =L('You can\'t add last conference in blacklist.','%s/%s'%(jid,nick))
|
||||
else:
|
||||
msg = leave_room(room, reason)
|
||||
cur_execute('insert into blacklist values (%s)', (room,))
|
||||
msg += L('Add to blacklist: %s','%s/%s'%(jid,nick)) % room
|
||||
elif room and cmd == 'del':
|
||||
if cur_execute_fetchone('select * from blacklist where room=%s', (room,)):
|
||||
cur_execute('delete from blacklist where room=%s', (room,))
|
||||
msg = L('Removed from blacklist: %s','%s/%s'%(jid,nick)) % room
|
||||
else: msg = L('Address not in blacklist.','%s/%s'%(jid,nick))
|
||||
else: msg = L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(9, 'blacklist', blacklist, 2, 'Manage of conferences blacklist.\nblacklist add|del|show|clear\nblacklist add|del room@conference.server.tld - add|remove address from blacklist\nblacklist show - show blacklist\nblacklist clear - clear blacklist')]
|
||||
177
plugins/bomb.py
Normal file
177
plugins/bomb.py
Normal file
@@ -0,0 +1,177 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
bomb_colors = [L('blue'),L('red'),L('magenta'),L('green'),L('cyan'),L('yellow'),L('white'),L('black')]
|
||||
bomb_current = {}
|
||||
|
||||
bomb_random_list = {}
|
||||
bomb_random_timer_check_period = 10
|
||||
bomb_random_sleep = 600
|
||||
bomb_deny_access = [-1,9]
|
||||
bomb_last_activity = {}
|
||||
bomb_access_level = {}
|
||||
|
||||
def bomb_idle(jid,nick):
|
||||
global idle_base
|
||||
for tmp in idle_base:
|
||||
if tmp[0] == jid and tmp[1] == nick:
|
||||
bid = get_config_int(getRoom(jid),'bomb_idle')
|
||||
if int(time.time())-tmp[3] >= bid: break
|
||||
else: return False
|
||||
return True
|
||||
|
||||
def boom_bomb(room,type,nick,bc,mode):
|
||||
global bomb_access_level
|
||||
b_fault = None
|
||||
if get_config(getRoom(room),'bomb_fault'):
|
||||
bfp = get_config_int(getRoom(room),'bomb_fault_persent')
|
||||
if bfp < 0 or bfp > 100: bfp = int(config_prefs['bomb_fault_persent'][3])
|
||||
b_fault = random.randint(0,100) < bfp
|
||||
if b_fault: send_msg(type, room, nick, L('It\'s a lucky day for you! Bomb is fault! Right wide is %s','%s/%s'%(room,nick)) % bc)
|
||||
else:
|
||||
if mode: send_msg(type, room, nick, L('You were wrong! Right wire is %s','%s/%s'%(room,nick)) % bc)
|
||||
try:
|
||||
if get_config(getRoom(room),'bomb_action') == 'kick' and bomb_access_level.pop(room+nick) >= get_config_int(getRoom(room),'bomb_action_level'): muc_role(type, room, nick, '%s\n%s' % (nick,get_config(getRoom(room),'bomb_reason')), 'none',0)
|
||||
except: pass
|
||||
|
||||
def get_next_random(room):
|
||||
btm = get_config_int(room,'bomb_random_timer')
|
||||
if btm < 0: btm = int(config_prefs['bomb_random_timer'][3])
|
||||
btmp = get_config_int(room,'bomb_random_timer_persent')
|
||||
if btmp <= 0 or btmp > 99: btmp = int(config_prefs['bomb_random_timer_persent'][3])
|
||||
btm_pers = int(btm/100*btmp)
|
||||
bskp = get_config_int(room,'bomb_random_timer_skip_persent')
|
||||
if bskp <= 0 or bskp > 99: bskp = int(config_prefs['bomb_random_timer_skip_persent'][3])
|
||||
if random.randint(0,100) > bskp: btm *= 2
|
||||
return time.time() + btm + random.randint(-btm_pers,btm_pers)
|
||||
|
||||
def bomb_joke(type, jid, nick, text):
|
||||
global bomb_current,bomb_random_list,bomb_access_level
|
||||
if type == 'chat':
|
||||
send_msg(type, jid, nick, L('Not allowed in private!','%s/%s'%(jid,nick)))
|
||||
return
|
||||
if len(text) == 0 or len(text) == text.count(' ')+text.count('\n'):
|
||||
rlist,tconf = [],getRoom(jid)
|
||||
for tm in megabase:
|
||||
if tm[0] == tconf and not bomb_idle(jid,text) and not (get_level(tconf,tm[1])[0] in bomb_deny_access) and not (getRoom(get_level(tconf,tm[1])[1]) in ['None',getRoom(selfjid)]): rlist.append(tm[1])
|
||||
if len(rlist): text = rlist[random.randrange(len(rlist))]
|
||||
else:
|
||||
if not (nick == text == ''): send_msg(type, jid, nick, L('Here is no candidate to take a bomb!','%s/%s'%(jid,nick)))
|
||||
return
|
||||
bmb = False
|
||||
if not get_config(getRoom(jid),'bomb'): msg = L('In this room not allowed take a bomb!','%s/%s'%(jid,nick))
|
||||
elif jid in bomb_current.keys(): msg = L('This room alredy boombed!','%s/%s'%(jid,nick))
|
||||
elif bomb_idle(jid,text) or get_level(jid,text)[0] in bomb_deny_access or getRoom(get_level(jid,text)[1]) in ['None',getRoom(selfjid)]: msg = L('I can\'t take a bomb to %s','%s/%s'%(jid,nick)) % text
|
||||
else:
|
||||
bomb_access_level[jid+text] = get_level(jid,nick)[0]
|
||||
b_timer = get_config_int(getRoom(jid),'bomb_timer')
|
||||
if b_timer < 0: b_timer = (config_prefs['bomb_timer'][3])
|
||||
b_wire = get_config_int(getRoom(jid),'bomb_wire')
|
||||
if b_wire < 3 or b_wire > len(bomb_colors): b_wire = int(config_prefs['bomb_wire'][3])
|
||||
b_clrs = []
|
||||
while len(b_clrs) < b_wire:
|
||||
bc = bomb_colors[random.randrange(len(bomb_colors))]
|
||||
if bc not in b_clrs: b_clrs.append(bc)
|
||||
bomb_current[getRoom(jid)] = [text,b_clrs,b_clrs[random.randrange(len(b_clrs))]]
|
||||
msg,bmb = L('/me take a bomb to %s with wires %s. Time to deactivate is %s sec.','%s/%s'%(jid,nick)) % (text,', '.join(b_clrs),b_timer),True
|
||||
send_msg(type, jid, '', msg)
|
||||
if bmb:
|
||||
while b_timer > 0 and not game_over:
|
||||
time.sleep(1)
|
||||
b_timer -= 1
|
||||
if jid not in bomb_current.keys(): break
|
||||
if b_timer <= 0 and not game_over:
|
||||
if bomb_current.has_key(getRoom(jid)): bc = bomb_current.pop(getRoom(jid))
|
||||
else: bc = L('unknown','%s/%s'%(jid,nick))
|
||||
b_fault = None
|
||||
if get_config(getRoom(jid),'bomb_fault'):
|
||||
bfp = get_config_int(getRoom(jid),'bomb_fault_persent')
|
||||
if bfp < 0 or bfp > 100: bfp = int(config_prefs['bomb_fault_persent'][3])
|
||||
b_fault = random.randint(0,100) < bfp
|
||||
if b_fault: send_msg(type, jid, text, L('It\'s a lucky day for you! Bomb is fault! Right wide is %s','%s/%s'%(jid,nick)) % bc[2])
|
||||
else:
|
||||
send_msg(type, jid, '', L('/me explode %s','%s/%s'%(jid,nick)) % text)
|
||||
if get_config(getRoom(jid),'bomb_action') == 'kick' and bomb_access_level.pop(jid+text) >= get_config_int(getRoom(jid),'bomb_action_level'): muc_role(type, jid, nick, '%s\n%s' % (text,get_config(getRoom(jid),'bomb_reason')), 'none',0)
|
||||
bomb_random_list[getRoom(jid)] = get_next_random(getRoom(jid))
|
||||
|
||||
def bomb_presence(room,jid,nick,type,mass):
|
||||
global bomb_current
|
||||
if not get_config(getRoom(room),'bomb'): return
|
||||
try: bc = bomb_current[getRoom(room)]
|
||||
except: return
|
||||
if nick != bc[0]: return
|
||||
if type == 'unavailable':
|
||||
if bomb_current.has_key(getRoom(room)): bc = bomb_current.pop(getRoom(room))
|
||||
else: bc = L('unknown','%s/%s'%(room,nick))
|
||||
if mass[8]:
|
||||
time.sleep(1)
|
||||
boom_bomb(room,'groupchat',mass[8],bc[2],None)
|
||||
bomb_random_list[getRoom(room)] = get_next_random(getRoom(room))
|
||||
|
||||
def bomb_message(room,jid,nick,type,text):
|
||||
global bomb_current,bomb_random_list
|
||||
gr = getRoom(room)
|
||||
if not get_config(gr,'bomb'): return
|
||||
try: bc = bomb_current[gr]
|
||||
except: return
|
||||
if nick != bc[0]: return
|
||||
if text.lower() not in bc[1]: return
|
||||
if bomb_current.has_key(gr): bomb_current.pop(gr)
|
||||
type = 'groupchat'
|
||||
if text.lower() == bc[2]: send_msg(type, room, nick, L('Bomb is deactivated! Congratulations!','%s/%s'%(room,nick)))
|
||||
else: boom_bomb(room,type,nick,bc[2],True)
|
||||
bomb_random_list[gr] = get_next_random(gr)
|
||||
|
||||
def bomb_random():
|
||||
global bomb_current,bomb_random_list
|
||||
bt = bomb_random_sleep
|
||||
while not game_over and bt > 0:
|
||||
time.sleep(1)
|
||||
bt -= 1
|
||||
while not game_over:
|
||||
ntime = time.time()
|
||||
cb = [t[0] for t in cur_execute_fetchall("select split_part(room,'/',1) from conference;") if t]
|
||||
for tmp in cb:
|
||||
try: bla = get_config(tmp,'bomb_random_active') and (ntime - bomb_last_activity[tmp]) < get_config_int(tmp,'bomb_random_active_timer')
|
||||
except: bla = True
|
||||
if get_config(tmp,'bomb') and get_config(tmp,'bomb_random') and bla:
|
||||
try: bsets = bomb_random_list[tmp]
|
||||
except: bomb_random_list[tmp],bsets = ntime,ntime
|
||||
if bsets < ntime:
|
||||
bomb_joke('groupchat', tmp, '', '')
|
||||
bomb_random_list[tmp] = get_next_random(tmp)
|
||||
bt = bomb_random_timer_check_period
|
||||
while not game_over and bt > 0:
|
||||
time.sleep(1)
|
||||
bt -= 1
|
||||
|
||||
def bomb_message_active(room,jid,nick,type,mass):
|
||||
global bomb_last_activity
|
||||
if jid != 'None': bomb_last_activity[getRoom(room)] = int(time.time())
|
||||
|
||||
global execute, presence_control, message_control
|
||||
|
||||
presence_control = [bomb_presence]
|
||||
message_act_control = [bomb_message,bomb_message_active]
|
||||
|
||||
execute = [(4, 'bomb', bomb_joke, 2, 'Take a bomb joke!')]
|
||||
99
plugins/bugmenot.py
Normal file
99
plugins/bugmenot.py
Normal file
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) Vit@liy <vitaliy@root.ua> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
bmn_last_res = {}
|
||||
|
||||
def dec(data):
|
||||
b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
|
||||
enc = ''
|
||||
for i in range(0, len(data)/4):
|
||||
h1 = b64.index(data[4*i])
|
||||
h2 = b64.index(data[4*i+1])
|
||||
h3 = b64.index(data[4*i+2])
|
||||
h4 = b64.index(data[4*i+3])
|
||||
bits = h1 << 18 | h2 << 12 | h3 << 6 | h4
|
||||
o1 = bits >> 16 & 255
|
||||
o2 = bits >> 8 & 255
|
||||
o3 = bits & 255
|
||||
if h3 == 64: enc += chr(o1)
|
||||
elif h4 == 64: enc += chr(o1) + chr(o2)
|
||||
else: enc += chr(o1) + chr(o2) + chr(o3)
|
||||
return enc
|
||||
|
||||
def d(strInput, key):
|
||||
strInput = dec(strInput)
|
||||
strOutput = ''
|
||||
intOffset = (key + 112) / 12
|
||||
for i in range(4, len(strInput)):
|
||||
thisCharCode = ord(strInput[i])
|
||||
newCharCode = thisCharCode - intOffset
|
||||
strOutput += chr(newCharCode)
|
||||
return strOutput
|
||||
|
||||
def decrypt(i, key):
|
||||
i = list(i)
|
||||
return map(lambda x: d(x, key), i[:3]) + i[-2:]
|
||||
|
||||
def bugmenot(type, jid, nick,text):
|
||||
global bmn_last_res
|
||||
result = ''
|
||||
text = text.strip()
|
||||
if text:
|
||||
connct = httplib.HTTPConnection('www.bugmenot.com')
|
||||
connct.request('GET', '/view/' + text.encode("utf-8"))
|
||||
r = connct.getresponse().read()
|
||||
try: key = int(re.findall('var key = (\d+)',r)[0])
|
||||
except: key = ''
|
||||
blocked = '<h2>Site Blocked</h2>' in r
|
||||
if key and not blocked:
|
||||
l = re.findall('<tr><th>Username </th><td><script>d\(\'(.+)\'\);</script></td></tr>\s+?<tr><th>Password </th><td><script>d\(\'(.+?)\'\);</script></td></tr>\s+?<tr><th>Other</th><td><script>d\(\'(.+?)\'\);</script></td></tr>\s+?<tr><th>Stats</th><td class="stats"><em class=".+?">(\d+?)% success rate</em> \((\d+?) votes\)</td></tr>', r)
|
||||
l = [decrypt(i, key) for i in l]
|
||||
logins = [i[0] for i in l]
|
||||
passwords = [i[1] for i in l]
|
||||
other = [i[2] for i in l]
|
||||
stats = [L('%s%% (%s votes)','%s/%s'%(jid,nick)) % (i[3],i[4]) for i in l]
|
||||
data = zip(logins, passwords, other, stats)
|
||||
if data:
|
||||
first = data[0]
|
||||
if bmn_last_res.has_key(jid): bmn_last_res[jid].update({nick: data[1:]})
|
||||
else: bmn_last_res[jid] = {nick: data[1:]}
|
||||
else: result = L('What?','%s/%s'%(jid,nick))
|
||||
elif blocked: result = L('Site Blocked','%s/%s'%(jid,nick))
|
||||
else: result = L('What?','%s/%s'%(jid,nick))
|
||||
else:
|
||||
if bmn_last_res.has_key(jid) and bmn_last_res[jid].has_key(nick) and bmn_last_res[jid][nick]:
|
||||
first = bmn_last_res[jid][nick][0]
|
||||
bmn_last_res[jid][nick] = bmn_last_res[jid][nick][1:]
|
||||
else: result = L('No results!','%s/%s'%(jid,nick))
|
||||
if not result: result = rss_replace(L('Login: %s, Pass: %s - %s %s','%s/%s'%(jid,nick)) % first)
|
||||
send_msg(type, jid, nick, result)
|
||||
|
||||
def bmn_clear(room,jid,nick,type,arr):
|
||||
if type == 'unavailable' and bmn_last_res.has_key(room) and bmn_last_res[room].has_key(nick): del bmn_last_res[room][nick]
|
||||
|
||||
global execute, presence_control
|
||||
|
||||
presence_control = [bmn_clear]
|
||||
|
||||
execute = [(3, 'bugmenot', bugmenot, 2, 'Search in bugmenot.com')]
|
||||
|
||||
41
plugins/calendar.py
Normal file
41
plugins/calendar.py
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# Copyright (C) dr.Schmurge <dr.schmurge@isida-bot.com> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def month_cal(type, jid, nick, text):
|
||||
text = text.split()
|
||||
try: month = int(text[0])
|
||||
except: month = tuple(time.localtime())[1]
|
||||
try: year = int(text[1])
|
||||
except: year = tuple(time.localtime())[0]
|
||||
try: smbl = text[2]
|
||||
except: smbl = GT('calendar_default_splitter')
|
||||
try:
|
||||
msg = L('\nMon Tue Wed Thu Fri Sat Sun\n','%s/%s'%(jid,nick)) + '\n'.join([' '.join([['%2d' % r,' '][r==0] for r in t]) for t in calendar.monthcalendar(year,month)])
|
||||
msg = L('Now: %s%s','%s/%s'%(jid,nick)) % (timeadd(tuple(time.localtime())), msg.replace(' ',smbl))
|
||||
except: msg = L('Error!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'calendar', month_cal, 2, 'Calendar. Without parameters show calendar for current month.\ncalendar [month][year][symbol_splitter]')]
|
||||
159
plugins/chat.py
Normal file
159
plugins/chat.py
Normal file
@@ -0,0 +1,159 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# Copyright (C) Vit@liy <vitaliy@root.ua> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
ANSW_PREV = {}
|
||||
FLOOD_STATS = {}
|
||||
LAST_PHRASE = {}
|
||||
|
||||
autophrases_time = {}
|
||||
list_of_answers, list_of_empty, list_of_phrases_with_highlight, list_of_phrases_no_highlight, dict_of_mind = {}, {}, {}, {}, {}
|
||||
|
||||
llist = ['en'] + [tmp[:-4] for tmp in os.listdir(loc_folder[:-6]) if tmp[-4:]=='.txt']
|
||||
for t in llist:
|
||||
if os.path.isfile(loc_folder % t): cur_lang = t
|
||||
else: cur_lang = 'en'
|
||||
chat_folder = data_folder % 'chat/%s/' % cur_lang
|
||||
MIND_FILE = chat_folder + 'mind.txt'
|
||||
EMPTY_FILE = chat_folder + 'empty.txt'
|
||||
ANSWER_FILE = chat_folder + 'answer.txt'
|
||||
PHRASES_FILE = chat_folder + 'phrases.txt'
|
||||
|
||||
list_of_answers[cur_lang] = readfile(ANSWER_FILE).decode('utf-8').split('\n')
|
||||
list_of_empty[cur_lang] = readfile(EMPTY_FILE).decode('utf-8').split('\n')
|
||||
list_of_phrases_with_highlight[cur_lang] = []
|
||||
list_of_phrases_no_highlight[cur_lang] = []
|
||||
for phrase in readfile(PHRASES_FILE).split('\n'):
|
||||
if 'NICK' in phrase: list_of_phrases_with_highlight[cur_lang].append(phrase.decode('utf-8'))
|
||||
else: list_of_phrases_no_highlight[cur_lang].append(phrase.decode('utf-8'))
|
||||
|
||||
dict_of_mind[cur_lang] = {}
|
||||
for p in readfile(MIND_FILE).decode('utf-8').split('\n'):
|
||||
if '||' in p:
|
||||
tmp1, tmp2 = p.strip().split('||')
|
||||
dict_of_mind[cur_lang][tmp1] = tmp2.split('|')
|
||||
|
||||
def addAnswerToBase(tx):
|
||||
if not len(tx) or tx.count(' ') == len(tx): return
|
||||
lent = len(cur_execute_fetchall('select ind from answer'))+1
|
||||
cur_execute('insert into answer values (%s,%s)', (lent,tx))
|
||||
if base_type not in ['sqlite3','mysql']:
|
||||
conn.commit()
|
||||
|
||||
def getRandomAnswer(tx,room):
|
||||
if not tx.strip(): return None
|
||||
lent = len(cur_execute_fetchall('select ind from answer'))
|
||||
mrand = random.randint(1,lent)
|
||||
answ = to_censore(cur_execute_fetchone('select body from answer where ind=%s', (mrand,))[0],room)
|
||||
return answ
|
||||
|
||||
def getSmartAnswer(type, room, nick, text):
|
||||
loc = get_L_('%s/%s' % (room,nick))
|
||||
if '?' in text: answ = random.choice(list_of_answers[loc]).strip()
|
||||
else: answ = random.choice(list_of_empty[loc]).strip()
|
||||
score,sc, var = 1.0,0,[answ]
|
||||
text = ' %s ' % text.upper()
|
||||
for answer in dict_of_mind[loc]:
|
||||
sc = rating(answer, text, room)
|
||||
if sc > score: score,var = sc,dict_of_mind[loc][answer]
|
||||
elif sc == score: var += dict_of_mind[loc][answer]
|
||||
|
||||
return random.choice(var)
|
||||
|
||||
def rating(s, text, room):
|
||||
r,s = 0.0,s.split('|')
|
||||
for k in s:
|
||||
if k in text: r += 1
|
||||
if k in ANSW_PREV.get(room, ''): r += 0.5
|
||||
return r
|
||||
|
||||
def getAnswer(type, room, nick, text):
|
||||
text = text.strip()
|
||||
if get_config(getRoom(room),'flood') in ['random',True]: answ = getRandomAnswer(text,room)
|
||||
else:
|
||||
answ = getSmartAnswer(type, room, nick, text)
|
||||
ANSW_PREV[room] = text.upper()
|
||||
if type == 'groupchat' and text == to_censore(text,room): addAnswerToBase(text)
|
||||
return answ
|
||||
|
||||
def flood_action(room,jid,nick,type,text):
|
||||
if get_config(room,'autoflood'):
|
||||
jjid = getRoom(jid)
|
||||
tm = time.time()
|
||||
prefix = get_local_prefix(room)
|
||||
first_word = text.split(' ', 1)[0]
|
||||
cur_alias = cur_execute_fetchall('select match from alias where room=%s',(room,))
|
||||
if cur_alias: cur_alias = [t[0] for t in cur_alias]
|
||||
else: cur_alias = []
|
||||
if nick in [get_xnick(room), ''] or cur_execute_fetchone('select pattern from bot_ignore where %s ilike pattern',(jjid,)) or ddos_ignore.has_key(jjid): return
|
||||
if first_word in [prefix + i[1] for i in comms] + cur_alias or first_word[:-1] in [d[1] for d in megabase if d[0]==room]:
|
||||
if FLOOD_STATS.has_key(room) and FLOOD_STATS[room][0] != jjid: FLOOD_STATS[room] = ['', 0, 0]
|
||||
return
|
||||
if not FLOOD_STATS.has_key(room) or FLOOD_STATS[room][0] != jjid: FLOOD_STATS[room] = [jjid, tm, 1]
|
||||
else: FLOOD_STATS[room][2] += 1
|
||||
if FLOOD_STATS.has_key(room) and FLOOD_STATS[room][2] >= get_config_int(room,'floodcount') and tm - FLOOD_STATS[room][1] > get_config_int(room,'floodtime'):
|
||||
pprint('Send msg human: %s/%s [%s] <<< %s' % (room,nick,type,text),'dark_gray')
|
||||
try:
|
||||
msg = getAnswer(type, room, nick, text)
|
||||
if text: send_msg_human(type, room, nick, msg, 'msg_human_auto')
|
||||
else: return False
|
||||
except: return False
|
||||
return True
|
||||
if get_config(room,'floodrepeat') != 'off' and get_level(room,nick)[0] > 0:
|
||||
text = text.strip()
|
||||
if LAST_PHRASE.has_key(room) and LAST_PHRASE[room][0] != jid and LAST_PHRASE[room][2] == text:
|
||||
if LAST_PHRASE[room][1] >= get_config_int(room,'floodrepeat') - 1:
|
||||
try: LAST_PHRASE.pop(room)
|
||||
except: pass
|
||||
pprint('Send msg human repeat: %s/%s [%s] <<< %s' % (room,nick,type,text),'dark_gray')
|
||||
try: send_msg_human(type, room, '', text, 'msg_human_repeat')
|
||||
except: return False
|
||||
return True
|
||||
else: LAST_PHRASE[room] = [jid,LAST_PHRASE[room][1] + 1,text]
|
||||
else: LAST_PHRASE[room] = [jid,1,text]
|
||||
return False
|
||||
|
||||
def phrases_timer():
|
||||
for room in list(set([i[0] for i in megabase])):
|
||||
if get_config(room,'autophrases') != 'off':
|
||||
a_time = int(get_config(room,'autophrasestime'))
|
||||
if not room in autophrases_time:
|
||||
autophrases_time[room] = time.time() + random.normalvariate(a_time, a_time/12.0)/2
|
||||
if time.time() > autophrases_time[room]:
|
||||
autophrases_time[room] = time.time() + random.normalvariate(a_time, a_time/12.0)
|
||||
if get_config(room,'autophrases') == 'all':
|
||||
rand_nicks = [d[1] for d in megabase if d[0]==room if not cur_execute_fetchone('select pattern from bot_ignore where %s ilike pattern',(getRoom(d[4]),)) and d[1] not in [get_xnick(room), '']]
|
||||
if rand_nicks:
|
||||
nick = random.choice(rand_nicks)
|
||||
loc = get_L_('%s/%s' % (room,nick))
|
||||
msg = random.choice(list_of_phrases_with_highlight[loc] + list_of_phrases_no_highlight[loc])
|
||||
msg = msg.replace('NICK', nick)
|
||||
if get_config(room,'autophrases') == 'without highlight' or not rand_nicks: msg = random.choice(list_of_phrases_no_highlight[CURRENT_LOCALE])
|
||||
pprint('Send autophrase: %s >>> %s' % (room, msg), 'dark_gray')
|
||||
send_msg('groupchat', room, '', msg)
|
||||
|
||||
global execute, message_act_control, timer
|
||||
|
||||
message_act_control = [flood_action]
|
||||
timer = [phrases_timer]
|
||||
execute = []
|
||||
44
plugins/clear.py
Normal file
44
plugins/clear.py
Normal file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def hidden_clear(type, jid, nick, text):
|
||||
try: cntr = int(text)
|
||||
except: cntr = GT('clear_default_count')
|
||||
if cntr > GT('clear_max_count'): cntr = GT('clear_max_count')
|
||||
elif cntr < 2: cntr = 2
|
||||
cdel,cmode = GT('clear_delay'),get_config(getRoom(jid),'clear_answer') == 'presence'
|
||||
clear_msg = L('Clean by %s messages in approximately %s sec.','%s/%s'%(jid,nick)) % (cntr,int(cntr*cdel))
|
||||
if cmode: caps_and_send(xmpp.Presence(jid,show=Settings['status'], status=clear_msg, priority=Settings['priority']))
|
||||
else: send_msg(type, jid, nick, clear_msg)
|
||||
time.sleep(cdel)
|
||||
for tmp in range(0,cntr):
|
||||
msg = xmpp.Message(jid, '', "groupchat")
|
||||
msg.setTag('body')
|
||||
sender(msg)
|
||||
time.sleep(cdel)
|
||||
if cmode: caps_and_send(xmpp.Presence(jid,show=Settings['status'], status=Settings['message'], priority=Settings['priority']))
|
||||
else: send_msg(type, jid, nick, L('Cleaned!','%s/%s'%(jid,nick)))
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(7, 'clear', hidden_clear, 2, 'Hidden cleaning of conference history.')]
|
||||
128
plugins/clients.py
Normal file
128
plugins/clients.py
Normal file
@@ -0,0 +1,128 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def clients_stats_old(type, jid, nick, text):
|
||||
text = reduce_spaces_all(text).lower().split()
|
||||
if text:
|
||||
is_short = 'short' in text
|
||||
is_os = 'os' in text
|
||||
is_global = 'global' in text or 'total' in text or 'all' in text
|
||||
if is_short or is_global or is_os:
|
||||
for t in ['all','total','global','short','os']:
|
||||
if t in text: text.remove(t)
|
||||
if text: match = '%%\r%%%s%%' % ' '.join(text)
|
||||
else: match = '%\r%'
|
||||
else:
|
||||
match = '%\r%'
|
||||
is_short = is_global = is_os = False
|
||||
if is_global: req,par = 'select message from age where message ilike %s',(match,)
|
||||
else: req,par = 'select message from age where room=%s and message ilike %s',(jid,match)
|
||||
st = cur_execute_fetchall(req,par)
|
||||
if st:
|
||||
ns = {}
|
||||
et = L('Error! %s','%s/%s'%(jid,nick))%''
|
||||
for t in st:
|
||||
if is_os:
|
||||
k = t[0].split('\r',1)[1].split(' // ',1)
|
||||
if len(k) == 2: k = k[1]
|
||||
else: k = ''
|
||||
else: k = t[0].split('\r',1)[1].split(' // ',1)[0]
|
||||
k = k.replace('\r','[LF]').replace('\n','[CR]').replace('\t','[TAB]')
|
||||
if is_short and k: k = k.split()[0]
|
||||
if not k or k == 'None': k = 'Unknown'
|
||||
if not k.startswith(et.strip()):
|
||||
if ns.has_key(k): ns[k] += 1
|
||||
else: ns[k] = 1
|
||||
ns = [(ns[t],t) for t in ns.keys()]
|
||||
ns.sort(reverse=True)
|
||||
msg = L('Client statistic:%s','%s/%s'%(jid,nick)) % '\n%s' % '\n'.join(['%s. %s\t- %s' % (ns.index(t)+1,t[1],t[0]) for t in ns[:10]])
|
||||
else: msg = L('Clients statistic not available.','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def clients_stats(type, jid, nick, text):
|
||||
text2 = text.split(' ')
|
||||
text = text.lower().split(' ')
|
||||
match = '%'
|
||||
if text:
|
||||
is_short = 'short' in text
|
||||
is_os = 'os' in text
|
||||
is_user = 'user' in text
|
||||
is_global = 'global' in text or 'total' in text or 'all' in text
|
||||
if is_short or is_global or is_os or is_user:
|
||||
for t in ['all','total','global','short','os','user']:
|
||||
if t in text: text.remove(t)
|
||||
for t2 in text2:
|
||||
if t2.lower() == t.lower():
|
||||
text2.remove(t2)
|
||||
break
|
||||
if is_user:
|
||||
if text2:
|
||||
cnick = text = ' '.join(text2)
|
||||
for t in megabase:
|
||||
if t[0] == jid and t[1] in text:
|
||||
match,cnick = '%%%s%%' % reduce_spaces_all(text.replace(t[1],'')),t[1]
|
||||
break
|
||||
else: cnick = nick
|
||||
cjid = getRoom(get_level(jid,cnick)[1])
|
||||
if cjid == 'None':
|
||||
send_msg(type, jid, nick, L('I could be wrong, but %s not is here...','%s/%s'%(jid,nick)) % cnick)
|
||||
return
|
||||
elif text: match = '%%%s%%' % reduce_spaces_all(' '.join(text))
|
||||
else: is_short = is_global = is_os = is_user = False
|
||||
|
||||
if is_global:
|
||||
if is_user: req,par = 'select client,version,os from versions where jid=%s and (client ilike %s or version ilike %s or os ilike %s)',(cjid,match,match,match)
|
||||
else: req,par = 'select client,version,os from versions where client ilike %s or version ilike %s or os ilike %s',(match,match,match)
|
||||
elif is_user: req,par = 'select client,version,os from versions where room=%s and jid=%s',(jid,cjid)
|
||||
else: req,par = 'select client,version,os from versions where room=%s and (client ilike %s or version ilike %s or os ilike %s)',(jid,match,match,match)
|
||||
st = cur_execute_fetchall(req,par)
|
||||
if st:
|
||||
ns = {}
|
||||
for t in st:
|
||||
if is_os:
|
||||
k = t[2]
|
||||
if k and k.strip() and is_short:
|
||||
if '/' in k: k = k.split('/')[0]
|
||||
elif k.lower().startswith('microsoft') or k.lower().startswith('(c)') or k.startswith(u'©'): k = k.split()[1]
|
||||
else: k = k.split()[0]
|
||||
if '=' in k: k = k.split('=')[1]
|
||||
else:
|
||||
if is_short: k = t[0]
|
||||
else: k = '%s %s' % (t[:2])
|
||||
if not k or k == 'None': k = 'Unknown'
|
||||
k = k.replace('\r','[LF]').replace('\n','[CR]').replace('\t','[TAB]')
|
||||
if ns.has_key(k): ns[k] += 1
|
||||
else: ns[k] = 1
|
||||
ns = [(ns[t],t) for t in ns.keys()]
|
||||
ns.sort(reverse=True)
|
||||
if is_user:
|
||||
if is_short: msg = L('Client statistic:%s','%s/%s'%(jid,nick)) % ' %s' % ', '.join(['%s (%s)' % (t[1],t[0]) for t in ns])
|
||||
else: msg = L('Client statistic:%s','%s/%s'%(jid,nick)) % '\n%s' % '\n'.join([t[1] for t in ns])
|
||||
else: msg = L('Client statistic:%s','%s/%s'%(jid,nick)) % '\n%s' % '\n'.join(['%s. %s\t- %s' % (ns.index(t)+1,t[1],t[0]) for t in ns[:10]])
|
||||
else: msg = L('Clients statistic not available.','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(4, 'clients_old', clients_stats_old, 2, 'Show clients statistic when available.\nclients [total|global|all[ short][ os]] [string]'),
|
||||
(4, 'clients', clients_stats, 2, 'Show clients statistic when available.\nclients [total|global|all[ short][ os]] [string]')]
|
||||
74
plugins/convert.py
Normal file
74
plugins/convert.py
Normal file
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
currency_conv_list = ['ATS','AUD','BEF','BYR','CAD','CHF','CNY','DEM','DKK','EEK',\
|
||||
'EGP','ESP','EUR','FIM','FRF','GBP','GRD','IEP','ISK','ITL',\
|
||||
'JPY','KGS','KWD','KZT','LTL','NLG','NOK','PTE','SDR','SEK',\
|
||||
'SGD','TRL','TRY','UAH','USD','XDR','YUN','RUB']
|
||||
|
||||
def currency_converter(type, jid, nick, text):
|
||||
msg = L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
text = text.strip().upper()
|
||||
if text == 'LIST': msg = L('Available values:\n%s','%s/%s'%(jid,nick)) % ', '.join(currency_conv_list).replace('RUB','RUR')
|
||||
else:
|
||||
repl_curr = ((u'RUR','RUB'),(u'€','EUR'),('$','USD'),(u'¥','JPY'),(u'£','GBP'),(',','.'))
|
||||
for tmp in repl_curr: text = text.replace(tmp[0],' %s ' % tmp[1])
|
||||
c_from,c_to,c_summ = '','',''
|
||||
val = [t for t in re.findall('[A-Z]{3,4}', text, re.S) if t in currency_conv_list]
|
||||
if len(val) >= 2: c_from,c_to = val[:2]
|
||||
val = ''.join(re.findall('[0-9\.]',text))
|
||||
if val.replace('.','').isdigit() and val.count('.') <= 1:
|
||||
if val.startswith('.'): c_summ = '0%s' % val
|
||||
elif val.endswith('.'): c_summ = '%s0' % val
|
||||
else: c_summ = val
|
||||
if c_from and c_to and c_summ:
|
||||
date = tuple(time.localtime())[:3]
|
||||
mname = ['%D0%AF%D0%BD%D0%B2%D0%B0%D1%80%D1%8C','%D0%A4%D0%B5%D0%B2%D1%80%D0%B0%D0%BB%D1%8C',
|
||||
'%D0%9C%D0%B0%D1%80%D1%82','%D0%90%D0%BF%D1%80%D0%B5%D0%BB%D1%8C',
|
||||
'%D0%9C%D0%B0%D0%B9','%D0%98%D1%8E%D0%BD%D1%8C',
|
||||
'%D0%98%D1%8E%D0%BB%D1%8C','%D0%90%D0%B2%D0%B3%D1%83%D1%81%D1%82',
|
||||
'%D0%A1%D0%B5%D0%BD%D1%82%D1%8F%D0%B1%D1%80%D1%8C','%D0%9E%D0%BA%D1%82%D1%8F%D0%B1%D1%80%D1%8C',
|
||||
'%D0%9D%D0%BE%D1%8F%D0%B1%D1%80%D1%8C','%D0%94%D0%B5%D0%BA%D0%B0%D0%B1%D1%80%D1%8C']
|
||||
url = 'http://quote.rbc.ru/cgi-bin/conv/external/converter.shtml?source=cb.0&tid_from=%s&commission=1.0&tid_to=%s&summa=%s&day=%s&mon=%s&year=%s' % (c_from,c_to,c_summ,date[2],mname[date[1]-1],date[0])
|
||||
body = html_encode(load_page(url))
|
||||
try:
|
||||
curr = body.split('<select name="tid_from" class="n">')[1].split('</select>')[0]
|
||||
curr_list = dict(re.findall('<option value="(.*?)".*?>(.*?)</option>',curr,re.S|re.I|re.U))
|
||||
except: curr_list = {}
|
||||
try: body = body.split('<table id="rTable" class="table">',1)[1]
|
||||
except: body = ''
|
||||
regex = '<tbody>.*?<td>(.*?)</td>.*?<td class="b">(.*?)</td>.*?<td class="b">(.*?)</td>.*?<td>(.*?)</td>.*?<td class="b">(.*?)</td>'
|
||||
mt = re.findall(regex, body, re.S)
|
||||
if mt != []:
|
||||
mt = [t.strip() for t in mt[0]]
|
||||
if curr_list.has_key(mt[0]): frv = curr_list[mt[0]]
|
||||
else: frv = mt[0]
|
||||
if curr_list.has_key(mt[3]): tov = curr_list[mt[3]]
|
||||
else: tov = mt[3]
|
||||
msg = '%s %s (%s) = %s %s (%s) | 1 %s = %s %s' % (c_summ,c_from,frv,mt[4],c_to,tov,c_from,mt[2],c_to)
|
||||
msg = msg.replace('RUB','RUR')
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'convert', currency_converter, 2, 'Currency converter\nconvert from to count\nconvert list')]
|
||||
133
plugins/cron.py
Normal file
133
plugins/cron.py
Normal file
@@ -0,0 +1,133 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
# cron * * * * * \n command
|
||||
|
||||
def time_cron(type, jid, nick, text):
|
||||
ar = text.split(' ',1)[0].lower()
|
||||
try: par = text.split(' ',1)[1]
|
||||
except: par = ''
|
||||
if ar == 'show': msg = time_cron_show(jid,nick,par)
|
||||
elif ar == 'del': msg = time_cron_del(jid,nick,par)
|
||||
else: msg = time_cron_add(text,jid,nick)
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def time_cron_show(jid,nick,ar):
|
||||
al = get_level(jid,nick)[0]
|
||||
if ar:
|
||||
if al == 9 and ar.lower().split()[0] in ['all','global','total']: room = '%'
|
||||
else: room = jid
|
||||
else: room = jid
|
||||
c = cur_execute_fetchall('select * from cron where room ilike %s order by room, time',(room,))
|
||||
if c:
|
||||
tmp, idx = [], 1
|
||||
for t in c:
|
||||
if t[2] == '\n': mode = '[silent]'
|
||||
elif not t[2]: mode = '[anonim]'
|
||||
else: mode = ''
|
||||
if room=='%': msg = '%s|%s' % (t[0],disp_time(t[3],'%s/%s'%(jid,nick)))
|
||||
else: msg = '%s. %s' % (idx,disp_time(t[3],'%s/%s'%(jid,nick)))
|
||||
if mode: msg = '%s %s' % (msg,mode)
|
||||
if t[4]: msg += ' [%s]' % t[4]
|
||||
msg += ' -> %s' % t[5]
|
||||
tmp.append(msg)
|
||||
idx += 1
|
||||
return L('Cron rules:\n%s','%s/%s'%(jid,nick)) % '\n'.join(tmp)
|
||||
else: return L('There is no cron rules.','%s/%s'%(jid,nick))
|
||||
|
||||
def time_cron_add(ar,jid,nick):
|
||||
try: cron_time, cron_cmd = ar.split('\n',1)
|
||||
except: return L('Not enough parameters!','%s/%s'%(jid,nick))
|
||||
try:
|
||||
SM,RM,NM = 'silent','once','anonim'
|
||||
CMD = [SM,RM,NM]
|
||||
ct = cron_time.lower().split()
|
||||
rm,sm,nm = RM in ct,SM in ct,NM in ct
|
||||
if rm or sm or nm:
|
||||
for t in CMD:
|
||||
try: ct.remove(t)
|
||||
except: pass
|
||||
ct = ' '.join(ct)
|
||||
if rm: cron_time,repeat_time = ct,''
|
||||
else: cron_time,repeat_time = ct,ct
|
||||
next_time = crontab.CronTab(cron_time).next() + time.time()
|
||||
except: return L('Error in time format!','%s/%s'%(jid,nick))
|
||||
lvl,rj = get_level(jid,nick)
|
||||
amm,tcmd = -1,cron_cmd.split(' ')[0]
|
||||
for tmp in comms:
|
||||
if tmp[1] == tcmd:
|
||||
amm = tmp[0]
|
||||
break
|
||||
if amm < 0: return L('Command not found: %s','%s/%s'%(jid,nick)) % tcmd
|
||||
elif amm > lvl: return L('Not allowed launch: %s','%s/%s'%(jid,nick)) % tcmd
|
||||
else:
|
||||
if sm: nick = '\n'
|
||||
elif nm: nick = ''
|
||||
cur_execute('insert into cron values (%s,%s,%s,%s,%s,%s,%s)', (jid,getRoom(rj),nick,next_time,repeat_time,cron_cmd,lvl))
|
||||
return '%s -> %s' % (disp_time(next_time,'%s/%s'%(jid,nick)),cron_cmd)
|
||||
|
||||
def time_cron_del(jid,nick,ar):
|
||||
al = get_level(jid,nick)[0]
|
||||
if al == 9 and ar.lower() == 'all':
|
||||
cur_execute('delete from cron where room=%s',(jid,))
|
||||
return L('All cron rules removed!','%s/%s'%(jid,nick))
|
||||
elif not ar: return L('Need choise record number.','%s/%s'%(jid,nick))
|
||||
elif not ar.isdigit(): return L('Record ID is numeric.','%s/%s'%(jid,nick))
|
||||
else:
|
||||
c = cur_execute_fetchall('select * from cron where room ilike %s order by room, time',(jid,))
|
||||
try: rec = c[int(ar)-1]
|
||||
except: return L('Record #%s not found!','%s/%s'%(jid,nick)) % ar
|
||||
cur_execute('delete from cron where room=%s and jid=%s and nick=%s and time=%s and repeat=%s and command=%s and level=%s',rec)
|
||||
msg = disp_time(rec[3],'%s/%s'%(jid,nick))
|
||||
if rec[2] == '\n': mode = '[silent]'
|
||||
elif not rec[2]: mode = '[anonim]'
|
||||
else: mode = ''
|
||||
if mode: msg = '%s %s' % (msg,mode)
|
||||
if rec[4]: msg += ' [%s]' % rec[4]
|
||||
msg += ' -> %s' % rec[5]
|
||||
return L('Removed: %s','%s/%s'%(jid,nick)) % msg
|
||||
|
||||
def cron_action():
|
||||
itt = int(time.time())
|
||||
c = cur_execute_fetchall('select distinct * from cron where %s >= time',(itt,))
|
||||
if c:
|
||||
cur_execute('delete from cron where %s >= time',(itt,))
|
||||
for t in c:
|
||||
if t[4]:
|
||||
tm = crontab.CronTab(t[4]).next() + time.time()
|
||||
m = list(t[:3]) + [tm] + list(t[4:7])
|
||||
cur_execute('insert into cron values (%s,%s,%s,%s,%s,%s,%s)', m)
|
||||
tmp = cur_execute_fetchone('select room from conference where room ilike %s',('%s/%%'%t[0],))
|
||||
if not tmp:
|
||||
pprint('Can\'t execute by cron: %s in %s' % (t[5].split()[0],t[0]),'red')
|
||||
return
|
||||
else: nowname = getResourse(tmp[0])
|
||||
if t[2] == '\n': tmp_nick,tmp_type = '%s_cron_%d' % (nowname,time.time()),'chat'
|
||||
else: tmp_nick,tmp_type = t[2],'groupchat'
|
||||
com_parser(t[6], nowname, tmp_type, t[0], tmp_nick, t[5], Settings['jid'])
|
||||
|
||||
global execute, timer
|
||||
|
||||
timer = [cron_action]
|
||||
|
||||
execute = [(7, 'cron', time_cron, 2, 'Execute command by cron. Used unix-type time format.\ncron [once] [anonim|silent] * * * * *\ncommand')]
|
||||
994
plugins/disco.py
Normal file
994
plugins/disco.py
Normal file
@@ -0,0 +1,994 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
whereis_answers = {}
|
||||
whereis_regx = re.compile('<item .*?name=[\'"](.*?)[\'"]',re.S|re.I|re.U)
|
||||
whereis_lock = None
|
||||
disco_excl = []
|
||||
|
||||
disco_features_list = {'dnssrv':'Support for DNS SRV lookups of XMPP services., RFC 3920: XMPP Core, RFC 3921: XMPP IM',
|
||||
'fullunicode':'Support for Unicode characters, including in displayed text, JIDs, and passwords.',
|
||||
'gc-1.0':'Support for the "groupchat 1.0" protocol. (XEP-0045)',
|
||||
'http://jabber.org/protocol/activity':'User Activity (XEP-0108)',
|
||||
'http://jabber.org/protocol/address':'Extended Stanza Addressing (XEP-0033)',
|
||||
'http://jabber.org/protocol/amp':'Advanced Message Processing (XEP-0079)',
|
||||
'http://jabber.org/protocol/amp#errors':'Advanced Message Processing (XEP-0079)',
|
||||
'http://jabber.org/protocol/amp?action=alert':'Support for the "alert" action in Advanced Message Processing. (XEP-0079)',
|
||||
'http://jabber.org/protocol/amp?action=drop':'Support for the "drop" action in Advanced Message Processing. (XEP-0079)',
|
||||
'http://jabber.org/protocol/amp?action=error':'Support for the "error" action in Advanced Message Processing. (XEP-0079)',
|
||||
'http://jabber.org/protocol/amp?action=notify':'Support for the "notify" action in Advanced Message Processing. (XEP-0079)',
|
||||
'http://jabber.org/protocol/amp?condition=deliver':'Support for the "deliver" condition in Advanced Message Processing. (XEP-0079)',
|
||||
'http://jabber.org/protocol/amp?condition=expire-at':'Support for the "expire-at" condition in Advanced Message Processing. (XEP-0079)',
|
||||
'http://jabber.org/protocol/amp?condition=match-resource':'Support for the "match-resource" condition in Advanced Message Processing. (XEP-0079)',
|
||||
'http://jabber.org/protocol/bytestreams':'SOCKS5 Bytestreams (XEP-0065)',
|
||||
'http://jabber.org/protocol/bytestreams#udp':'SOCKS5 Bytestreams (XEP-0065)',
|
||||
'http://jabber.org/protocol/caps':'Entity Capabilities (XEP-0115)',
|
||||
'http://jabber.org/protocol/chatstates':'Chat State Notifications (XEP-0085)',
|
||||
'http://jabber.org/protocol/commands':'Ad-Hoc Commands (XEP-0050)',
|
||||
'http://jabber.org/protocol/compress':'Stream Compression (XEP-0138)',
|
||||
'http://jabber.org/protocol/disco#info':'Service Discovery Info (XEP-0030)',
|
||||
'http://jabber.org/protocol/disco#items':'Service Discovery Items (XEP-0030)',
|
||||
'http://jabber.org/protocol/feature-neg':'Feature Negotiation (XEP-0020)',
|
||||
'http://jabber.org/protocol/geoloc':'User Geolocation (XEP-0080)',
|
||||
'http://jabber.org/protocol/http-auth':'Verifying HTTP Requests via XMPP (XEP-0070)',
|
||||
'http://jabber.org/protocol/httpbind':'Bidirectional-streams Over Synchronous HTTP (XEP-0124)',
|
||||
'http://jabber.org/protocol/ibb':'In-Band Bytestreams (XEP-0047)',
|
||||
'http://jabber.org/protocol/mood':'User Mood (XEP-0107)',
|
||||
'http://jabber.org/protocol/muc':'Multi-User Chat (XEP-0045)',
|
||||
'http://jabber.org/protocol/muc#admin':'Multi-User Chat Admin (XEP-0045)',
|
||||
'http://jabber.org/protocol/muc#owner':'Multi-User Chat Owner (XEP-0045)',
|
||||
'http://jabber.org/protocol/muc#register':'Support for the muc#register FORM_TYPE in Multi-User Chat. (XEP-0045)',
|
||||
'http://jabber.org/protocol/muc#roomconfig':'Support for the muc#roomconfig FORM_TYPE in Multi-User Chat. (XEP-0045)',
|
||||
'http://jabber.org/protocol/muc#roominfo':'Support for the muc#roominfo FORM_TYPE in Multi-User Chat. (XEP-0045)',
|
||||
'http://jabber.org/protocol/muc#user':'Multi-User Chat User (XEP-0045)',
|
||||
'http://jabber.org/protocol/offline':'Flexible Offline Message Retrieval (XEP-0013)',
|
||||
'http://jabber.org/protocol/pubsub#access-authorize':'The default node access model is authorize. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#access-open':'The default node access model is open. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#access-presence':'The default node access model is presence. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#access-roster':'The default node access model is roster. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#access-whitelist':'The default node access model is whitelist. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#auto-create':'The service supports automatic creation of nodes on first publish. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#auto-subscribe':'The service supports automatic subscription to a nodes based on presence subscription. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#collections':'Collection nodes are supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#config-node':'Configuration of node options is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#create-and-configure':'Simultaneous creation and configuration of nodes is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#create-nodes':'Creation of nodes is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#delete-any':'Any publisher may delete an item (not only the originating publisher). (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#delete-nodes':'Deletion of nodes is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#filtered-notifications':'The service supports filtering of notifications based on Entity Capabilities. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#get-pending':'Retrieval of pending subscription approvals is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#instant-nodes':'Creation of instant nodes is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#item-ids':'Publishers may specify item identifiers. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#last-published':'The service supports sending of the last published item to new subscribers and to newly available resources. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#leased-subscription':'Time-based subscriptions are supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#manage-subscription':'Node owners may manage subscriptions. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#member-affiliation':'The member affiliation is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#meta-data':'Node meta-data is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#modify-affiliations':'Node owners may modify affiliations. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#multi-collection':'A single leaf node may be associated with multiple collections. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#multi-subscribe':'A single entity may subscribe to a node multiple times. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#outcast-affiliation':'The outcast affiliation is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#persistent-items':'Persistent items are supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#presence-notifications':'Presence-based delivery of event notifications is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#presence-subscribe':'Implicit presence-based subscriptions are supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#publish':'Publishing items is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#publish-options':'Publication with publish options is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#publisher-affiliation':'The publisher affiliation is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#purge-nodes':'Purging of nodes is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#retract-items':'Item retraction is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#retrieve-affiliations':'Retrieval of current affiliations is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#retrieve-default':'Retrieval of default node configuration is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#retrieve-items':'Item retrieval is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#retrieve-subscriptions':'Retrieval of current subscriptions is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#subscribe':'Subscribing and unsubscribing are supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#subscription-options':'Configuration of subscription options is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#subscription-notifications':'Notification of subscription state changes is supported. (XEP-0060)',
|
||||
'http://jabber.org/protocol/rosterx':'Roster Item Exchange (XEP-0144)',
|
||||
'http://jabber.org/protocol/sipub':'Publishing SI Requests (XEP-0137)',
|
||||
'http://jabber.org/protocol/soap':'SOAP Over XMPP (XEP-0072)',
|
||||
'http://jabber.org/protocol/soap#fault':'SOAP Over XMPP (XEP-0072)',
|
||||
'http://jabber.org/protocol/waitinglist':'Waiting Lists (XEP-0130)',
|
||||
'http://jabber.org/protocol/waitinglist/schemes/mailto':'Waiting list service supports the mailto: URI scheme. (XEP-0130)',
|
||||
'http://jabber.org/protocol/waitinglist/schemes/tel':'Waiting list service supports the tel: URI scheme. (XEP-0130)',
|
||||
'http://jabber.org/protocol/xhtml-im':'XHTML-IM (XEP-0071)',
|
||||
'http://jabber.org/protocol/xdata-layout':'Data Forms Layout (XEP-0141)',
|
||||
'http://jabber.org/protocol/xdata-validate':'Data Forms Validation (XEP-0122)',
|
||||
'ipv6':'Application supports IPv6.',
|
||||
'jabber:client':'Client, XMPP IM (RFC 3921)',
|
||||
'jabber:component:accept':'Existing Component Protocol Accept(XEP-0114)',
|
||||
'jabber:component:connect':'Existing Component Protocol Connect (XEP-0114)',
|
||||
'jabber:iq:auth':'Non-SASL Authentication (XEP-0078)',
|
||||
'jabber:iq:browse':'Iq browse (XEP-0011, Deprecated)',
|
||||
'jabber:iq:gateway':'Gateway Interaction (XEP-0100)',
|
||||
'jabber:iq:last':'Last Activity (XEP-0012)',
|
||||
'jabber:iq:oob':'Out of Band Data (XEP-0066)',
|
||||
'jabber:iq:pass':'DEPRECATED (XEP-0003)',
|
||||
'jabber:iq:privacy':'Privacy Lists (XEP-0016) / XMPP IM (RFC 3921)',
|
||||
'jabber:iq:private':'Private XML Storage (XEP-0049)',
|
||||
'jabber:iq:register':'In-Band Registration (XEP-0077)',
|
||||
'jabber:iq:roster':'Roster, XMPP IM (RFC 3921)',
|
||||
'jabber:iq:rpc':'Jabber-RPC (XEP-0009)',
|
||||
'jabber:iq:search':'Jabber Search (XEP-0055)',
|
||||
'jabber:iq:version':'Software Version (XEP-0092)',
|
||||
'jabber:server':'Server, XMPP IM (RFC 3921)',
|
||||
'jabber:x:data':'Data Forms (XEP-0004)',
|
||||
'jabber:x:delay':'Delayed Delivery (XEP-0091, Deprecated)',
|
||||
'jabber:x:encrypted':'Current OpenPGP Usage (XEP-0027)',
|
||||
'jabber:x:event':'X:Event (XEP-0022, Deprecated)',
|
||||
'jabber:x:expire':'X:Expire (XEP-0023, Deprecated)',
|
||||
'jabber:x:oob':'Out of Band Data (XEP-0066)',
|
||||
'jabber:x:roster':'X:Roster (XEP-0093, Deprecated)',
|
||||
'jabber:x:signed':'Current OpenPGP Usage (XEP-0027)',
|
||||
'msglog':'Application performs logging or archiving of messages.',
|
||||
'msgoffline':'Server stores messages offline for later delivery. (XEP-0160)',
|
||||
'muc_hidden':'Hidden room in Multi-User Chat (MUC) (XEP-0045)',
|
||||
'muc_membersonly':'Members-only room in Multi-User Chat (MUC) (XEP-0045)',
|
||||
'muc_moderated':'Moderated room in Multi-User Chat (MUC) (XEP-0045)',
|
||||
'muc_nonanonymous':'Non-anonymous room in Multi-User Chat (MUC) (XEP-0045)',
|
||||
'muc_open':'Open room in Multi-User Chat (MUC) (XEP-0045)',
|
||||
'muc_passwordprotected':'Password-protected room in Multi-User Chat (MUC) (XEP-0045)',
|
||||
'muc_persistent':'Persistent room in Multi-User Chat (MUC) (XEP-0045)',
|
||||
'muc_public':'Public room in Multi-User Chat (MUC) (XEP-0045)',
|
||||
'muc_rooms':'List of MUC rooms (each as a separate item) (XEP-0045)',
|
||||
'muc_semianonymous':'Semi-anonymous room in Multi-User Chat (MUC) (XEP-0045)',
|
||||
'muc_temporary':'Temporary room in Multi-User Chat (MUC) (XEP-0045)',
|
||||
'muc_unmoderated':'Unmoderated room in Multi-User Chat (MUC) (XEP-0045)',
|
||||
'muc_unsecured':'Unsecured room in Multi-User Chat (MUC) (XEP-0045)',
|
||||
'roster:delimiter':'Nested Roster Groups (XEP-0083)',
|
||||
'sslc2s':'Application supports old-style (pre-TLS) SSL connections on a dedicated port.',
|
||||
'stringprep':'Application supports the nameprep, nodeprep, and resourceprep profiles of stringprep. (RFC 3920)',
|
||||
'urn:ietf:params:xml:ns:xmpp-bind':'XMPP Core Bind (RFC 3920)',
|
||||
'urn:ietf:params:xml:ns:xmpp-e2e':'XMPP E2E (RFC 3921)',
|
||||
'urn:ietf:params:xml:ns:xmpp-sasl':'XMPP Core Sasl (RFC 3920)',
|
||||
'urn:ietf:params:xml:ns:xmpp-sasl#c2s':'Application supports client-to-server SASL. (RFC 3920)',
|
||||
'urn:ietf:params:xml:ns:xmpp-sasl#s2s':'Application supports server-to-server SASL. (RFC 3920)',
|
||||
'urn:ietf:params:xml:ns:xmpp-session':'XMPP IM (RFC 3921)',
|
||||
'urn:ietf:params:xml:ns:xmpp-stanzas':'XMPP Core Stanzas (RFC 3920)',
|
||||
'urn:ietf:params:xml:ns:xmpp-streams':'XMPP Core Streams (RFC 3920)',
|
||||
'urn:ietf:params:xml:ns:xmpp-tls':'XMPP Core TLS (RFC 3920)',
|
||||
'urn:ietf:params:xml:ns:xmpp-tls#c2s':'Application supports client-to-server TLS. (RFC 3920)',
|
||||
'urn:ietf:params:xml:ns:xmpp-tls#s2s':'Application supports server-to-server TLS. (RFC 3920)',
|
||||
'urn:ietf:rfc:3264':'Jingle ICE-UDP Transport Method (XEP-0176)',
|
||||
'urn:xmpp:archive:auto':'Server supports automatic message archiving (XEP-0136)',
|
||||
'urn:xmpp:archive:manage':'Server supports management of archived messages (XEP-0136)',
|
||||
'urn:xmpp:archive:manual':'Server supports manual message archiving (XEP-0136)',
|
||||
'urn:xmpp:archive:pref':'Server supports message archiving preferences (XEP-0136)',
|
||||
'urn:xmpp:avatar:data':'User Avatars (XEP-0084)',
|
||||
'urn:xmpp:avatar:metadata':'User Avatars (XEP-0084)',
|
||||
'urn:xmpp:avatar:metadata+notify':'User Avatars and notify (XEP-0084)',
|
||||
'http://www.xmpp.org/extensions/xep-0084.html#ns-metadata+notify':'User Avatars and notify (XEP-0084)',
|
||||
'urn:xmpp:delay':'Delayed Delivery (XEP-0203)',
|
||||
'urn:xmpp:jingle:apps:rtp:audio':'Jingle RTP Sessions (XEP-0167)',
|
||||
'urn:xmpp:jingle:apps:rtp:video':'Jingle RTP Sessions (XEP-0167)',
|
||||
'urn:xmpp:ping':'XMPP Ping (XEP-0199)',
|
||||
'urn:xmpp:receipts':'Message Receipts (XEP-0184)',
|
||||
'urn:xmpp:ssn':'Support for Stanza Session Negotiation and its FORM_TYPE (XEP-0155)',
|
||||
'urn:xmpp:time':'Entity Time (XEP-0202)',
|
||||
'xmllang':'Application supports the \'xml:lang\' attribute as described in RFC 3920. (RFC 3920)',
|
||||
'vcard-temp':'vCard-temp (XEP-0054)',
|
||||
'http://jabber.org/protocol/admin':'Admin (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#add-user':'Add-user (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#delete-user':'Delete-user (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#disable-user':'Disable-user (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#reenable-user':'Reenable-user (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#end-user-session':'End-user-session (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#get-user-password':'Get-user-password (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#change-user-password':'Change-user-password (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#get-user-roster':'Get-user-roster (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#get-user-lastlogin':'Get-user-lastlogin (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#user-stats':'User-stats (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#edit-blacklist':'Edit-blacklist (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#edit-whitelist':'Edit-whitelist (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#get-registered-users-num':'Get-registered-users-num (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#get-disabled-users-num':'Get-disabled-users-num (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#get-online-users-num':'Get-online-users-num (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#get-active-users-num':'Get-active-users-num (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#get-idle-users-num':'Get-idle-users-num (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#get-registered-users-list':'Get-registered-users-list (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#get-disabled-users-list':'Get-disabled-users-list (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#get-online-users-list':'Get-online-users-list (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#get-active-users-list':'Get-active-users-list (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#get-idle-users-list':'Get-idle-users-list (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#announce':'Announce (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#set-motd':'Set-motd (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#edit-motd':'Edit-motd (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#delete-motd':'Delete-motd (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#set-welcome':'Set-welcome (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#delete-welcome':'Delete-welcome (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#edit-admin':'Edit-admin (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#restart':'Restart (XEP-0133)',
|
||||
'http://jabber.org/protocol/admin#shutdown':'Shutdown (XEP-0133)',
|
||||
'jabber:iq:agents':'Agents (XEP-0094, Historical)',
|
||||
'jabber:iq:avatar':'Avatar (XEP-0008, Historical)',
|
||||
'http://jabberd.jabberstudio.org/ns/component/1.0':'Jabberstudio Component (Jabberd2)',
|
||||
'jabber:server:dialback':'Dialback (RFC 3921)',
|
||||
'http://jabber.org/protocol/si/profile/file-transfer':'File Transfer (XEP-0096)',
|
||||
'presence-invisible':'Presence invisible (Jabberd2)',
|
||||
'iq':'Iq (Jabberd2)',
|
||||
'message':'Message (Jabberd2)',
|
||||
'http://jabber.org/protocol/muc#unique':'Muc Unicue (XEP-0045)',
|
||||
'http://jabber.org/protocol/muc#request':'Muc Request (XEP-0045)',
|
||||
'http://jabber.org/protocol/muc#rooms':'Muc Rooms (XEP-0045)',
|
||||
'http://jabber.org/protocol/muc#traffic':'Muc Traffic (XEP-0045)',
|
||||
'http://jabber.org/protocol/nick':'User Nickname (XEP-0172)',
|
||||
'http://jabber.org/protocol/nick+notify':'Nick and notify (XEP-0172)',
|
||||
'http://jabber.org/protocol/physloc':'Physloc User Geolocation (XEP-0112)',
|
||||
'presence':'Presence (Jabberd2)',
|
||||
'http://jabber.org/protocol/pubsub':'PubSub (XEP-0060)',
|
||||
'http://jabber.org/protocol/rc':'Remote Controllling Clients (XEP-0146)',
|
||||
'http://jabber.org/protocol/si':'SI File Transfer (XEP-0096)',
|
||||
'http://etherx.jabber.org/streams':'Etherx streams (RFC 3920)',
|
||||
'jabber:iq:time':'Iq:time (XEP-0090, Deprecated)',
|
||||
'http://jabber.org/protocol/vacation':'Vacalation (XEP-0109)',
|
||||
'vcard-temp:x:update':'vCard-Based Avatars (XEP-0153)',
|
||||
'http://jabber.org/protocol/stats':'Stats (XEP-0039)',
|
||||
'http://jabber.ru/muc-filter':'Muc-filter (Experimental!)',
|
||||
'jabber:x:avatar':'Avatar (XEP-0008)',
|
||||
'http://jabber.org/protocol/activity+notify':'User activity and notify (XEP-0108)',
|
||||
'http://jabber.org/protocol/geoloc+notify':'User Geolocation (XEP-0080)',
|
||||
'http://jabber.org/protocol/iqibb':'IqIBB (Unknown)',
|
||||
'http://jabber.org/protocol/mood+notify':'User mood and notify (XEP-0107)',
|
||||
'http://jabber.org/protocol/tune':'User tune (XEP-0118)',
|
||||
'http://jabber.org/protocol/tune+notify':'User tune (XEP-0118)',
|
||||
'games:board':'Games board (No XEP)',
|
||||
'http://jabber.org/protocol/mute#ancestor':'Multi-User Text Editing Ancestor (XEP-0058)',
|
||||
'http://jabber.org/protocol/mute#editor':'Multi-User Text Editing Editor (XEP-0058)',
|
||||
'plugins:alarm':'Plugins Alarm (No XEP)',
|
||||
'http://www.w3.org/2000/svg':'Whiteboard (XEP-XXXX)',
|
||||
'urn:xmpp:attention:0':'Attention (XEP-0224)',
|
||||
'urn:xmpp:bob':'Bits of Binary (XEP-0231)',
|
||||
'urn:xmpp:jingle:1':'Jingle (XEP-0166)',
|
||||
'urn:xmpp:jingle:error:1':'Jingle Error (XEP-0166)',
|
||||
'urn:xmpp:jingle:apps:rtp:1':'Jingle RTP Session (XEP-0167)',
|
||||
'urn:xmpp:jingle:apps:rtp:errors:1':'Jingle RTP Session Errors (XEP-0167)',
|
||||
'urn:xmpp:jingle:apps:rtp:info:1':'Jingle RTP Session Info (XEP-0167)',
|
||||
'urn:xmpp:jingle:transports:ice-udp:1':'Jingle ICE-UDP Transport Method (XEP-0176)',
|
||||
'urn:xmpp:jingle:transports:raw-udp:1':'Jingle RAW-UDP Transport Method (XEP-0176)',
|
||||
'http://jabber.org/protocol/pubsub#errors':'Publish-Subscribe (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#event':'Publish-Subscribe (XEP-0060)',
|
||||
'http://jabber.org/protocol/pubsub#owner':'Publish-Subscribe (XEP-0060)',
|
||||
'jabber:x:conference':'Direct MUC Invitations (XEP-0249)',
|
||||
'urn:xmpp:archive':'Message Archiving (XEP-0136)',
|
||||
'urn:xmpp:captcha':'CAPTCHA Forms (XEP-0158)',
|
||||
'urn:xmpp:errors':'Application-Specific Error Conditions (XEP-0182)',
|
||||
'urn:xmpp:langtrans':'Language Translation (XEP-0171)',
|
||||
'urn:xmpp:langtrans#items':'Language Translation Items (XEP-0171)',
|
||||
'urn:xmpp:media-element':'Data Forms Media Element (XEP-0221)',
|
||||
'urn:xmpp:pie':'Portable Import/Export Format for XMPP-IM Servers (XEP-0227)',
|
||||
'urn:xmpp:sm:2':'Stream Management (XEP-0198)',
|
||||
'urn:xmpp:xbosh':'XMPP Over BOSH (XEP-0206)',
|
||||
'http://jabber.org/protocol/sxe':'http://jabber.org/protocol/sxe',
|
||||
'http://miranda-im.org/caps/secureim':'http://miranda-im.org/caps/secureim',
|
||||
'bugs':'bugs',
|
||||
'http://qip.ru/x-status':'http://qip.ru/x-status',
|
||||
'http://www.xmpp.org/extensions/xep-0116.html#ns':'Encrypted Session Negotiation (XEP-0116)',
|
||||
'urn:xmpp:sec-label:0':'urn:xmpp:sec-label:0',
|
||||
'jabber:iq:dtcp':'jabber:iq:dtcp',
|
||||
'jabber:iq:filexfer':'jabber:iq:filexfer',
|
||||
'jabber:iq:ibb':'jabber:iq:ibb',
|
||||
'jabber:iq:inband':'jabber:iq:inband',
|
||||
'jabber:iq:jidlink':'jabber:iq:jidlink',
|
||||
'urn:xmpp:message-correct:0':'Last Message Correction (XEP-0308)'}
|
||||
|
||||
def disco_features_add(i):
|
||||
for t in bot_features: i.getTag('query').setTag('feature',attrs={'var':t})
|
||||
return i
|
||||
|
||||
def disco_ext_info_add(i):
|
||||
i.getTag('query').setTag('identity',attrs={'xml:lang':CURRENT_LOCALE,'category':id_category,'type':id_type,'name':id_name})
|
||||
i.getTag('query').setTag('x',namespace=xmpp.NS_DATA,attrs={'type':'result'})
|
||||
i.getTag('query').getTag('x',namespace=xmpp.NS_DATA).setTag('field',attrs={'var':'FORM_TYPE','type':'hidden'})
|
||||
i.getTag('query').getTag('x',namespace=xmpp.NS_DATA).getTag('field',attrs={'var':'FORM_TYPE','type':'hidden'}).setTagData('value',xmpp.NS_SOFTWAREINFO)
|
||||
for t in bot_softwareinfo.keys():
|
||||
i.getTag('query').getTag('x',namespace=xmpp.NS_DATA).setTag('field',attrs={'var':t})
|
||||
i.getTag('query').getTag('x',namespace=xmpp.NS_DATA).getTag('field',attrs={'var':t}).setTagData('value',bot_softwareinfo[t])
|
||||
return i
|
||||
|
||||
def disco_iq_get(iq,id,room,acclvl,query,towh,al):
|
||||
if iq.getTag(name='query', namespace=xmpp.NS_DISCO_INFO):
|
||||
node=get_tag_item(unicode(query),'query','node')
|
||||
if node.split('#')[0] in ['', disco_config_node, xmpp.NS_COMMANDS] or node in [xmpp.NS_MUC_ROOMS, '%s#%s' % (capsNode,capsHash)]:
|
||||
pprint('*** iq:disco_info from %s node "%s"' % (unicode(room),node),'magenta')
|
||||
i=xmpp.Iq(to=room, typ='result')
|
||||
i.setAttr(key='id', val=id)
|
||||
if node == '': i.setQueryNS(namespace=xmpp.NS_DISCO_INFO)
|
||||
else: i.setTag('query',namespace=xmpp.NS_DISCO_INFO,attrs={'node':node})
|
||||
if node == '' or node == '%s#%s' % (capsNode,capsHash):
|
||||
i = disco_features_add(i)
|
||||
sender(disco_ext_info_add(i))
|
||||
raise xmpp.NodeProcessed
|
||||
elif node == xmpp.NS_MUC_ROOMS:
|
||||
#i.getTag('query').setTag('feature',attrs={'var':xmpp.NS_MUC_ROOMS})
|
||||
return i
|
||||
elif node.split('#')[0] == disco_config_node or node == xmpp.NS_COMMANDS:
|
||||
if node != xmpp.NS_COMMANDS:
|
||||
i.getTag('query').setTag('feature',attrs={'var':xmpp.NS_COMMANDS})
|
||||
#i.getTag('query').setTag('feature',attrs={'var':disco_config_node})
|
||||
#i.getTag('query').setTag('feature',attrs={'var':xmpp.NS_DATA})
|
||||
try: tn = '#' + node.split('#')[1]
|
||||
except: tn = ''
|
||||
if tn:
|
||||
if tn.split('-',1)[0] == '#owner': settz = owner_groups
|
||||
elif tn.split('-',1)[0] == '#room': settz = config_groups
|
||||
else: settz = None
|
||||
if settz:
|
||||
for tmp in settz:
|
||||
if tn == tmp[1]:
|
||||
i.getTag('query').setTag('identity',attrs={'category':'automation','type':'command-node','name':tmp[0]})
|
||||
break
|
||||
return i
|
||||
|
||||
elif iq.getTag(name='query', namespace=xmpp.NS_DISCO_ITEMS):
|
||||
node=get_tag_item(unicode(query),'query','node')
|
||||
pprint('*** iq:disco_items from %s node "%s"' % (unicode(room),node),'magenta')
|
||||
if node == xmpp.NS_MUC_ROOMS and GT('iq_show_rooms_disco'):
|
||||
i=xmpp.Iq(to=room, typ='result')
|
||||
i.setAttr(key='id', val=id)
|
||||
i.setTag('query',namespace=xmpp.NS_DISCO_ITEMS,attrs={'node':node})
|
||||
if al == 9: cnf = cur_execute_fetchall("select room from conference;")
|
||||
else: cnf = cur_execute_fetchall("select room from conference where split_part(room,'/',1) not in (select room from hiden_rooms as hrr);")
|
||||
trooms = [t[0] for t in cnf]
|
||||
trooms.sort()
|
||||
trooms = [xmpp.Node('item',attrs={'jid':t}) for t in trooms]
|
||||
i.getTag('query',namespace=xmpp.NS_DISCO_ITEMS).setPayload(trooms)
|
||||
return i
|
||||
elif node.split('#')[0] in [disco_config_node, xmpp.NS_COMMANDS] and acclvl:
|
||||
try: tn = '#' + node.split('#')[1]
|
||||
except: tn = ''
|
||||
i=xmpp.Iq(to=room, typ='result')
|
||||
i.setAttr(key='id', val=id)
|
||||
if node == '': i.setQueryNS(namespace=xmpp.NS_DISCO_ITEMS)
|
||||
else: i.setTag('query',namespace=xmpp.NS_DISCO_ITEMS,attrs={'node':node})
|
||||
if node == '' or node == xmpp.NS_COMMANDS:
|
||||
if towh == selfjid: settings_set = owner_groups
|
||||
else: settings_set = config_groups
|
||||
for tmp in settings_set: i.getTag('query').setTag('item',attrs={'node':disco_config_node+tmp[1], 'name':L(tmp[0],room),'jid':towh})
|
||||
return i
|
||||
elif node == '' and al > 3:
|
||||
i=xmpp.Iq(to=room, typ='result')
|
||||
i.setAttr(key='id', val=id)
|
||||
i.setQueryNS(namespace=xmpp.NS_DISCO_ITEMS)
|
||||
if acclvl: i.getTag('query').setTag('item',attrs={'node':xmpp.NS_COMMANDS, 'name':L('AD-Hoc commands'),'jid':towh})
|
||||
i.getTag('query').setTag('item',attrs={'node':xmpp.NS_MUC_ROOMS, 'name':L('Current bot rooms'),'jid':towh})
|
||||
return i
|
||||
return None
|
||||
|
||||
def disco_iq_set(iq,id,room,acclvl,query,towh,al):
|
||||
if iq.getTag(name='command', namespace=xmpp.NS_COMMANDS) and acclvl:
|
||||
node=get_tag_item(unicode(iq),'command','node')
|
||||
if get_tag_item(unicode(iq),'command','action') == 'execute' and (node.split('#')[0] in ['', disco_config_node, xmpp.NS_COMMANDS] or node == xmpp.NS_MUC_ROOMS):
|
||||
pprint('*** iq:ad-hoc commands from %s node "%s"' % (unicode(room),node),'magenta')
|
||||
i=xmpp.Iq(to=room, typ='result')
|
||||
i.setAttr(key='id', val=id)
|
||||
if node == '': i.setQueryNS(namespace=xmpp.NS_DISCO_INFO)
|
||||
else: i.setTag('query',namespace=xmpp.NS_DISCO_ITEMS,attrs={'node':node})
|
||||
if node == '':
|
||||
i = disco_features_add(i)
|
||||
sender(disco_ext_info_add(i))
|
||||
raise xmpp.NodeProcessed
|
||||
elif node == xmpp.NS_MUC_ROOMS and GT('iq_show_rooms_disco'):
|
||||
if al == 9: cnf = cur_execute_fetchall("select room from conference;")
|
||||
else: cnf = cur_execute_fetchall("select room from conference where split_part(room,'/',1) not in (select room from hiden_rooms as hrr);")
|
||||
trooms = [t[0] for t in cnf]
|
||||
trooms.sort()
|
||||
trooms = [xmpp.Node('item',attrs={'jid':t}) for t in trooms]
|
||||
i.getTag('query',namespace=xmpp.NS_DISCO_ITEMS).setPayload(trooms)
|
||||
return i
|
||||
elif node.split('#')[0] == disco_config_node or node == xmpp.NS_COMMANDS:
|
||||
if node != xmpp.NS_COMMANDS:
|
||||
i.getTag('query').setTag('feature',attrs={'var':xmpp.NS_COMMANDS})
|
||||
#i.getTag('query').setTag('feature',attrs={'var':xmpp.NS_DATA})
|
||||
#i.getTag('query').setTag('feature',attrs={'var':disco_config_node})
|
||||
try: tn = '#' + node.split('#')[1]
|
||||
except: tn = ''
|
||||
try: tmpn = tn.split('-',1)[1]
|
||||
except: tmpn = ''
|
||||
if tmpn:
|
||||
action=get_tag_item(unicode(iq),'command','action')
|
||||
i=xmpp.Iq(to=room, typ='result')
|
||||
i.setAttr(key='id', val=id)
|
||||
if action == 'cancel': i.setTag('command',namespace=xmpp.NS_COMMANDS,attrs={'status':'canceled', 'node':disco_config_node+tn,'sessionid':id})
|
||||
elif towh == selfjid:
|
||||
if get_tag_item(unicode(iq),'x','type') == 'submit':
|
||||
varz = iq.getTag('command').getTag('x')
|
||||
sucess_label,unsucess = True,[]
|
||||
for t in owner_prefs.keys():
|
||||
try:
|
||||
tp = owner_prefs[t][1]
|
||||
tm = varz.getTag('field',attrs={'var':t}).getTags('value')
|
||||
tm = '\n'.join([tm2.getData() for tm2 in tm])
|
||||
old_tm = GT(t)
|
||||
try:
|
||||
if tp[0] == 'b': tm = [False,True][int(tm)]
|
||||
elif tp[0] == 'f': tm = float(tm)
|
||||
elif tp[0] == 'i': tm = int(tm)
|
||||
elif tp[0] == 't': tm = tm[:int(tp.replace('e','')[1:])]
|
||||
elif tp[0] == 'm': tm = tm[:int(tp.replace('e','')[1:])]
|
||||
elif tp[0] == 'l' and len(json.loads(tm)) == int(tp.replace('e','')[1:]): tm = json.loads(tm)
|
||||
elif tp[0] == 'd' and tm not in owner_prefs[t][3]: tm = owner_prefs[t][2]
|
||||
except:
|
||||
tm,sucess_label = GT(t),False
|
||||
unsucess.append(L(owner_prefs[t][0],room))
|
||||
PT(t,tm)
|
||||
if tp[-1] == 'e' and old_tm != tm: eval(owner_prefs[t][-1])
|
||||
except: pass
|
||||
sucess_answer = [L('Settings unsuccesfully accepted:\n%s',room) % '\n'.join(unsucess),L('Settings succesfully accepted',room)][sucess_label]
|
||||
i.setTag('command',namespace=xmpp.NS_COMMANDS,attrs={'status':'completed', 'node':disco_config_node+tn,'sessionid':id})
|
||||
i.getTag('command').setTag('note',attrs={'type':'info'})
|
||||
i.getTag('command').setTagData('note',sucess_answer)
|
||||
i.getTag('command').setTag('x',namespace=xmpp.NS_DATA)
|
||||
i.getTag('command').getTag('x').setTagData('title',L('Settings',room))
|
||||
i.getTag('command').getTag('x').setTagData('instrustion',sucess_answer)
|
||||
pprint('*** bot reconfigure by %s' % unicode(room),'purple')
|
||||
else:
|
||||
i.setTag('command',namespace=xmpp.NS_COMMANDS,attrs={'status':'executing', 'node':disco_config_node+tn,'sessionid':id})
|
||||
i.getTag('command').setTag('x',namespace=xmpp.NS_DATA,attrs={'type':'form'})
|
||||
#i.getTag('command').getTag('x').setTag('item',attrs={'node':disco_config_node+tn, 'name':'Configuration','jid':selfjid})
|
||||
#i.getTag('command').getTag('x').setTagData('instructions',L('For configure required x:data-compatible client',room))
|
||||
tkeys = []
|
||||
for tmp in owner_groups: tkeys.append(tmp[1])
|
||||
if tn in tkeys:
|
||||
for tmp in owner_groups:
|
||||
if tn == tmp[1]:
|
||||
c_prefs,c_name = tmp[2],tmp[0]
|
||||
break
|
||||
i.getTag('command').getTag('x').setTagData('title',L(c_name,room))
|
||||
cnf_prefs = {}
|
||||
for tmp in c_prefs: cnf_prefs[tmp] = owner_prefs[tmp]
|
||||
tmp = cnf_prefs.keys()
|
||||
tt = []
|
||||
for t in tmp: tt.append((L(owner_prefs[t][0],room),t))
|
||||
tt.sort()
|
||||
tmp = []
|
||||
for t in tt: tmp.append(t[1])
|
||||
for t in tmp:
|
||||
itm = owner_prefs[t]
|
||||
itm_label = L(itm[0],room).replace('%s','').replace(':','').strip()
|
||||
if itm[1][0] == 'b':
|
||||
dc = GT(t) in [True,1,'1','on']
|
||||
i.getTag('command').getTag('x').setTag('field',attrs={'type':'boolean','label':itm_label,'var':t})\
|
||||
.setTagData('value',[0,1][dc])
|
||||
elif itm[1][0] in ['t','i','f','l']:
|
||||
i.getTag('command').getTag('x').setTag('field',attrs={'type':'text-single','label':itm_label,'var':t})\
|
||||
.setTagData('value',unicode(GT(t)))
|
||||
elif itm[1][0] == 'm':
|
||||
tprm = [xmpp.Node('value',payload=prm) for prm in unicode(GT(t)).split('\n')]
|
||||
i.getTag('command').getTag('x').setTag('field',attrs={'type':'text-multi','label':itm_label,'var':t})\
|
||||
.setPayload(tprm)
|
||||
else:
|
||||
i.getTag('command').getTag('x').setTag('field',\
|
||||
attrs={'type':'list-single','label':itm_label,'var':t})\
|
||||
.setTagData('value',GT(t))
|
||||
for t2 in itm[3]:
|
||||
i.getTag('command').getTag('x').getTag('field',\
|
||||
attrs={'type':'list-single','label':itm_label,'var':t})\
|
||||
.setTag('option',attrs={'label':L(t2,room)})\
|
||||
.setTagData('value',t2)
|
||||
else:
|
||||
if get_tag_item(unicode(iq),'x','type') == 'submit':
|
||||
varz = iq.getTag('command').getTag('x')
|
||||
for t in config_prefs.keys():
|
||||
try:
|
||||
tmtype = varz.getTagAttr('field','type')
|
||||
tm = varz.getTag('field',attrs={'var':t}).getTags('value')
|
||||
tm = '\n'.join([tm2.getData() for tm2 in tm])
|
||||
if tmtype == 'boolean' and tm in ['0','1']: tm = [False,True][int(tm)]
|
||||
elif config_prefs[t][2] != None:
|
||||
if config_prefs[t][2] == [True,False] and tm in ['0','1']: tm = [False,True][int(tm)]
|
||||
elif tm in config_prefs[t][2]: pass
|
||||
else: tm = config_prefs[t][3]
|
||||
put_config(getRoom(room),t,tm)
|
||||
except: pass
|
||||
sucess_answer = L('Settings succesfully accepted',room)
|
||||
i.setTag('command',namespace=xmpp.NS_COMMANDS,attrs={'status':'completed', 'node':disco_config_node+tn,'sessionid':id})
|
||||
i.getTag('command').setTag('note',attrs={'type':'info'})
|
||||
i.getTag('command').setTagData('note',sucess_answer)
|
||||
i.getTag('command').setTag('x',namespace=xmpp.NS_DATA)
|
||||
i.getTag('command').getTag('x').setTagData('title',L('Settings',room))
|
||||
i.getTag('command').getTag('x').setTagData('instrustion',sucess_answer)
|
||||
pprint('*** reconfigure by %s' % unicode(room),'purple')
|
||||
else:
|
||||
i.setTag('command',namespace=xmpp.NS_COMMANDS,attrs={'status':'executing', 'node':disco_config_node+tn,'sessionid':id})
|
||||
i.getTag('command').setTag('x',namespace=xmpp.NS_DATA,attrs={'type':'form'})
|
||||
#i.getTag('command').getTag('x').setTag('item',attrs={'node':disco_config_node+tn, 'name':'Configuration','jid':selfjid})
|
||||
#i.getTag('command').getTag('x').setTagData('instructions',L('For configure required x:data-compatible client',room))
|
||||
tkeys = []
|
||||
for tmp in config_groups: tkeys.append(tmp[1])
|
||||
if tn in tkeys:
|
||||
for tmp in config_groups:
|
||||
if tn == tmp[1]:
|
||||
c_prefs,c_name = tmp[2],tmp[0]
|
||||
break
|
||||
i.getTag('command').getTag('x').setTagData('title',L(c_name,room))
|
||||
cnf_prefs = {}
|
||||
for tmp in c_prefs: cnf_prefs[tmp] = config_prefs[tmp]
|
||||
tmp = cnf_prefs.keys()
|
||||
tmp.sort()
|
||||
for t in tmp:
|
||||
itm = config_prefs[t]
|
||||
itm_label = L(itm[0],room).replace('%s','').replace(':','').strip()
|
||||
itm_desc = L(itm[1],room).strip()
|
||||
if itm[2] == [True,False]:
|
||||
dc = get_config(getRoom(room),t) in [True,1,'1','on']
|
||||
i.getTag('command').getTag('x').setTag('field',attrs={'type':'boolean','label':itm_label,'var':t})\
|
||||
.setTagData('value',[0,1][dc])
|
||||
elif itm[2] == None:
|
||||
if '\n' in itm[3]:
|
||||
tprm = [xmpp.Node('value',payload=prm) for prm in get_config(getRoom(room),t).split('\n')]
|
||||
i.getTag('command').getTag('x').setTag('field',attrs={'type':'text-multi','label':itm_label,'var':t})\
|
||||
.setPayload(tprm)
|
||||
else:
|
||||
i.getTag('command').getTag('x').setTag('field',attrs={'type':'text-single','label':itm_label,'var':t})\
|
||||
.setTagData('value',get_config(getRoom(room),t))
|
||||
else:
|
||||
i.getTag('command').getTag('x').setTag('field',\
|
||||
attrs={'type':'list-single','label':itm_label,'var':t})\
|
||||
.setTagData('value',get_config(getRoom(room),t))
|
||||
for t2 in itm[2]:
|
||||
i.getTag('command').getTag('x').getTag('field',\
|
||||
attrs={'type':'list-single','label':itm_label,'var':t})\
|
||||
.setTag('option',attrs={'label':onoff(t2,room)})\
|
||||
.setTagData('value',t2)
|
||||
i.getTag('command').getTag('x').getTag('field',attrs={'label':itm_label,'var':t})\
|
||||
.setTagData('desc',itm_desc)
|
||||
|
||||
else: i.getTag('command').getTag('x').setTagData('title',L('Unknown configuration request!',room))
|
||||
return i
|
||||
else:
|
||||
if tn:
|
||||
if tn.split('-',1)[0] == '#owner': settz = owner_groups
|
||||
elif tn.split('-',1)[0] == '#room': settz = config_groups
|
||||
else: settz = None
|
||||
if settz:
|
||||
for tmp in settz:
|
||||
if tn == tmp[1]:
|
||||
i.getTag('query').setTag('identity',attrs={'category':'automation','type':'command-node','name':tmp[0]})
|
||||
break
|
||||
return i
|
||||
else:
|
||||
pprint('*** iq:disco_set from %s node "%s"' % (unicode(room),node),'magenta')
|
||||
try: tn = '#' + node.split('#')[1]
|
||||
except: tn = ''
|
||||
if node.split('#')[0] == disco_config_node or node == xmpp.NS_COMMANDS:
|
||||
action=get_tag_item(unicode(iq),'command','action')
|
||||
i=xmpp.Iq(to=room, typ='result')
|
||||
i.setAttr(key='id', val=id)
|
||||
if action == 'cancel': i.setTag('command',namespace=xmpp.NS_COMMANDS,attrs={'status':'canceled', 'node':disco_config_node+tn,'sessionid':id})
|
||||
elif towh == selfjid:
|
||||
if get_tag_item(unicode(iq),'x','type') == 'submit':
|
||||
varz = iq.getTag('command').getTag('x')
|
||||
sucess_label,unsucess = True,[]
|
||||
for t in owner_prefs.keys():
|
||||
try:
|
||||
tp = owner_prefs[t][1]
|
||||
tm = varz.getTag('field',attrs={'var':t}).getTags('value')
|
||||
tm = '\n'.join([tm2.getData() for tm2 in tm])
|
||||
old_tm = GT(t)
|
||||
try:
|
||||
if tp[0] == 'b': tm = [False,True][int(tm)]
|
||||
elif tp[0] == 'f': tm = float(tm)
|
||||
elif tp[0] == 'i': tm = int(tm)
|
||||
elif tp[0] == 't': tm = tm[:int(tp.replace('e','')[1:])]
|
||||
elif tp[0] == 'm': tm = tm[:int(tp.replace('e','')[1:])]
|
||||
elif tp[0] == 'l' and len(json.loads(tm)) == int(tp.replace('e','')[1:]): tm = json.loads(tm)
|
||||
elif tp[0] == 'd' and tm not in owner_prefs[t][3]: tm = owner_prefs[t][2]
|
||||
except:
|
||||
tm,sucess_label = GT(t),False
|
||||
unsucess.append(L(owner_prefs[t][0],room))
|
||||
PT(t,tm)
|
||||
if tp[-1] == 'e' and old_tm != tm: eval(owner_prefs[t][-1])
|
||||
except: pass
|
||||
sucess_answer = [L('Settings unsuccesfully accepted:\n%s',room) % '\n'.join(unsucess),L('Settings succesfully accepted',room)][sucess_label]
|
||||
i.setTag('command',namespace=xmpp.NS_COMMANDS,attrs={'status':'completed', 'node':disco_config_node+tn,'sessionid':id})
|
||||
i.getTag('command').setTag('note',attrs={'type':'info'})
|
||||
i.getTag('command').setTagData('note',sucess_answer)
|
||||
i.getTag('command').setTag('x',namespace=xmpp.NS_DATA)
|
||||
i.getTag('command').getTag('x').setTagData('title',L('Settings',room))
|
||||
i.getTag('command').getTag('x').setTagData('instrustion',sucess_answer)
|
||||
pprint('*** bot reconfigure by %s' % unicode(room),'purple')
|
||||
else:
|
||||
i.setTag('command',namespace=xmpp.NS_COMMANDS,attrs={'status':'executing', 'node':disco_config_node+tn,'sessionid':id})
|
||||
i.getTag('command').setTag('x',namespace=xmpp.NS_DATA,attrs={'type':'form'})
|
||||
#i.getTag('command').getTag('x').setTag('item',attrs={'node':disco_config_node+tn, 'name':'Configuration','jid':selfjid})
|
||||
#i.getTag('command').getTag('x').setTagData('instructions',L('For configure required x:data-compatible client',room))
|
||||
tkeys = []
|
||||
for tmp in owner_groups: tkeys.append(tmp[1])
|
||||
if tn in tkeys:
|
||||
for tmp in owner_groups:
|
||||
if tn == tmp[1]:
|
||||
c_prefs,c_name = tmp[2],tmp[0]
|
||||
break
|
||||
i.getTag('command').getTag('x').setTagData('title',L(c_name,room))
|
||||
cnf_prefs = {}
|
||||
for tmp in c_prefs: cnf_prefs[tmp] = owner_prefs[tmp]
|
||||
tmp = cnf_prefs.keys()
|
||||
tt = []
|
||||
for t in tmp: tt.append((L(owner_prefs[t][0],room),t))
|
||||
tt.sort()
|
||||
tmp = []
|
||||
for t in tt: tmp.append(t[1])
|
||||
for t in tmp:
|
||||
itm = owner_prefs[t]
|
||||
itm_label = L(itm[0],room).replace('%s','').replace(':','').strip()
|
||||
if itm[1] == 'b':
|
||||
dc = GT(t) in [True,1,'1','on']
|
||||
i.getTag('command').getTag('x').setTag('field',attrs={'type':'boolean','label':itm_label,'var':t})\
|
||||
.setTagData('value',[0,1][dc])
|
||||
elif itm[1][0] in ['t','i','f','l']:
|
||||
i.getTag('command').getTag('x').setTag('field',attrs={'type':'text-single','label':itm_label,'var':t})\
|
||||
.setTagData('value',unicode(GT(t)))
|
||||
elif itm[1][0] == 'm':
|
||||
tprm = [xmpp.Node('value',payload=prm) for prm in unicode(GT(t)).split('\n')]
|
||||
i.getTag('command').getTag('x').setTag('field',attrs={'type':'text-multi','label':itm_label,'var':t})\
|
||||
.setPayload(tprm)
|
||||
else:
|
||||
i.getTag('command').getTag('x').setTag('field',\
|
||||
attrs={'type':'list-single','label':itm_label,'var':t})\
|
||||
.setTagData('value',GT(t))
|
||||
for t2 in itm[3]:
|
||||
i.getTag('command').getTag('x').getTag('field',\
|
||||
attrs={'type':'list-single','label':itm_label,'var':t})\
|
||||
.setTag('option',attrs={'label':L(t2,room)})\
|
||||
.setTagData('value',t2)
|
||||
else:
|
||||
if get_tag_item(unicode(iq),'x','type') == 'submit':
|
||||
varz = iq.getTag('command').getTag('x')
|
||||
for t in config_prefs.keys():
|
||||
try:
|
||||
tmtype = varz.getTagAttr('field','type')
|
||||
tm = varz.getTag('field',attrs={'var':t}).getTags('value')
|
||||
tm = '\n'.join([tm2.getData() for tm2 in tm])
|
||||
if tmtype == 'boolean' and tm in ['0','1']: tm = [False,True][int(tm)]
|
||||
elif config_prefs[t][2] != None:
|
||||
if config_prefs[t][2] == [True,False] and tm in ['0','1']: tm = [False,True][int(tm)]
|
||||
elif tm in config_prefs[t][2]: pass
|
||||
else: tm = config_prefs[t][3]
|
||||
put_config(getRoom(room),t,tm)
|
||||
except: pass
|
||||
sucess_answer = L('Settings succesfully accepted',room)
|
||||
i.setTag('command',namespace=xmpp.NS_COMMANDS,attrs={'status':'completed', 'node':disco_config_node+tn,'sessionid':id})
|
||||
i.getTag('command').setTag('note',attrs={'type':'info'})
|
||||
i.getTag('command').setTagData('note',sucess_answer)
|
||||
i.getTag('command').setTag('x',namespace=xmpp.NS_DATA)
|
||||
i.getTag('command').getTag('x').setTagData('title',L('Settings',room))
|
||||
i.getTag('command').getTag('x').setTagData('instrustion',sucess_answer)
|
||||
|
||||
pprint('*** reconfigure by %s' % unicode(room),'purple')
|
||||
else:
|
||||
i.setTag('command',namespace=xmpp.NS_COMMANDS,attrs={'status':'executing', 'node':disco_config_node+tn,'sessionid':id})
|
||||
i.getTag('command').setTag('x',namespace=xmpp.NS_DATA,attrs={'type':'form'})
|
||||
#i.getTag('command').getTag('x').setTag('item',attrs={'node':disco_config_node+tn, 'name':'Configuration','jid':selfjid})
|
||||
#i.getTag('command').getTag('x').setTagData('instructions',L('For configure required x:data-compatible client',room))
|
||||
tkeys = []
|
||||
for tmp in config_groups: tkeys.append(tmp[1])
|
||||
if tn in tkeys:
|
||||
for tmp in config_groups:
|
||||
if tn == tmp[1]:
|
||||
c_prefs,c_name = tmp[2],tmp[0]
|
||||
break
|
||||
i.getTag('command').getTag('x').setTagData('title',L(c_name,room))
|
||||
cnf_prefs = {}
|
||||
for tmp in c_prefs: cnf_prefs[tmp] = config_prefs[tmp]
|
||||
tmp = cnf_prefs.keys()
|
||||
tmp.sort()
|
||||
for t in tmp:
|
||||
itm = config_prefs[t]
|
||||
itm_label = L(itm[0],room).replace('%s','').replace(':','').strip()
|
||||
itm_desc = L(itm[1],room).strip()
|
||||
if itm[2] == [True,False]:
|
||||
dc = get_config(getRoom(room),t) in [True,1,'1','on']
|
||||
i.getTag('command').getTag('x').setTag('field',attrs={'type':'boolean','label':itm_label,'var':t})\
|
||||
.setTagData('value',[0,1][dc])
|
||||
elif itm[2] == None:
|
||||
if '\n' in itm[3]:
|
||||
tprm = [xmpp.Node('value',payload=prm) for prm in get_config(getRoom(room),t).split('\n')]
|
||||
i.getTag('command').getTag('x').setTag('field',attrs={'type':'text-multi','label':itm_label,'var':t})\
|
||||
.setPayload(tprm)
|
||||
else:
|
||||
i.getTag('command').getTag('x').setTag('field',attrs={'type':'text-single','label':itm_label,'var':t})\
|
||||
.setTagData('value',get_config(getRoom(room),t))
|
||||
else:
|
||||
i.getTag('command').getTag('x').setTag('field',\
|
||||
attrs={'type':'list-single','label':itm_label,'var':t})\
|
||||
.setTagData('value',get_config(getRoom(room),t))
|
||||
for t2 in itm[2]:
|
||||
i.getTag('command').getTag('x').getTag('field',\
|
||||
attrs={'type':'list-single','label':itm_label,'var':t})\
|
||||
.setTag('option',attrs={'label':onoff(t2,room)})\
|
||||
.setTagData('value',t2)
|
||||
i.getTag('command').getTag('x').getTag('field',attrs={'label':itm_label,'var':t})\
|
||||
.setTagData('desc',itm_desc)
|
||||
else: i.getTag('command').getTag('x').setTagData('title',L('Unknown configuration request!',room))
|
||||
return i
|
||||
return None
|
||||
|
||||
def disco_exclude_update():
|
||||
global disco_excl
|
||||
excl = GT('disco_exclude').replace('\r','').replace('\t','').split('\n')
|
||||
disco_excl = []
|
||||
for c in excl:
|
||||
if '#' not in c and len(c): disco_excl.append(c)
|
||||
|
||||
def disco_validate(item):
|
||||
for c in disco_excl:
|
||||
if re.findall(c,' %s ' % item,re.S|re.I|re.U): return None
|
||||
return item
|
||||
|
||||
def smart_sort(item):
|
||||
itm1,itm2,cnt = [],[],0
|
||||
for t in item:
|
||||
itm1.append([t.lower(),cnt])
|
||||
cnt += 1
|
||||
itm1.sort()
|
||||
for t in itm1: itm2.append(item[t[1]])
|
||||
return itm2
|
||||
|
||||
def features(type, jid, nick, text):
|
||||
global iq_answer,iq_request
|
||||
text = text.strip()
|
||||
if text == '': where,what = '%s/%s' % (getRoom(jid),nick),''
|
||||
else:
|
||||
text = text.split('\n')
|
||||
where = text[0]
|
||||
try: what = text[1]
|
||||
except: what = ''
|
||||
for mega1 in megabase:
|
||||
if mega1[0] == jid and mega1[1] == text[0]:
|
||||
where = '%s/%s' % (getRoom(jid),text[0])
|
||||
break
|
||||
iqid = get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':where}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_DISCO_INFO},[])])
|
||||
iq_request[iqid]=(time.time(),features_async,[type, jid, nick, what, where],xmpp.NS_DISCO_INFO)
|
||||
sender(i)
|
||||
|
||||
def features_async(type, jid, nick, what, where, is_answ):
|
||||
isa = is_answ[1]
|
||||
if len(isa) >= 2 and isa[1] == 'error': msg = L('Error! %s','%s/%s'%(jid,nick)) % L(isa[0].capitalize().replace('-',' '),'%s/%s'%(jid,nick))
|
||||
else:
|
||||
isa, ftr, client_features = isa[1], [], []
|
||||
for f in [t.getAttr('var') for t in isa.getTag('query',namespace=xmpp.NS_DISCO_INFO).getTags('feature')]:
|
||||
client_features.append(f)
|
||||
if disco_features_list.has_key(f): ft = '- %s' % disco_features_list[f]
|
||||
else: ft = L('- Unknown feature: %s','%s/%s'%(jid,nick)) % f
|
||||
if (what and (what.lower() in ft.lower() or what.lower() in f.lower())) or not what: ftr.append(ft)
|
||||
|
||||
ftrs,erc,q_features = {},0,['os_version','os','software_version','software']
|
||||
client_softwareinfo = {}
|
||||
for t in q_features:
|
||||
try:
|
||||
res = isa.getTag('query').getTag('x',namespace=xmpp.NS_DATA).getTag('field',attrs={'var':t}).getTagData('value')
|
||||
client_softwareinfo[t] = res
|
||||
except:
|
||||
res = 'N/A'
|
||||
erc += 1
|
||||
ftrs[t] = res
|
||||
|
||||
if erc != len(q_features):
|
||||
f = L('Software: %s | Version: %s\nOS: %s | Version: %s','%s/%s'%(jid,nick)) % (ftrs['software'],ftrs['software_version'],ftrs['os'],ftrs['os_version'])
|
||||
if (what and what.lower() in f.lower()) or not what: ftr.append(f)
|
||||
id_category,id_type,id_name,id_lang = '','','',''
|
||||
try:
|
||||
ids_t = isa.getTag('query').getTags('identity')
|
||||
idk = {'type':L('Type: %s','%s/%s'%(jid,nick)), 'name':L('Name: %s','%s/%s'%(jid,nick)), 'category':L('Category: %s','%s/%s'%(jid,nick)), 'xml:lang':L('Language: %s','%s/%s'%(jid,nick))}
|
||||
for tg in ids_t:
|
||||
ids = tg.getAttrs()
|
||||
idf = []
|
||||
for t in idk.keys():
|
||||
if ids.has_key(t):
|
||||
idf.append(idk[t] % ids[t])
|
||||
if t == 'type': id_type = ids[t]
|
||||
elif t == 'name': id_name = ids[t]
|
||||
elif t == 'category': id_category = ids[t]
|
||||
elif t == 'xml:lang': id_lang = ids[t]
|
||||
if idf:
|
||||
f = ' | '.join(idf)
|
||||
if (what and what.lower() in f.lower()) or not what: ftr.append(f)
|
||||
except: pass
|
||||
|
||||
if ftr:
|
||||
f = []
|
||||
for tmp in ftr:
|
||||
if tmp not in f: f.append(tmp)
|
||||
f.sort()
|
||||
msg = L('Features list:\n%s','%s/%s'%(jid,nick)) % '\n'.join(f)
|
||||
_hash = '%s<' % '/'.join([t.replace('/','//') for t in [id_category,id_type,id_lang,id_name]])
|
||||
client_features.sort()
|
||||
_hash += ''.join(['%s<' % t for t in client_features])
|
||||
if client_softwareinfo:
|
||||
_hash += '%s<' % xmpp.NS_SOFTWAREINFO
|
||||
tmp = ['%s<%s' % (t,client_softwareinfo[t]) for t in client_softwareinfo.keys()]
|
||||
tmp.sort()
|
||||
_hash += ''.join(['%s<' % t for t in tmp])
|
||||
_hash = _hash.encode('utf-8')
|
||||
_hash_sha1 = 'SHA1: %s' % hashlib.sha1(_hash).digest().encode('base64').replace('\n','')
|
||||
_hash_md5 = 'MD5: %s' % hashlib.md5(_hash).digest().encode('base64').replace('\n','')
|
||||
_hashes = '%s | %s' % (_hash_sha1,_hash_md5)
|
||||
if (what and what.lower() in _hashes.lower()) or not what: msg = '%s\n%s' % (msg, _hashes)
|
||||
else: msg = L('Unable to get features list','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def disco(type, jid, nick, text): disco_r(type, jid, nick, text, True)
|
||||
def disco_raw(type, jid, nick, text): disco_r(type, jid, nick, text, False)
|
||||
|
||||
def disco_r(type, jid, nick, text, raw_type):
|
||||
global iq_answer,iq_request
|
||||
text = text.strip()
|
||||
if text == '':
|
||||
send_msg(type, jid, nick, L('What?','%s/%s'%(jid,nick)))
|
||||
return
|
||||
where = text.lower().split('\n',1)[0].split(' ',1)[0]
|
||||
try: what = text.lower().split('\n',1)[0].split(' ',1)[1]
|
||||
except: what = ''
|
||||
try: hm = int(text.lower().split('\n',1)[1])
|
||||
except: hm = GT('disco_max_limit')
|
||||
iqid = get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':where}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_DISCO_INFO},[])])
|
||||
iq_request[iqid]=(time.time(),disco_features_async,[type, jid, nick, what, where, hm, raw_type],xmpp.NS_DISCO_INFO)
|
||||
sender(i)
|
||||
|
||||
def disco_features_async(type, jid, nick, what, where, hm, raw_type, is_answ):
|
||||
isa = is_answ[1]
|
||||
if len(isa) >= 2 and isa[1] == 'error':
|
||||
msg = L('Error! %s','%s/%s'%(jid,nick)) % L(isa[0].capitalize().replace('-',' '),'%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
return
|
||||
else:
|
||||
disco_type = xmpp.NS_MUC in [t.getAttr('var') for t in isa[1].getTag('query',namespace=xmpp.NS_DISCO_INFO).getTags('feature')]
|
||||
iqid = get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':where}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_DISCO_ITEMS},[])])
|
||||
iq_request[iqid]=(time.time(),disco_async,[type, jid, nick, what, where, hm, disco_type, raw_type, isa[1]],xmpp.NS_DISCO_ITEMS)
|
||||
sender(i)
|
||||
|
||||
def disco_async(type, jid, nick, what, where, hm, disco_type, raw_type, isa_prev, is_answ):
|
||||
if len(is_answ[1]) >= 2 and is_answ[1][1] == 'error': msg = L('Error! %s','%s/%s'%(jid,nick)) % L(is_answ[1][0].capitalize().replace('-',' '),'%s/%s'%(jid,nick))
|
||||
else:
|
||||
if disco_type and '@' not in where:
|
||||
cm = []
|
||||
for ii in [[t.getAttr('name'),t.getAttr('jid')] for t in is_answ[1][1].getTag('query',namespace=xmpp.NS_DISCO_ITEMS).getTags('item')]:
|
||||
dname,djid = ii
|
||||
if not dname: dname = ''
|
||||
elif '(' in dname and ')' in dname:
|
||||
try: dsize = int(dname.split('(')[-1].split(')')[0])
|
||||
except: dsize = -1
|
||||
dname = '('.join(dname.split('(')[:-1])
|
||||
else: dsize = -1
|
||||
if dname == djid: djid = ''
|
||||
if not what or what in dname.lower() or what in djid.lower():
|
||||
if raw_type and disco_validate(dname) and disco_validate(djid): cm.append(('%04d' % dsize, dname, djid))
|
||||
elif not raw_type: cm.append(('%04d' % dsize, dname, djid))
|
||||
if len(cm):
|
||||
cm.sort(reverse=True)
|
||||
msg,cnt = L('Total: %s','%s/%s'%(jid,nick)) % len(cm),1
|
||||
for i in cm[:hm]:
|
||||
vl = [int(i[0]),'n/a'][int(i[0]) == -1]
|
||||
if len(i[2]): msg += '\n%s. %s [%s] . %s' % (cnt,i[1],i[2],vl)
|
||||
else: msg += '\n%s. %s . %s' % (cnt,i[1],vl)
|
||||
cnt += 1
|
||||
while ' ' in msg: msg = msg.replace(' ',' ')
|
||||
elif len(what): msg = L('\"%s\" not found','%s/%s'%(jid,nick)) % what
|
||||
else: msg = L('Not found.','%s/%s'%(jid,nick))
|
||||
elif disco_type and '@' in where:
|
||||
cm = []
|
||||
for ii in [t.getAttr('name') for t in is_answ[1][1].getTag('query',namespace=xmpp.NS_DISCO_ITEMS).getTags('item')]:
|
||||
if ii and (not what or what in ii.lower()): cm.append(ii)
|
||||
cm = smart_sort(cm)
|
||||
if len(cm):
|
||||
d_name = reduce_spaces_all(isa_prev.getTag('query',namespace=xmpp.NS_DISCO_INFO).getTagAttr('identity','name'))
|
||||
d_deskr = reduce_spaces_all(isa_prev.getTag('query',namespace=xmpp.NS_DISCO_INFO).getTag('x',namespace=xmpp.NS_DATA).getTag('field',attrs={'var':'muc#roominfo_description'}).getTagData('value'))
|
||||
d_occup = isa_prev.getTag('query',namespace=xmpp.NS_DISCO_INFO).getTag('x',namespace=xmpp.NS_DATA).getTag('field',attrs={'var':'muc#roominfo_occupants'}).getTagData('value')
|
||||
if d_name == d_deskr or not d_deskr: msg = '%s\n%s' % (d_name,L('Total: %s%s','%s/%s'%(jid,nick)) % (d_occup,' - %s' % ', '.join(cm)))
|
||||
else: msg = '%s [%s]\n%s' % (d_name,d_deskr,L('Total: %s%s','%s/%s'%(jid,nick)) % (d_occup,' - %s' % ', '.join(cm)))
|
||||
elif len(what): msg = L('\"%s\" not found','%s/%s'%(jid,nick)) % what
|
||||
else: msg = L('Not found.','%s/%s'%(jid,nick))
|
||||
else:
|
||||
cm = [t.getAttrs() for t in is_answ[1][1].getTag('query',namespace=xmpp.NS_DISCO_ITEMS).getTags('item')]
|
||||
if len(cm):
|
||||
cm.sort()
|
||||
cnt = 1
|
||||
msg = L('Total: %s','%s/%s'%(jid,nick)) % len(cm)
|
||||
for i in cm[:hm]:
|
||||
msg += '\n%s. ' % cnt
|
||||
if i.has_key('name'):
|
||||
msg += '%s ' % i['name']
|
||||
if i.has_key('node'): msg += '[%s] ' % i['node']
|
||||
msg += '%s' % i['jid']
|
||||
cnt += 1
|
||||
else: msg = L('Not found.','%s/%s'%(jid,nick))
|
||||
msg = rss_replace(msg)
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def whereis(type, jid, nick, text):
|
||||
global iq_request,whereis_lock
|
||||
if whereis_lock: send_msg(type, jid, nick, L('This command in use somewhere else. Please try later.','%s/%s'%(jid,nick)))
|
||||
else:
|
||||
if len(text):
|
||||
text = text.split('\n')
|
||||
who = text[0]
|
||||
else: who = nick
|
||||
if len(text)<2: where = getServer(jid)
|
||||
else:
|
||||
if 'conference' in text[1]: where = text[1]
|
||||
else: where = 'conference.'+text[1]
|
||||
iqid = get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':where}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_DISCO_ITEMS},[])])
|
||||
iq_request[iqid]=(time.time(),whereis_async,[type, jid, nick, who, where],xmpp.NS_DISCO_ITEMS)
|
||||
sender(i)
|
||||
|
||||
def whereis_async(type, jid, nick, who, where, is_answ):
|
||||
global iq_request, whereis_answers, whereis_lock
|
||||
isan = unicode(is_answ[1][0])
|
||||
isa = isan.split('<item ')
|
||||
djids = []
|
||||
for ii in isa[1:]:
|
||||
dname = get_subtag(ii,'name').split('(')[-1][:-1]
|
||||
if dname.isdigit() and dname != '0': djids.append(get_subtag(ii,'jid'))
|
||||
send_msg(type, jid, nick, L('Please wait. Result you will be receive in private message approximately %s %s','%s/%s'%(jid,nick)) % (int(len(djids)*(time_nolimit+0.05)), L('sec.','%s/%s'%(jid,nick))))
|
||||
curr_id = 'whereis_%s' % get_id()
|
||||
whereis_lock = True
|
||||
wtd = GT('whereis_time_dec')
|
||||
whereis_id = get_id()
|
||||
whereis_answers[whereis_id] = []
|
||||
for ii in djids:
|
||||
iqid = get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':ii}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_DISCO_ITEMS},[])])
|
||||
iq_request[iqid]=(time.time(),whereis_collect_async,[whereis_id,who],xmpp.NS_DISCO_ITEMS)
|
||||
sender(i)
|
||||
if game_over: return
|
||||
while len(whereis_answers[whereis_id]) != len(djids) and not game_over: time.sleep(wtd)
|
||||
if game_over: return
|
||||
result = []
|
||||
for t in whereis_answers[whereis_id]:
|
||||
if t: result += t
|
||||
whereis_answers.pop(whereis_id)
|
||||
result.sort()
|
||||
if result:
|
||||
msgg = L('matches with nick \"%s\": %s','%s/%s'%(jid,nick)) % (who, len(result))
|
||||
for i in result: msgg += '\n%s\t%s' % (esc_min(i[0]),esc_min(i[1]))
|
||||
else: msgg = L('nick \"%s\" not found.','%s/%s'%(jid,nick)) % who
|
||||
msg = L('Total conferences: %s, available: %s','%s/%s'%(jid,nick)) % (len(isa)-1, '%s, %s' % (len(djids),msgg))
|
||||
send_msg('chat', jid, nick, msg)
|
||||
whereis_lock = None
|
||||
|
||||
def whereis_collect_async(whereis_id,who,is_answ):
|
||||
global whereis_answers
|
||||
try:
|
||||
result = []
|
||||
if is_answ[1][0]:
|
||||
names = re.findall(whereis_regx,is_answ[1][0])
|
||||
if names:
|
||||
conf = get_tag_item(is_answ[1][0],'iq','from')
|
||||
for tmp in names:
|
||||
if who.lower() in tmp.lower(): result.append([tmp,conf])
|
||||
whereis_answers[whereis_id].append(result)
|
||||
except: whereis_answers[whereis_id].append([])
|
||||
|
||||
global execute, iq_hook
|
||||
|
||||
iq_hook = [[100,'get',disco_iq_get],[100,'set',disco_iq_set]]
|
||||
|
||||
disco_exclude_update()
|
||||
|
||||
execute = [(3, 'disco', disco, 2, 'Service discovery.\ndisco server.tld - request information about server\ndisco conference.server.tld [body [size]] - find body string in conference list and show size results\ndisco room@conference.server.tld [body [size]] - find body string in disco room conference and show size results.'),
|
||||
(3, 'disco_raw', disco_raw, 2, 'Service discovery.\ndisco_raw server.tld - request information about server\ndisco_raw conference.server.tld [body [size]] - find body string in conference list and show size results\ndisco_raw room@conference.server.tld [body [size]] - find body string in disco room conference and show size results.'),
|
||||
(4, 'features', features, 2, 'Show features of object'),
|
||||
(7, 'whereis', whereis, 2, 'Find nick on conference server\nwhereis - find your nick on current conference server\nwhereis nick - find nick on current conference server\nwhereis nick\n[conference.]server.tld - find nick on server server.tld')]
|
||||
158
plugins/dist.py
Normal file
158
plugins/dist.py
Normal file
@@ -0,0 +1,158 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# Copyright (C) Vit@liy <vitaliy@root.ua> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
dist_max_search_limit = 100
|
||||
dist_default_search_count = 10
|
||||
|
||||
def points2distance(start, end):
|
||||
"""
|
||||
Calculate distance (in kilometers) between two points given as (latt, long) pairs
|
||||
based on Haversine formula (http://en.wikipedia.org/wiki/Haversine_formula).
|
||||
"""
|
||||
start_latt = math.radians(start[0])
|
||||
start_long = math.radians(start[1])
|
||||
end_latt = math.radians(end[0])
|
||||
end_long = math.radians(end[1])
|
||||
d_long = end_long - start_long
|
||||
a = (math.cos(end_latt) * math.sin(d_long))**2 + (math.cos(start_latt)*math.sin(end_latt)-math.sin(start_latt)*math.cos(end_latt)*math.cos(d_long))**2
|
||||
b = math.sin(start_latt)*math.sin(end_latt) + math.cos(start_latt)*math.cos(end_latt)*math.cos(d_long)
|
||||
dist = math.atan2(math.sqrt(a), b) * 6372.795
|
||||
dist = int(dist + 0.5)
|
||||
return dist
|
||||
|
||||
def city_capitalize(s):
|
||||
s = s.capitalize()
|
||||
for k in re.findall('[ -].', s): s = s.replace(k,k.upper())
|
||||
for tmp in [u'-На-', u' На ', u'-Де-', u' Де ']: s = s.replace(tmp, tmp.lower())
|
||||
return s
|
||||
|
||||
def city(type, jid, nick, text):
|
||||
parameters = text.strip().split(' ', 1)
|
||||
if parameters[0] == 'add' and get_level(jid,nick)[0] == 9:
|
||||
try:
|
||||
tmp = parameters[1].split('\n', 1)
|
||||
place = tmp[0].strip().lower().replace(' - ', '-')
|
||||
if len(tmp) == 2:
|
||||
coords = re.sub('[^-\.\d]+', ' ', tmp[1]).strip().split()
|
||||
if abs(float(coords[0])) < 90 and abs(float(coords[1])) < 180:
|
||||
if not cur_execute_fetchone('select * from dist_user where point ilike %s',(place,)):
|
||||
cur_execute('insert into dist_user values (%s,%s,%s)',(place,coords[1],coords[0]))
|
||||
if base_type not in ['sqlite3','mysql']:
|
||||
conn.commit()
|
||||
msg = L('Added!','%s/%s'%(jid,nick))
|
||||
else: msg = L('This point is in database!','%s/%s'%(jid,nick))
|
||||
elif len(GT('yandex_api_key')) > 60:
|
||||
text = place.encode('utf-8')
|
||||
url = 'http://geocode-maps.yandex.ru/1.x/?geocode=%s&key=%s&format=json&results=1' % (urllib.quote_plus(text), GT('yandex_api_key'))
|
||||
j = json.loads(load_page(url))
|
||||
place_ext = j['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['metaDataProperty']['GeocoderMetaData']['text']
|
||||
coords = j['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['Point']['pos'].split()
|
||||
if not cur_execute_fetchone('select * from dist_user where point ilike %s',(place,)):
|
||||
cur_execute('insert into dist_user values (%s,%s,%s)',(place,coords[1],coords[0]))
|
||||
if base_type not in ['sqlite3','mysql']:
|
||||
conn.commit()
|
||||
msg = L('Added: ','%s/%s'%(jid,nick)) + place_ext + L(' as ','%s/%s'%(jid,nick)) + '"%s"' % place
|
||||
else: msg = L('This point is in database!','%s/%s'%(jid,nick))
|
||||
else: msg = L('Not found Yandex.Map API. Get API-key on http://api.yandex.ru/maps/form.xml','%s/%s'%(jid,nick))
|
||||
except: msg = L('What?','%s/%s'%(jid,nick))
|
||||
elif parameters[0] == 'del' and get_level(jid,nick)[0] == 9:
|
||||
if cur_execute_fetchone('select * from dist_user where point ilike %s',(parameters[1].lower(),)):
|
||||
cur_execute('delete from dist_user where point=%s',(parameters[1].lower(),))
|
||||
if base_type not in ['sqlite3','mysql']:
|
||||
conn.commit()
|
||||
msg = L('Deleted!','%s/%s'%(jid,nick))
|
||||
else: msg = L('This point isn\'t in database!','%s/%s'%(jid,nick))
|
||||
elif parameters[0] == 'map':
|
||||
t = cur_execute_fetchone('select * from dist_user where point ilike %s',(parameters[1].lower(),))
|
||||
if not t: t = cur_execute_fetchone('select * from dist where point ilike %s',(parameters[1].lower(),))
|
||||
if t:
|
||||
tmp = 'http://maps.google.com/maps?ll=%s,%s&spn=0.01,0.01&t=h&q=%s,%s' % (t[1], t[2], t[1], t[2])
|
||||
try: msg = city_capitalize(parameters[1]) + L(' on the map: ','%s/%s'%(jid,nick)) + load_page(SHORT_TINYURL % enidna(tmp).decode('utf-8'))
|
||||
except: msg = city_capitalize(parameters[1]) + L(' on the map: ','%s/%s'%(jid,nick)) + tmp
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
elif parameters[0] == 'search':
|
||||
if len(GT('yandex_api_key')) > 60:
|
||||
text = parameters[1].encode('utf-8')
|
||||
text_tmp = text.split(' ', 1)
|
||||
if re.match('\d+$', text_tmp[0]):
|
||||
results = text_tmp[0]
|
||||
text = text_tmp[1]
|
||||
skip = '0'
|
||||
elif re.match('\d+[-: |]\d+$', text_tmp[0]):
|
||||
tmp = re.sub('[-: |]', ' ', text_tmp[0]).split()
|
||||
results = int(tmp[1]) - int(tmp[0]) + 1
|
||||
skip = int(tmp[0]) - 1
|
||||
text = text_tmp[1]
|
||||
else: results, skip = '5', '0'
|
||||
url = 'http://geocode-maps.yandex.ru/1.x/?geocode=%s&key=%s&format=json&results=%s&skip=%s' % (urllib.quote_plus(text), GT('yandex_api_key'), results, skip)
|
||||
j = json.loads(load_page(url))
|
||||
msg = ''
|
||||
for object in j['response']['GeoObjectCollection']['featureMember']:
|
||||
msg += object['GeoObject']['metaDataProperty']['GeocoderMetaData']['text']
|
||||
msg += ' - (%s)\n' % ', '.join(object['GeoObject']['Point']['pos'].split()[::-1])
|
||||
if msg: msg = '\n' + msg
|
||||
else: msg = L('Not found!','%s/%s'%(jid,nick))
|
||||
else: msg = L('Not found Yandex.Map API. Get API-key on http://api.yandex.ru/maps/form.xml','%s/%s'%(jid,nick))
|
||||
else:
|
||||
t = cur_execute_fetchone('select * from dist_user where point ilike %s',(text.strip().lower(),))
|
||||
if not t:
|
||||
t = cur_execute_fetchone('select * from dist where point ilike %s',(text.strip().lower(),))
|
||||
if t: msg = L(u'%s - latitude: %s, longtitude: %s') % (city_capitalize(t[0]), t[1], t[2])
|
||||
else: msg = L('Not found!','%s/%s'%(jid,nick))
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type,jid,nick,msg)
|
||||
|
||||
def dist(type, jid, nick, text):
|
||||
text,splitter,splitted,points = text.strip(),[' - ','|','\n',' '],False,''
|
||||
if ' ' in text and text.split(' ',1)[0].lower() == 'search':
|
||||
try:
|
||||
dist_count = int(text.split(' ',2)[2])
|
||||
dist_count = 1 if dist_count < 1 else dist_max_search_limit if dist_count > dist_max_search_limit else dist_count
|
||||
except: dist_count = dist_default_search_count
|
||||
tmp = cur_execute_fetchall('select point from dist_user where point ilike %s order by point limit %s',('%%%s%%' % text.split(' ',2)[1].lower(),dist_count))
|
||||
if not tmp: tmp = cur_execute_fetchall('select point from dist where point ilike %s order by point limit %s',('%%%s%%' % text.split(' ',2)[1].lower(),dist_count))
|
||||
if tmp: msg = L('Found: %s','%s/%s'%(jid,nick)) % ', '.join(map(city_capitalize, [t[0] for t in tmp]))
|
||||
else: msg = L('City %s not found','%s/%s'%(jid,nick)) % city_capitalize(text.split(' ',2)[1])
|
||||
else:
|
||||
for tmp in splitter:
|
||||
if tmp in text:
|
||||
points,splitted = text.split(tmp),True
|
||||
break
|
||||
if splitted and len(points)==2:
|
||||
t1 = cur_execute_fetchone('select * from dist_user where point ilike %s',(points[0].lower(),))
|
||||
t2 = cur_execute_fetchone('select * from dist_user where point ilike %s',(points[1].lower(),))
|
||||
if not t1 or not t2:
|
||||
if not t1: t1 = cur_execute_fetchone('select * from dist where point ilike %s',(points[0].lower(),))
|
||||
if not t2: t2 = cur_execute_fetchone('select * from dist where point ilike %s',(points[1].lower(),))
|
||||
if t1 and t2: msg = L('%s km','%s/%s'%(jid,nick)) % points2distance((float(t1[1]), float(t1[2])), (float(t2[1]), float(t2[2])))
|
||||
elif t1: msg = L('City %s not found','%s/%s'%(jid,nick)) % city_capitalize(points[1])
|
||||
elif t2: msg = L('City %s not found','%s/%s'%(jid,nick)) % city_capitalize(points[0])
|
||||
else: msg = L('Cities not found','%s/%s'%(jid,nick))
|
||||
else: msg = L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
send_msg(type,jid,nick,msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'dist', dist, 2, 'Distance between cities.\ndist search city [count of cities]\ndist city1 - city2'),
|
||||
(3, 'city', city, 2, 'Cities and other place-name of the world. Examples:\ncity add place-name\n[latitude, longtitude] - add city to database\ncity del place-name - delete city from database\ncity search [count of results|range of results] place-name - search city\ncity map place-name - city on the map\ncity place-name - coordinates of city')]
|
||||
72
plugins/domain.py
Normal file
72
plugins/domain.py
Normal file
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def domaininfo_raw(type, jid, nick, text):
|
||||
text = text.strip().lower()
|
||||
while ' \n' in text: text = text.replace(' \n','\n')
|
||||
if ''.join(re.findall(u'[-0-9a-zа-я. ]+',text,re.U+re.I)) == text and text.count('.') >= 1 and len(text) > 4:
|
||||
if text.startswith('sites '): t, text, regex = 2, text.split(' ')[1], '<h3>(.*?)<br></font><br><br>'
|
||||
else: t, regex = 1, '</a><br /><h3>(.*?)<br /></font></blockquote>'
|
||||
url = 'http://1whois.ru/index.php?url=%s&t=%s' % (text.encode('idna'),t)
|
||||
body = deidna(html_encode(load_page(url).replace(' ', ' ')))
|
||||
try:
|
||||
body = re.findall(regex, body, re.S)
|
||||
if body: msg = unhtml_hard(''.join(body[0]))
|
||||
else: msg = L('No data!','%s/%s'%(jid,nick))
|
||||
except: msg = L('Unexpected error','%s/%s'%(jid,nick))
|
||||
else: msg = L('Error!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def domaininfo(type, jid, nick, text):
|
||||
text = text.strip().lower()
|
||||
while ' \n' in text: text = text.replace(' \n','\n')
|
||||
if ''.join(re.findall(u'[-0-9a-zа-я. ]+',text,re.U+re.I)) == text and text.count('.') >= 1 and len(text) > 4:
|
||||
if 'sites' in text: t, text, regex, msg = 2, text.split(' ')[1], '<font color="black" size="2">(.*?)</font>', L('Sites at Domain/IP address: %s','%s/%s'%(jid,nick)) % text.split(' ')[1]
|
||||
else: t, regex, msg = 1, '<blockquote><font.*?>(.*?)</font></blockquote>', L('Domain/IP address info:','%s/%s'%(jid,nick))
|
||||
url = 'http://1whois.ru/index.php?url=%s&t=%s' % (text.encode('idna'),t)
|
||||
body = deidna(html_encode(load_page(url).replace(' ', ' ')))
|
||||
try:
|
||||
body = re.findall(regex, body, re.S)[0]
|
||||
if u'Нет данных!' in body: msg += ' '+ L('No data!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
tmp_body = {}
|
||||
body = replacer(body).split('\n')
|
||||
newbody = []
|
||||
for tmp in body:
|
||||
if ':' in tmp:
|
||||
if len(tmp.split(':')[0].split()) <= 2 and len(tmp.split(':')[1]) >= 2:
|
||||
if not tmp_body.has_key(tmp.split(':')[1]):
|
||||
tmp_body[tmp.split(':')[1]]=tmp.split(':')[0]
|
||||
newbody.append(tmp)
|
||||
elif tmp.count(' ') <= 4 and not tmp_body.has_key(tmp):
|
||||
tmp_body[tmp] = tmp
|
||||
newbody.append(tmp)
|
||||
msg += '\n'+'\n'.join(newbody)
|
||||
except: msg = L('Unexpected error','%s/%s'%(jid,nick))
|
||||
else: msg = L('Error!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'domain_info_raw', domaininfo_raw, 2, 'Domain/IP address whois info.'),
|
||||
(3, 'domain_info', domaininfo, 2, 'Domain/IP address whois info.')]
|
||||
110
plugins/drink.py
Normal file
110
plugins/drink.py
Normal file
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def to_drink(type, jid, nick, text):
|
||||
dmas = [L('first','%s/%s'%(jid,nick)),L('second','%s/%s'%(jid,nick)),L('third','%s/%s'%(jid,nick)),L('fourth','%s/%s'%(jid,nick)),
|
||||
L('fifth','%s/%s'%(jid,nick)),L('sixth','%s/%s'%(jid,nick)),L('seventh','%s/%s'%(jid,nick)),L('eighth','%s/%s'%(jid,nick)),
|
||||
L('nineth','%s/%s'%(jid,nick)),L('tenth','%s/%s'%(jid,nick)),L('eleventh','%s/%s'%(jid,nick)),L('twelveth','%s/%s'%(jid,nick)),
|
||||
L('thirteenth','%s/%s'%(jid,nick)),L('fourteenth','%s/%s'%(jid,nick)),L('fivteenth','%s/%s'%(jid,nick)),L('sixteenth','%s/%s'%(jid,nick)),
|
||||
L('seventeenth','%s/%s'%(jid,nick)),L('eighteenth','%s/%s'%(jid,nick)),L('nineteenth','%s/%s'%(jid,nick)),('twentieth'),
|
||||
L('twenty-first','%s/%s'%(jid,nick)),L('twenty-second','%s/%s'%(jid,nick)),L('twenty-third','%s/%s'%(jid,nick)),
|
||||
L('twenty-fourth','%s/%s'%(jid,nick)),L('twenty-fifth','%s/%s'%(jid,nick)),L('twenty-sixth','%s/%s'%(jid,nick)),L('twenty-seventh','%s/%s'%(jid,nick)),
|
||||
L('twenty-eighth','%s/%s'%(jid,nick)),L('twenty-nineth','%s/%s'%(jid,nick)),L('thirtieth','%s/%s'%(jid,nick)),L('thirty-first','%s/%s'%(jid,nick))]
|
||||
mmas1 = [L('january','%s/%s'%(jid,nick)),L('february','%s/%s'%(jid,nick)),L('march','%s/%s'%(jid,nick)),L('april','%s/%s'%(jid,nick)),
|
||||
L('may','%s/%s'%(jid,nick)),L('june','%s/%s'%(jid,nick)),L('july','%s/%s'%(jid,nick)),L('august','%s/%s'%(jid,nick)),
|
||||
L('september','%s/%s'%(jid,nick)),L('october','%s/%s'%(jid,nick)),L('november','%s/%s'%(jid,nick)),L('december','%s/%s'%(jid,nick))]
|
||||
mmas2 = [L('January','%s/%s'%(jid,nick)),L('February','%s/%s'%(jid,nick)),L('March','%s/%s'%(jid,nick)),L('April','%s/%s'%(jid,nick)),
|
||||
L('May','%s/%s'%(jid,nick)),L('June','%s/%s'%(jid,nick)),L('July','%s/%s'%(jid,nick)),L('August','%s/%s'%(jid,nick)),
|
||||
L('September','%s/%s'%(jid,nick)),L('October','%s/%s'%(jid,nick)),L('November','%s/%s'%(jid,nick)),L('December','%s/%s'%(jid,nick))]
|
||||
wday = [L('monday','%s/%s'%(jid,nick)),L('tuesday','%s/%s'%(jid,nick)),L('wendesday','%s/%s'%(jid,nick)),L('thirsday','%s/%s'%(jid,nick)),
|
||||
L('friday','%s/%s'%(jid,nick)),L('saturday','%s/%s'%(jid,nick)),L('sunday','%s/%s'%(jid,nick))]
|
||||
lday = [L('last','%s/%s'%(jid,nick)),L('last','%s/%s'%(jid,nick)),L('Last','%s/%s'%(jid,nick)),L('last','%s/%s'%(jid,nick)),
|
||||
L('Last','%s/%s'%(jid,nick)),L('Last','%s/%s'%(jid,nick)),L('lAst','%s/%s'%(jid,nick))]
|
||||
if os.path.isfile(date_file):
|
||||
ddate = readfile(date_file).decode('UTF')
|
||||
week1 = ''
|
||||
week2 = ''
|
||||
if not ddate: msg = L('Read file error.','%s/%s'%(jid,nick))
|
||||
else:
|
||||
if len(text) <= 2:
|
||||
ltim = tuple(time.localtime())
|
||||
text = '%s %s' % (ltim[2], mmas2[ltim[1]-1])
|
||||
week1 = '%s %s %s' % (ltim[2]/7+(ltim[2]%7 > 0), wday[ltim[6]], mmas2[ltim[1]-1])
|
||||
if ltim[2]+7 > calendar.monthrange(ltim[0], ltim[1])[1]: week2 = '%s %s %s' % (lday[ltim[6]].lower(), wday[ltim[6]], mmas2[ltim[1]-1])
|
||||
or_text = text
|
||||
if text.count('.')==1: text = text.split('.')
|
||||
elif text.count(' ')==1: text = text.split(' ')
|
||||
else: text = [text]
|
||||
msg = ''
|
||||
ddate = ddate.split('\n')
|
||||
ltxt = len(text)
|
||||
for tmp in ddate:
|
||||
if or_text.lower() in tmp.lower(): msg += '\n'+tmp
|
||||
elif week1.lower() in tmp.lower() and week1 != '': msg += '\n'+tmp
|
||||
elif week2.lower() in tmp.lower() and week2 != '': msg += '\n'+tmp
|
||||
else:
|
||||
try:
|
||||
ttmp = tmp.split(' ')[0].split('.')
|
||||
tday = [ttmp[0]]
|
||||
tday.append(dmas[int(ttmp[0])-1])
|
||||
tmonth = [ttmp[1]]
|
||||
tmonth.append(mmas1[int(ttmp[1])-1])
|
||||
tmonth.append(mmas2[int(ttmp[1])-1])
|
||||
tmonth.append(str(int(ttmp[1])))
|
||||
t = tday.index(text[0])
|
||||
t = tmonth.index(text[1])
|
||||
msg += '\n'+tmp
|
||||
except: pass
|
||||
if msg == '': msg = L('Holiday: %s not found.','%s/%s'%(jid,nick)) % or_text
|
||||
else: msg = L('I know holidays: %s','%s/%s'%(jid,nick)) % msg
|
||||
else: msg = L('Database doesn\'t exist.','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def calend(type, jid, nick, text):
|
||||
msg, url, text = '', '', text.strip()
|
||||
if not text: url = 'http://www.calend.ru/day/%s-%s/' % tuple(time.localtime())[1:3]
|
||||
elif re.match('\d+\.\d+$', text): url = 'http://www.calend.ru/day/%s-%s/' % tuple(text.split('.')[::-1])
|
||||
elif len(text) > 1: url = 'http://www.calend.ru/search/?search_str=' + urllib.quote(text.encode('cp1251'))
|
||||
if url:
|
||||
data = html_encode(load_page(url))
|
||||
t = get_tag(data,'title')
|
||||
if t == u'Поиск':
|
||||
hl = re.findall('<a href="(/holidays(?:/\d*?)+?)" title=".+?">(.+?)</a>(?:.|\s)+?/>\s+?(\d+ .+?)\s', data)
|
||||
if len(hl) == 1:
|
||||
d = re.search('class="img_small" /></a></td>\s+?<td>\s+?(.+?\.)\s+?</td>', data, re.S).group(1)
|
||||
d = unescape(re.sub('\s+', ' ', d.strip()))
|
||||
msg += '%s (%s) - %s\nhttp://www.calend.ru%s' % (hl[0][1], hl[0][2], d, hl[0][0])
|
||||
elif hl:
|
||||
for a in hl: msg += '\n%s (%s)' % (a[1], a[2])
|
||||
else:
|
||||
d = get_tag(data,'h1')
|
||||
hl = re.findall('<a href="/holidays(?:/\d*?)+?" title=".+?">(.+?)</a>', data)
|
||||
if hl: msg = '%s:\n%s' % (d, '\n'.join(hl))
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
if not msg: msg = L('Holiday: %s not found.','%s/%s'%(jid,nick)) % text
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'drink', to_drink, 2, 'Find holiday\ndrink [name_holiday/date]'),
|
||||
(3, 'calend', calend, 2, 'Find holiday\ncalend [name_holiday/date]')]
|
||||
48
plugins/dumpz.py
Normal file
48
plugins/dumpz.py
Normal file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) Vit@liy <vitaliy@root.ua> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
dumpz_var = {'sh':'bash', 'bash':'bash', 'c':'c', 'h':'c', 'html':'html', 'htm':'html', 'python':'python', 'py':'python', 'php':'php', 'css':'css', 'sql':'sql', 'cpp':'cpp', 'hpp':'cpp'}
|
||||
|
||||
def dumpz(type, jid, nick, text):
|
||||
try:
|
||||
p = text.split(' ',1)
|
||||
if p[0].lower() in dumpz_var.keys():
|
||||
highlighting = dumpz_var[p[0].lower()]
|
||||
code = p[1]
|
||||
else:
|
||||
highlighting = 'text'
|
||||
code = text
|
||||
values = {'lexer': highlighting, 'code': code.encode('utf-8'),}
|
||||
data = urllib.urlencode(values)
|
||||
req = urllib2.Request('http://dumpz.org/' ,data,{'Content-type':'application/x-www-form-urlencoded'})
|
||||
res = urllib2.urlopen(req)
|
||||
link = res.url
|
||||
msg = L('Posting by URL: %s','%s/%s'%(jid,nick)) % link
|
||||
except:
|
||||
msg = L('Unexpected error','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'dumpz', dumpz, 2, 'Posting text&code on dedicated server for easy sharing.\ndumpz text - posting plain text,\ndumpz [sh|c|html|py|php|css|sql|cpp] - posting text with highlighting')]
|
||||
|
||||
92
plugins/execute.py
Normal file
92
plugins/execute.py
Normal file
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
calc_last_res = {}
|
||||
|
||||
def exec_ute(type, jid, nick, text):
|
||||
try: text = remove_sub_space(unicode(eval(text)))
|
||||
except Exception, SM:
|
||||
try: SM = str(SM)
|
||||
except: SM = unicode(SM)
|
||||
text = L('I can\'t execute it! Error: %s','%s/%s'%(jid,nick)) % SM[:int(msg_limit/2)]
|
||||
send_msg(type, jid, nick, text)
|
||||
|
||||
def calc(type, jid, nick, text):
|
||||
global calc_last_res
|
||||
if 'Ans' in text and calc_last_res.has_key(jid) and calc_last_res[jid].has_key(nick) and calc_last_res[jid][nick]:
|
||||
text = text.replace('Ans', calc_last_res[jid][nick])
|
||||
legal = string.digits + string.letters + '*/+-()=^!<>. '
|
||||
ppc = 1
|
||||
if '**' in text or 'pow' in text or 'factorial' in text: ppc = 0
|
||||
else:
|
||||
for tt in text:
|
||||
if tt not in legal:
|
||||
ppc = 0
|
||||
break
|
||||
if ppc:
|
||||
text = re.sub('([^.0-9]\d+)(?=([^.0-9]|$))', r'\1.0', text)
|
||||
try:
|
||||
text = remove_sub_space(str(eval(re.sub('([^a-zA-Z]|\A)([a-zA-Z])', r'\1math.\2', text))))
|
||||
if text[-2:] == '.0': text = text[:-2]
|
||||
if calc_last_res.has_key(jid): calc_last_res[jid][nick] = text
|
||||
else: calc_last_res[jid] = {nick: text}
|
||||
except:
|
||||
text = L('I can\'t calculate it','%s/%s'%(jid,nick))
|
||||
if calc_last_res.has_key(jid): calc_last_res[jid][nick] = None
|
||||
else: calc_last_res[jid] = {nick: None}
|
||||
else:
|
||||
text = L('Expression unacceptable!','%s/%s'%(jid,nick))
|
||||
if calc_last_res.has_key(jid): calc_last_res[jid][nick] = None
|
||||
else: calc_last_res[jid] = {nick: None}
|
||||
send_msg(type, jid, nick, text)
|
||||
|
||||
def dpi_calc(type, jid, nick, text):
|
||||
text = text.strip().replace(',','.')
|
||||
if text:
|
||||
tupl = re.findall('([0-9.]+)',text)[:3]
|
||||
if len(tupl) == 3:
|
||||
if '.' in tupl[0] or '.' in tupl[1]: msg = L('Width and height must be integer!','%s/%s'%(jid,nick))
|
||||
elif not float(tupl[2]): msg = L('Incorrect diagonal value!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
dpi_type = [0,'L'],[160,'M'],[240,'H'],[320,'XH']
|
||||
dpi = int((math.sqrt(int(tupl[0])**2+int(tupl[1])**2))/float(tupl[2]))
|
||||
dpi_name = 'unknown'
|
||||
for t in dpi_type:
|
||||
if dpi > t[0]: dpi_name = '%sDPI' % t[1]
|
||||
msg = u'%s %s×%s×%s\" - %sdpi [%s]' % (L('Screen','%s/%s'%(jid,nick)),tupl[0],tupl[1],tupl[2],dpi,dpi_name)
|
||||
else: msg = L('Not enough parameters!','%s/%s'%(jid,nick))
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def calc_clear(room,jid,nick,type,arr):
|
||||
if type == 'unavailable' and calc_last_res.has_key(room) and calc_last_res[room].has_key(nick): del calc_last_res[room][nick]
|
||||
|
||||
global execute, presence_control
|
||||
|
||||
presence_control = [calc_clear]
|
||||
|
||||
if not GT('paranoia_mode'): execute = [(3, 'calc', calc, 2, 'Calculator.'),
|
||||
(9, 'exec', exec_ute, 2, 'Execution of external code.')]
|
||||
else: execute = []
|
||||
|
||||
execute.append((3, 'dpi', dpi_calc, 2, 'DPI calculator.\ndpi <width height size>'))
|
||||
97
plugins/flibusta.py
Normal file
97
plugins/flibusta.py
Normal file
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) Vit@liy <vitaliy@root.ua> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
from xml.dom.minidom import parseString
|
||||
|
||||
def flibusta(type, jid, nick, text):
|
||||
text = re.sub(' +', ' ', text).strip()
|
||||
msg = ''
|
||||
if text == 'new':
|
||||
c=urllib.urlopen('http://xpresslib.mobile-master.org/new').read()
|
||||
xml=parseString(c)
|
||||
nodes=xml.getElementsByTagName('book')
|
||||
for el in nodes:
|
||||
f=el.getAttribute('file')
|
||||
size=el.getAttribute('size')
|
||||
author=unicode(el.getAttribute('author'))
|
||||
title=unicode(el.firstChild.data)
|
||||
msg += u'\n%s - %s, %s кБ, http://flibusta.net/b/%s' % (author,title,round(float(size)/1024,1),f.split('.')[0]+'/fb2')
|
||||
if not msg: msg = L('No news','%s/%s'%(jid,nick))
|
||||
else:
|
||||
opt = [i for i in (' ' + text).split(' -') if len(i)>2 and i[1]==' ']
|
||||
opt = dict([i.split(' ', 1) for i in opt])
|
||||
if opt.has_key('n'):
|
||||
if re.match('\d+$', opt['n']): a = b = int(opt['n'])
|
||||
elif re.match('\d+-\d+$', opt['n']): a, b = map(int,opt['n'].split('-'))
|
||||
else: a, b = 1, 5
|
||||
else: a, b = 1, 5
|
||||
if opt.has_key('t'):
|
||||
i={}
|
||||
i['search']=opt['t'].encode('utf-8')
|
||||
d=urllib.urlencode(i)
|
||||
s=urllib.urlopen('http://xpresslib.mobile-master.org/search',d).read()
|
||||
xml=parseString(s)
|
||||
nodes=xml.getElementsByTagName('book')
|
||||
t_book=[]
|
||||
for el in nodes:
|
||||
f0=el.getAttribute('file')
|
||||
size=el.getAttribute('size')
|
||||
author=unicode(el.getAttribute('author'))
|
||||
title=unicode(el.firstChild.data)
|
||||
t_book.append([author,title,size,f0])
|
||||
if opt.has_key('a'): t_book = filter(lambda x: opt['a'].lower() in x[0].lower(), t_book)
|
||||
if t_book:
|
||||
c = len(t_book)
|
||||
if b > c:
|
||||
if b != a: b = c
|
||||
else: a = b = c
|
||||
msg += L('Total found %s matches. Result(s) %s:\n','%s/%s'%(jid,nick)) % (c, a if a == b else '%s-%s' % (a,b))
|
||||
for i in t_book[a-1:b]:
|
||||
msg += u'%s- %s, %s кБ, http://flibusta.net/b/%s\n' % (i[0],i[1],round(float(i[2])/1024,1),i[3].split('.')[0]+'/fb2')
|
||||
elif opt.has_key('a'):
|
||||
i={}
|
||||
i['search']=opt['a'].encode('utf-8')
|
||||
d=urllib.urlencode(i)
|
||||
s=urllib.urlopen('http://xpresslib.mobile-master.org/authors',d).read()
|
||||
xml=parseString(s)
|
||||
nodes=xml.getElementsByTagName('author')
|
||||
a_book=[]
|
||||
for el in nodes:
|
||||
id=el.getAttribute('id')
|
||||
title=unicode(el.firstChild.data)
|
||||
a_book.append([id,title])
|
||||
if a_book:
|
||||
c = len(a_book)
|
||||
if b > c:
|
||||
if b != a: b = c
|
||||
else: a = b = c
|
||||
msg += L('Total found %s matches. Result(s) %s:\n','%s/%s'%(jid,nick)) % (c, a if a == b else '%s-%s' % (a,b))
|
||||
for i in a_book[a-1:b]:
|
||||
msg += '%s- http://flibusta.net/a/%s\n' % (i[1], i[0])
|
||||
|
||||
if not msg: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'flibusta', flibusta, 2, 'Search books and authors on flibusta.net.\nflibusta [-a author] [-t title] [-n number of result]')]
|
||||
252
plugins/fun.py
Normal file
252
plugins/fun.py
Normal file
@@ -0,0 +1,252 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# Copyright (C) Vit@liy <vitaliy@root.ua> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
LAST_RANDOM_POKE = {}
|
||||
LAST_POKE_PHRASE = {}
|
||||
|
||||
def poem(type, jid, nick):
|
||||
dict = [[u'я помню',u'не помню',u'забыть бы',u'купите',u'очкуешь',u'какое',u'угробил',u'открою',u'ты чуешь?'],
|
||||
[u'чудное',u'странное',u'некое',u'вкусное',u'пьяное',u'свинское',u'чоткое',u'сраное',u'нужное',u'конское'],
|
||||
[u'мгновенье,',u'затменье,',u'хотенье,',u'варенье,',u'творенье,',u'везенье,',u'рожденье,',u'смущенье,',u'печенье,',u'ученье,'],
|
||||
[u'\n'],
|
||||
[u'передомной',u'под косячком',u'на кладбище',u'в моих мечтах',u'под скальпилем',u'в моих штанах',u'из-за угла',u'в моих ушах',u'в ночном горшке',u'из головы',],
|
||||
[u'явилась ты,',u'добилась ты,',u'торчат кресты,',u'стихов листы,',u'забилась ты,',u'мои трусы,',u'поют дрозды,',u'из темноты,',u'помылась ты,',u'дают пизды,'],
|
||||
[u'\n'],
|
||||
[u'как'],
|
||||
[u'мимолётное',u'детородное',u'психотропное',u'кайфоломное',u'очевидное',u'у воробушков',u'эдакое вот',u'нам не чуждое',u'благородное',u'ябывдульское'],
|
||||
[u'виденье,',u'сиденье,',u'паренье,',u'сужденье,',u'вращенье,',u'сношенье,',u'смятенье,',u'теченье,',u'паденье,',u'сплетенье,'],
|
||||
[u'\n'],
|
||||
[u'как'],
|
||||
[u'гений',u'сторож',u'символ',u'спарта',u'правда',u'ангел',u'водка',u'пиво',u'ахтунг',u'жопа'],
|
||||
[u'чистой',u'вечной',u'тухлой',u'просит',u'грязной',u'липкой',u'на хрен',u'в пене',u'женской',u'жаждет'],
|
||||
[u'красоты',u'мерзлоты',u'суеты',u'наркоты',u'срамоты',u'школоты',u'типа ты',u'простоты',u'хуеты',u'наготы']]
|
||||
send_msg(type, jid, nick, '\n %s' % ' '.join([random.choice(t) for t in dict]))
|
||||
|
||||
def oracle(type, jid, nick, text):
|
||||
if not text.strip() or text.strip()[-1] != '?': msg = L('What?','%s/%s'%(jid,nick))
|
||||
else: msg = random.choice([L('Yes','%s/%s'%(jid,nick)),
|
||||
L('Yes - definitely','%s/%s'%(jid,nick)),
|
||||
L('You may rely on it','%s/%s'%(jid,nick)),
|
||||
L('Without a doubt','%s/%s'%(jid,nick)),
|
||||
L('Signs point to yes','%s/%s'%(jid,nick)),
|
||||
L('Outlook good','%s/%s'%(jid,nick)),
|
||||
L('Most likely','%s/%s'%(jid,nick)),
|
||||
L('It is decidedly so','%s/%s'%(jid,nick)),
|
||||
L('It is certain','%s/%s'%(jid,nick)),
|
||||
L('As I see it, yes','%s/%s'%(jid,nick)),
|
||||
L('Reply hazy, try again','%s/%s'%(jid,nick)),
|
||||
L('Ask again later','%s/%s'%(jid,nick)),
|
||||
L('Better not tell you now','%s/%s'%(jid,nick)),
|
||||
L('Cannot predict now','%s/%s'%(jid,nick)),
|
||||
L('Concentrate and ask again','%s/%s'%(jid,nick)),
|
||||
L('Don\'t count on it','%s/%s'%(jid,nick)),
|
||||
L('My reply is no','%s/%s'%(jid,nick)),
|
||||
L('Outlook not so good','%s/%s'%(jid,nick)),
|
||||
L('My sources say no','%s/%s'%(jid,nick))])
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def coin(type, jid, nick, text):
|
||||
msg = random.choice([L('Head','%s/%s'%(jid,nick)), L('Tail','%s/%s'%(jid,nick))])
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def to_poke(type, jid, nick, text):
|
||||
if len(text): text = text.strip()
|
||||
if type == 'chat' and get_level(jid,nick)[0] < 7:
|
||||
send_msg(type, jid, nick, L('For members this command not available in private!','%s/%s'%(jid,nick)))
|
||||
return
|
||||
predef_poke = [L('gave NICK ... just gave ... :-\"','%s/%s'%(jid,nick)),
|
||||
L('poked a stick NICK in the eye ...','%s/%s'%(jid,nick)),
|
||||
L('suggested NICK shrimp :-[','%s/%s'%(jid,nick)),
|
||||
L('fed NICK laxative with powdered glass!','%s/%s'%(jid,nick)),
|
||||
L('whispered in his ear softly NICK LOL!','%s/%s'%(jid,nick)),
|
||||
L('trying kick the ass NICK','%s/%s'%(jid,nick)),
|
||||
L('threw the crowbar aside NICK','%s/%s'%(jid,nick)),
|
||||
L('gave NICK strawberry poison','%s/%s'%(jid,nick)),
|
||||
L('jumped around with a tambourine NICK','%s/%s'%(jid,nick)),
|
||||
L('sticking NICK with the words "buy ice cream, you creep!"','%s/%s'%(jid,nick))]
|
||||
owner = get_level(jid,nick)[0] == 9
|
||||
dpoke = getFile(poke_file,predef_poke)
|
||||
t_cmd = text.lower()
|
||||
if t_cmd == 'show' and owner:
|
||||
if type == 'groupchat':
|
||||
send_msg(type, jid, nick, L('Sent in private message','%s/%s'%(jid,nick)))
|
||||
type = 'chat'
|
||||
msg = '%s\n%s' % (L('Phrases:','%s/%s'%(jid,nick)),'\n'.join(['%s. %s' % (c+1,t) for c,t in enumerate(dpoke)]))
|
||||
elif t_cmd.startswith('del ') and owner:
|
||||
text = text[4:]
|
||||
try: pos = int(text)-1
|
||||
except: pos = len(dpoke)+1
|
||||
if pos < 0 or pos > len(dpoke): msg = L('The record doesn\'t exist!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
remove_body = dpoke[pos]
|
||||
dpoke.remove(remove_body)
|
||||
writefile(poke_file, str(dpoke))
|
||||
msg = L('Removed: %s','%s/%s'%(jid,nick)) % remove_body
|
||||
elif t_cmd.startswith('add ') and owner:
|
||||
text = text[4:]
|
||||
if 'NICK' in text:
|
||||
dpoke.append(text)
|
||||
writefile(poke_file, str(dpoke))
|
||||
msg = L('Added','%s/%s'%(jid,nick))
|
||||
else: msg = L('I can\'t add it! No keyword "NICK"!','%s/%s'%(jid,nick))
|
||||
elif get_level(jid,text)[1] == selfjid: msg = L('I ban a ip for such jokes!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
if not text:
|
||||
nick_list = [d[1] for d in megabase if d[0]==jid and d[4] != Settings['jid'] and d[1] != nick]
|
||||
if nick_list:
|
||||
curr_nick = random.choice(nick_list)
|
||||
try: last_nick = LAST_RANDOM_POKE[jid]
|
||||
except: last_nick = ''
|
||||
if len(nick_list) > 1:
|
||||
while curr_nick == last_nick: curr_nick = random.choice(nick_list)
|
||||
LAST_RANDOM_POKE[jid] = curr_nick
|
||||
text, is_found = curr_nick, True
|
||||
else: is_found = False
|
||||
else:
|
||||
is_found = False
|
||||
for tmp in megabase:
|
||||
if tmp[0] == jid and tmp[1] == text:
|
||||
is_found = True
|
||||
break
|
||||
if is_found:
|
||||
try: hl_pokes = list_of_phrases_with_highlight[get_L_('%s/%s'%(jid,nick))]
|
||||
except: hl_pokes = []
|
||||
dp = ['/me %s' % t for t in dpoke]
|
||||
for t in hl_pokes:
|
||||
if t and t not in dp: dp.append(t)
|
||||
try: last_poke = LAST_POKE_PHRASE[jid]
|
||||
except: last_poke = ''
|
||||
msg = random.choice(dp)
|
||||
while last_poke == msg: msg = random.choice(dp)
|
||||
LAST_POKE_PHRASE[jid] = msg
|
||||
msg,nick,type = msg.replace('NICK',text),'','groupchat'
|
||||
elif text: msg = L('I could be wrong, but %s not is here...','%s/%s'%(jid,nick)) % text
|
||||
else: msg = L('Masochist? 8-D','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def life(type, jid, nick, text):
|
||||
text = reduce_spaces_all(text)
|
||||
try:
|
||||
tmp = text.split(' ')
|
||||
d,m,y = tmp[0].strip().split('.')
|
||||
y = int(y)
|
||||
if y<20: y += 2000
|
||||
elif y<100: y += 1900
|
||||
y = str(y)
|
||||
if len(tmp)>1: hour, minute, sec = tmp[1].strip().split(':')
|
||||
else: hour, minute, sec = '00','00','00'
|
||||
BDate = time.mktime(time.strptime(' '.join([y, m, d, hour, minute, sec]), '%Y %m %d %H %M %S'))
|
||||
CDate = time.time()
|
||||
Age = CDate-BDate
|
||||
yrs = int(round(Age/31557600))
|
||||
dys = int(round(Age/86400))
|
||||
hrs = int(round(Age/3600))
|
||||
mins = int(round(Age/60))
|
||||
secs = int(round(Age))
|
||||
spal = int(round(Age*3285/31557600))
|
||||
spal24 = int(round(Age*136.9/31557600))
|
||||
morgnyl = int(round(Age*4160000/31557600))
|
||||
serdcelit = int(round(Age*2372500/31557600))
|
||||
serdceraz = int(round(Age*36500000/31557600))
|
||||
vodal = int(round(Age*750/31557600))
|
||||
voda = int(round(Age*21/31557600))
|
||||
volosicm = int(round(Age*18/31557600))
|
||||
volosi = int(round(Age*25550/31557600))
|
||||
volosivse = int(round(Age*14/31557600))
|
||||
nogtiryk = int(round(Age*5.2/31557600))
|
||||
nogtinog = int(round(Age*1.4/31557600))
|
||||
vozdyx = int(round(Age*3784320/31557600))
|
||||
vozdyxkg = int(round(Age*4881/31557600))
|
||||
pot = int(round(Age*252/31557600))
|
||||
mochalit = int(round(Age*489/31557600))
|
||||
sluni = int(round(Age*337/31557600))
|
||||
nervi = int(round(Age*136/31557600))
|
||||
smex = int(round(Age*5475/31557600))
|
||||
km = int(round(Age*1857/31557600))
|
||||
msg = L('You live %s years or %s days or %s hours or %s minutes or %s seconds.\nYou slept %s hours, or %s days.\nYou blink about %s times.\nYour heart pumped %s liters of blood and made %s strikes.\nYou drank %s liters of water and drank it %s hours.\nYou have increased by %s centimeters in my head of hair, dropped %s pieces, all of the hair %s kilometers.\nYou grew up in the hands %s centimeters and in the feet %s centimeters nails.\nYou breathed %s liters of air a total weight of %s kilograms.\nYou have stood out %s liters of sweat, and %s liters of urine, and %s liters of saliva.\nYou lost %s billion nerve cells.\nYou laughed %s times.\nYou\'ve gone %s kilometers','%s/%s'%(jid,nick)) % (yrs, dys, hrs, mins, secs, spal, spal24, morgnyl, serdcelit, serdceraz, vodal, voda, volosicm, volosi, volosivse, nogtiryk, nogtinog, vozdyx, vozdyxkg, pot, mochalit, sluni, nervi, smex, km)
|
||||
if type == 'groupchat': send_msg(type, jid, nick, L('Send for you in private','%s/%s'%(jid,nick)))
|
||||
send_msg('chat', jid, nick, msg)
|
||||
except: send_msg(type, jid, nick, L('Smoke help about command!','%s/%s'%(jid,nick)))
|
||||
|
||||
def zalgo(type, jid, nick, text):
|
||||
zalgo_threshold = 10
|
||||
zalgo_chars = [unichr(i) for i in range(0x0300, 0x036F + 1)]
|
||||
zalgo_chars.extend([u'\u0488', u'\u0489'])
|
||||
zalgoized = []
|
||||
for letter in text:
|
||||
zalgoized.append(letter)
|
||||
zalgo_num = random.randint(0, zalgo_threshold) + 1
|
||||
for _ in range(zalgo_num):
|
||||
zalgoized.append(random.choice(zalgo_chars))
|
||||
msg = random.choice(zalgo_chars).join(zalgoized)
|
||||
send_msg(type,jid,nick,msg)
|
||||
|
||||
def godville(type, jid, nick, text):
|
||||
text = text.strip()
|
||||
if ' ' in text:
|
||||
mode, name = text.split(' ', 1)
|
||||
else:
|
||||
mode, name = 'last', text
|
||||
if not mode in ['stat', 'extstat', 'last', 'inv', 'quest']:
|
||||
mode, name = 'last', text
|
||||
data = load_page('http://godville.net/gods/api/%s.json' % name.encode('utf-8'))
|
||||
try:
|
||||
data = json.loads(data)
|
||||
if mode == 'last':
|
||||
try:
|
||||
msg = '%s: %s' % (data['name'], data['diary_last'])
|
||||
except:
|
||||
msg = L('Turn on extended API on game\'s settings','%s/%s'%(jid,nick))
|
||||
elif mode in ['stat', 'extstat']:
|
||||
msg = L('Name: %s\n','%s/%s'%(jid,nick)) % data['name']
|
||||
msg += L('Gold: %s\n','%s/%s'%(jid,nick)) % data['gold_approx']
|
||||
msg += L('Level: %s\n','%s/%s'%(jid,nick)) % data['level']
|
||||
msg += L('Alignment: %s\n','%s/%s'%(jid,nick)) % data['alignment']
|
||||
msg += L('Motto: %s','%s/%s'%(jid,nick)) % data['motto']
|
||||
if data['clan']:
|
||||
msg += L('\nClan: %s (%s)','%s/%s'%(jid,nick)) % (data['clan'], data['clan_position'])
|
||||
if mode == 'extstat' and 'godpower' in data:
|
||||
msg += L('\nHealth: %s/%s\n','%s/%s'%(jid,nick)) % (data['health'], data['max_health'])
|
||||
msg += L('Bricks: %s\n','%s/%s'%(jid,nick)) % data['bricks_cnt']
|
||||
msg += L('Godpower: %s%%','%s/%s'%(jid,nick)) % data['godpower']
|
||||
elif mode == 'inv':
|
||||
if data['inventory']:
|
||||
msg = L('Inventory: %s','%s/%s'%(jid,nick)) % ', '.join(data['inventory'].keys())
|
||||
else:
|
||||
msg = L('Inventory: %s','%s/%s'%(jid,nick)) % L('Not found!','%s/%s'%(jid,nick))
|
||||
elif mode == 'quest':
|
||||
msg = '%s: %s' % (data['name'], data['quest'])
|
||||
except:
|
||||
msg = L('User not found','%s/%s'%(jid,nick))
|
||||
send_msg(type,jid,nick,msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'poem', poem, 1, 'Just funny poem'),
|
||||
(3, 'oracle', oracle, 2, 'Prophecy oracle. Example: oracle your_answer?'),
|
||||
(3, 'coin', coin, 2, 'Heads or tails'),
|
||||
(3, 'poke', to_poke, 2, '"Poke" command\npoke nick - say a random phrase for nick\nControls command, available only for bot owner:\npoke show - show list of phrases\npoke add phrase - add phrase\npoke del phrase_number - remove phrase.'),
|
||||
(3, 'life', life, 2, 'Info about your life. Example: life dd.mm.yy [hour:min:sec]'),
|
||||
(3, 'zalgo', zalgo, 2, 'Zalgo translate'),
|
||||
(3, 'godville', godville, 2, 'Information about hero from Godville.net.\ngodville [last|stat|extstat|inv|quest] username')]
|
||||
101
plugins/gis.py
Normal file
101
plugins/gis.py
Normal file
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def gweather_raw(type, jid, nick, text, fully):
|
||||
def get_date(body):
|
||||
tmp = get_tag_item(body,'FORECAST','day')+'.'+get_tag_item(body,'FORECAST','month')
|
||||
ytmp = get_tag_item(body,'FORECAST','year')
|
||||
if str(tuple(time.localtime())[0]) == ytmp: return tmp
|
||||
return tmp+'.'+ytmp
|
||||
def get_maxmin(body,tag,splitter):
|
||||
tmax = get_tag_item(body,tag,'max')
|
||||
tmin = get_tag_item(body,tag,'min')
|
||||
if not fully: return str(int((int(tmax)+int(tmin))/2))
|
||||
if tmax == tmin: return tmax
|
||||
if (int(tmin)+int(tmax))/2 == 0: return '0'
|
||||
return tmin + splitter + tmax
|
||||
def get_themp(body): return get_maxmin(body,'TEMPERATURE','..')
|
||||
def get_wind(body): return get_maxmin(body,'WIND','-')
|
||||
def get_pressure(body): return get_maxmin(body,'PRESSURE','-')
|
||||
def get_relwet(body): return get_maxmin(body,'RELWET','-')
|
||||
|
||||
tods = {'0':L('Night','%s/%s'%(jid,nick)),'1':L('Morning','%s/%s'%(jid,nick)),'2':L('Day','%s/%s'%(jid,nick)),'3':L('Evening','%s/%s'%(jid,nick))}
|
||||
precipitation = {'4':L('rain','%s/%s'%(jid,nick)),'5':L('downpour','%s/%s'%(jid,nick)),'6':L('snow','%s/%s'%(jid,nick)),'7':L('snow','%s/%s'%(jid,nick)),
|
||||
'8':L('storm','%s/%s'%(jid,nick)),'9':L('no data','%s/%s'%(jid,nick)),'10':L('no precipitation','%s/%s'%(jid,nick))}
|
||||
cloudiness = {'0':L('clear','%s/%s'%(jid,nick)),'1':L('cloudy','%s/%s'%(jid,nick)),'2':L('Cloudy','%s/%s'%(jid,nick)),'3':L('overcast','%s/%s'%(jid,nick))}
|
||||
winddir = {'0':L('N','%s/%s'%(jid,nick)),'1':L('NE','%s/%s'%(jid,nick)),'2':L('E','%s/%s'%(jid,nick)),'3':L('SE','%s/%s'%(jid,nick)),
|
||||
'4':L('S','%s/%s'%(jid,nick)),'5':L('SW','%s/%s'%(jid,nick)),'6':L('W','%s/%s'%(jid,nick)),'7':L('NW','%s/%s'%(jid,nick))}
|
||||
|
||||
if len(text.strip()):
|
||||
text = text.lower()
|
||||
wzc = cur_execute_fetchall('select * from gis where code ilike %s or lcity ilike %s',(text,text))
|
||||
if not wzc:
|
||||
ttext = '%%%s%%' % text
|
||||
wzc = cur_execute_fetchall('select * from gis where code ilike %s or lcity ilike %s',(ttext,ttext))
|
||||
if not wzc and text.isdigit() and 4 <= len(text) <= 5: wzc = [(text,'','')]
|
||||
if wzc:
|
||||
if len(wzc) == 1:
|
||||
text = wzc[0][0]
|
||||
link = 'http://informer.gismeteo.ru/xml/%s.xml' % text
|
||||
try: body, noerr = html_encode(load_page(link)), True
|
||||
except Exception, SM:
|
||||
try: body = str(SM)
|
||||
except: body = unicode(SM)
|
||||
noerr = None
|
||||
if not body or body == '<?xml version="1.0" encoding="UTF-8"?>\n</xml>': body,noerr = L('Unexpected error','%s/%s'%(jid,nick)), None
|
||||
if noerr:
|
||||
if wzc[0][1]: ct = wzc[0][1]
|
||||
else:
|
||||
try: res = re.findall('<TOWN index=".*?" sname="(.*?)"',body)
|
||||
except: res = ''
|
||||
if res: ct = urllib2.unquote(res[0]).encode('cp1252').decode('cp1251')
|
||||
else: ct = L('Unknown','%s/%s'%(jid,nick))
|
||||
body = body.split('<FORE')[1:]
|
||||
msg = L('Weather in %s:\nDate\t t%s\tWind\tClouds','%s/%s'%(jid,nick)) % (ct,u'°')
|
||||
if fully: msg += L('\tPressure, mm. Hg. Art.\tHumidity %','%s/%s'%(jid,nick))
|
||||
for tmp in body:
|
||||
tmp2 = '<FORE' + tmp
|
||||
msg += '\n' + tods[get_tag_item(tmp2,'FORECAST','tod')] + ' ' + get_date(tmp2) # дата + время суток
|
||||
msg += '\t' + get_themp(tmp2) # температура
|
||||
gwi = get_wind(tmp2) # ветер
|
||||
if gwi == '0': msg += L('\tCalm','%s/%s'%(jid,nick))
|
||||
else: msg += '\t' + gwi+' '+winddir[get_tag_item(tmp2,'WIND','direction')]
|
||||
msg += '\t' + cloudiness[get_tag_item(tmp2,'PHENOMENA','cloudiness')] # облачность
|
||||
msg += ', ' + precipitation[get_tag_item(tmp2,'PHENOMENA','precipitation')] # осадки
|
||||
if fully: msg += '\t' + get_pressure(tmp2) + '\t' + get_relwet(tmp2) # давление, влажность
|
||||
else: msg = L('Error! %s','%s/%s'%(jid,nick)) % body
|
||||
else:
|
||||
msg = L('Found:','%s/%s'%(jid,nick))
|
||||
for tmp in wzc: msg += '\n'+tmp[0]+' - '+tmp[1]
|
||||
else: msg = L('Not found.','%s/%s'%(jid,nick))
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def gweather(type, jid, nick, text): gweather_raw(type, jid, nick, text, None)
|
||||
|
||||
def gweatherplus(type, jid, nick, text): gweather_raw(type, jid, nick, text, True)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'gis', gweather, 2, 'Weather forecast (short). Courtesy Gismeteo.Ru | http://www.gismeteo.ru'),
|
||||
(3, 'gis+', gweatherplus, 2, 'Weather forecast (full). Courtesy Gismeteo.Ru | http://www.gismeteo.ru')]
|
||||
139
plugins/google.py
Normal file
139
plugins/google.py
Normal file
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
google_last_res = {}
|
||||
|
||||
def replace_bold(t,b,e): return t.replace('<b>',b).replace('</b>',e)
|
||||
|
||||
def wiki_search(type, jid, nick, text):
|
||||
if text not in ['next','']: text = L('%s site:en.wikipedia.org','%s/%s'%(jid,nick)) % text
|
||||
google(type, jid, nick, text)
|
||||
|
||||
def xep_show(type, jid, nick,text):
|
||||
ntext = 'xep '+text+' inurl:xmpp.org'
|
||||
url = 'http://ajax.googleapis.com/ajax/services/search/web?'
|
||||
search_results = html_encode(load_page(url, {'v': '1.0', 'q': ntext.encode("utf-8")}))
|
||||
jsonl = json.loads(search_results)
|
||||
try:
|
||||
results = jsonl['responseData']['results']
|
||||
title = results[0]['title']
|
||||
content = results[0]['content']
|
||||
noh_title = replace_bold(title,'','')
|
||||
content = replace_bold(content,'','')
|
||||
msg = '\n'.join((replacer(noh_title),replacer(content),results[0]['unescapedUrl']))
|
||||
except: msg = L('xep \"%s\" not found!','%s/%s'%(jid,nick)) % text
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def google(type, jid, nick, text):
|
||||
global google_last_res
|
||||
results = ''
|
||||
text = text.strip()
|
||||
if text in ['next','']:
|
||||
if google_last_res.has_key(jid) and google_last_res[jid].has_key(nick) and google_last_res[jid][nick]:
|
||||
first = google_last_res[jid][nick][0]
|
||||
google_last_res[jid][nick] = google_last_res[jid][nick][1:]
|
||||
else: results = L('No results!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
try:
|
||||
url = 'http://ajax.googleapis.com/ajax/services/search/web?'
|
||||
search_results = html_encode(load_page(url, {'v': '1.0', 'q': text.encode("utf-8")}))
|
||||
jsonl = json.loads(search_results)
|
||||
data = jsonl['responseData']['results']
|
||||
first = data[0]
|
||||
if google_last_res.has_key(jid): google_last_res[jid].update({nick: data[1:]})
|
||||
else: google_last_res[jid] = {nick: data[1:]}
|
||||
except: results = L('Expression \"%s\" not found!','%s/%s'%(jid,nick)) % text
|
||||
if not results:
|
||||
title = first['title']
|
||||
content = first['content']
|
||||
noh_title = replace_bold(title,u'«',u'»')
|
||||
content = replace_bold(content,u'«',u'»')
|
||||
url = urllib.unquote(first['unescapedUrl'].encode('utf8')).decode('utf8','ignore')
|
||||
results = replacer(noh_title)+'\n'+replacer(content)+'\n'+url
|
||||
send_msg(type, jid, nick, results)
|
||||
|
||||
def google_clear(room,jid,nick,type,arr):
|
||||
if type == 'unavailable' and google_last_res.has_key(room) and google_last_res[room].has_key(nick): del google_last_res[room][nick]
|
||||
|
||||
def translate(type, jid, nick, text):
|
||||
text = text.strip()
|
||||
trlang = {'sq':L('Albanian','%s/%s'%(jid,nick)),'en':L('English','%s/%s'%(jid,nick)),'ar':L('Arabic','%s/%s'%(jid,nick)),'af':L('Afrikaans','%s/%s'%(jid,nick)),
|
||||
'be':L('Belarusian','%s/%s'%(jid,nick)),'bg':L('Bulgarian','%s/%s'%(jid,nick)),'cy':L('Welsh','%s/%s'%(jid,nick)),
|
||||
'hu':L('Hungarian','%s/%s'%(jid,nick)),'vi':L('Vietnamese','%s/%s'%(jid,nick)),'gl':L('Galician','%s/%s'%(jid,nick)),
|
||||
'nl':L('Dutch','%s/%s'%(jid,nick)),'el':L('Greek','%s/%s'%(jid,nick)),'da':L('Danish','%s/%s'%(jid,nick)),'iw':L('Hebrew','%s/%s'%(jid,nick)),
|
||||
'yi':L('Yiddish','%s/%s'%(jid,nick)),'id':L('Indonesian','%s/%s'%(jid,nick)),'ga':L('Irish','%s/%s'%(jid,nick)),'is':L('Icelandic','%s/%s'%(jid,nick)),
|
||||
'es':L('Spanish','%s/%s'%(jid,nick)),'it':L('Italian','%s/%s'%(jid,nick)),'ca':L('Catalan','%s/%s'%(jid,nick)),'zh':L('Chinese','%s/%s'%(jid,nick)),
|
||||
'ko':L('Korean','%s/%s'%(jid,nick)),'lv':L('Latvian','%s/%s'%(jid,nick)),'lt':L('Lithuanian','%s/%s'%(jid,nick)),
|
||||
'mk':L('Macedonian','%s/%s'%(jid,nick)),'ms':L('Malay','%s/%s'%(jid,nick)),'mt':L('Maltese','%s/%s'%(jid,nick)),'de':L('German','%s/%s'%(jid,nick)),
|
||||
'no':L('Norwegian','%s/%s'%(jid,nick)),'fa':L('Persian','%s/%s'%(jid,nick)),'pl':L('Polish','%s/%s'%(jid,nick)),'pt':L('Portuguese','%s/%s'%(jid,nick)),
|
||||
'ro':L('Romanian','%s/%s'%(jid,nick)),'ru':L('Russian','%s/%s'%(jid,nick)),'sr':L('Serbian','%s/%s'%(jid,nick)),'sk':L('Slovak','%s/%s'%(jid,nick)),
|
||||
'sl':L('Slovenian','%s/%s'%(jid,nick)),'sw':L('Swahili','%s/%s'%(jid,nick)),'tl':L('Tagalog','%s/%s'%(jid,nick)),'th':L('Thai','%s/%s'%(jid,nick)),
|
||||
'tr':L('Turkish','%s/%s'%(jid,nick)),'uk':L('Ukrainian','%s/%s'%(jid,nick)),'fi':L('Finnish','%s/%s'%(jid,nick)),'fr':L('French','%s/%s'%(jid,nick)),
|
||||
'hi':L('Hindi','%s/%s'%(jid,nick)),'hr':L('Croatian','%s/%s'%(jid,nick)),'cs':L('Czech','%s/%s'%(jid,nick)),'sv':L('Swedish','%s/%s'%(jid,nick)),
|
||||
'et':L('Estonian','%s/%s'%(jid,nick)),'ja':L('Japanese','%s/%s'%(jid,nick)),'ht':L('Creole','%s/%s'%(jid,nick))}
|
||||
if text.lower() == 'list': msg = L('Available languages for translate:','%s/%s'%(jid,nick)) + ' ' + ', '.join(sorted(trlang.keys()))
|
||||
elif text[:5].lower() == 'info ':
|
||||
text = text.lower().split(' ')
|
||||
msg = ''
|
||||
for tmp in text:
|
||||
if tmp in trlang: msg += '%s - %s, ' % (tmp,trlang[tmp])
|
||||
if len(msg): msg = L('Available languages: %s','%s/%s'%(jid,nick)) % msg[:-2]
|
||||
else: msg = L('I don\'t know this language','%s/%s'%(jid,nick))
|
||||
elif text[:5].lower() == 'lang ' and text.count(' ')==1:
|
||||
text = text.lower().split(' ')[1]
|
||||
msg = ', '.join(['%s - %s' % (k,trlang[k]) for k in trlang.keys() if text in trlang[k].lower()])
|
||||
if len(msg): msg = L('Available languages: %s','%s/%s'%(jid,nick)) % msg
|
||||
else: msg = L('I don\'t know this language','%s/%s'%(jid,nick))
|
||||
else:
|
||||
if ' ' in text:
|
||||
text = text.split(' ',2)
|
||||
url = 'http://translate.google.ru/translate_a/t?'
|
||||
if len(text)>1 and trlang.has_key(text[0].lower()):
|
||||
if len(text)>2 and trlang.has_key(text[1].lower()): lfrom,lto,tr_text = text[0].lower(),text[1].lower(),text[2]
|
||||
else: lfrom,lto,tr_text = '',text[0].lower(),' '.join(text[1:])
|
||||
search_results = load_page(url, {'client':'x',\
|
||||
'text':tr_text.encode("utf-8"),\
|
||||
'hl':lfrom,\
|
||||
'sl':lfrom,\
|
||||
'tl':lto})
|
||||
try: jsonl = json.loads(search_results)['sentences']
|
||||
except ValueError: jsonl = None
|
||||
try: src = trlang[json.loads(search_results)['src']].capitalize()
|
||||
except: src = None
|
||||
if jsonl:
|
||||
msg = rss_replace(''.join(f['trans'] for f in jsonl))
|
||||
if src and not lfrom: msg = L('%s [Source: %s]','%s/%s'%(jid,nick)) % (msg,src.strip())
|
||||
else: msg = L('I can\'t translate it!','%s/%s'%(jid,nick))
|
||||
else: msg = L('Incorrect language settings for translate. tr list - available languages.','%s/%s'%(jid,nick))
|
||||
else: msg = L('Command\'s format: tr [from] to text','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute, presence_control
|
||||
|
||||
presence_control = [google_clear]
|
||||
|
||||
execute = [(3, 'tr', translate, 2, 'Translator.\ntr [from_language] to_language text - translate text\ntr list - list for available languages for translate\ntr info <reduction> - get info about language reduction\ntr lang <expression> - get languages by expression'),
|
||||
(3, 'google', google, 2, 'Search in google'),
|
||||
(3, 'xep', xep_show, 2, 'Search XEP'),
|
||||
(3, 'wiki', wiki_search, 2, 'Search in en.wikipedia.org')]
|
||||
|
||||
123
plugins/googleplus.py
Normal file
123
plugins/googleplus.py
Normal file
@@ -0,0 +1,123 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) Vit@liy <vitaliy@root.ua> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
# translate: verb,noun,preposition,adverb,adjective,phrase,conjunction,abbreviation,Google URL Shortener/Unshortener,Google QR-code generator
|
||||
|
||||
def gcalc(type, jid, nick, text):
|
||||
if not text.strip(): msg = L('What?','%s/%s'%(jid,nick))
|
||||
else:
|
||||
try:
|
||||
data = load_page('http://www.google.ru/search?', {'q': '%s=' % text.replace('=','').strip().encode('utf-8'), 'hl': GT('youtube_default_lang')}).decode('utf-8', 'ignore')
|
||||
msg = ' '.join([t.strip() for t in re.findall('<span class="cwclet" id="cwles">(.*?)</span> </div> </div>.*?<span class="cwcot" id="cwos">(.*?)</span> <script>',data)[0]])
|
||||
msg = msg.replace('<sup>2</sup>',u'²').replace('<sup>3</sup>',u'³')
|
||||
except:
|
||||
try: msg = reduce_spaces_all(' '.join(re.findall('<div class="vk_gy vk_sh">(.*?)</div><div class="vk_ans vk_bk">(.*?)</div>',data,re.S)[0])).strip()
|
||||
except: msg = L('Google Calculator results not found','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def define(type, jid, nick, text):
|
||||
text = text.strip()
|
||||
target, define_silent = '', False
|
||||
if not text: msg = L('What?','%s/%s'%(jid,nick))
|
||||
else:
|
||||
if re.search('\A\d+?(-\d+?)? ', text): target, text = text.split(' ', 1)
|
||||
data = load_page('http://www.google.com.ua/search?', {'hl': 'ru', 'q': text.encode('utf-8'), 'tbs': 'dfn:1'}).decode('utf-8')
|
||||
result = re.findall('<li style="list-style:none">(.+?)</li></ul><div style="color:#551a8b"><cite><span class=bc><a href="/url\?url=(.+?)&', data)
|
||||
if target:
|
||||
try: n1 = n2 = int(target)
|
||||
except: n1, n2 = map(int, target.split('-'))
|
||||
if n1 + n2 == 0: define_silent, n1, n2 = True, 1, 1
|
||||
if not result: msg = [L('I don\'t know!','%s/%s'%(jid,nick)), ''][define_silent]
|
||||
else:
|
||||
if target and target != '0':
|
||||
msg = ''
|
||||
if 0 < n1 <= n2 <= len(result):
|
||||
for k in xrange(n1 - 1, n2): msg += '%s\n%s\n\n' % (result[k][0], urllib.unquote(result[k][1].replace('%25', '%').encode('utf8')).decode('utf8'))
|
||||
else: msg = [L('I don\'t know!','%s/%s'%(jid,nick)), ''][define_silent]
|
||||
else:
|
||||
result = random.choice(result)
|
||||
msg = result[0] + '\n' + urllib.unquote(result[1].replace('%25', '%').encode('utf8')).decode('utf8')
|
||||
if '<' in msg and '>' in msg: msg = unhtml_hard(msg)
|
||||
if msg: send_msg(type, jid, nick, msg)
|
||||
|
||||
def define_message(room, jid, nick, type, text):
|
||||
s = get_config(room, 'parse_define')
|
||||
if s != 'off':
|
||||
if cur_execute_fetchone('select * from commonoff where room=%s and cmd=%s',(room,'define')): return
|
||||
troom = cur_execute_fetchone('select room from conference where room ilike %s',('%s/%%'%room,))
|
||||
if troom:
|
||||
nowname = getResourse(troom[0])
|
||||
text = re.sub('^%s[,:]\ ' % re.escape(nowname), '', text.strip())
|
||||
what = re.search([u'^(?:(?:что такое)|(?:кто такой)|(?:кто такая)) ([^?]+?)\?$', u'(?:(?:что такое)|(?:кто такой)) ([^?]+?)\?'][s == 'partial'], text, re.I + re.U + re.S)
|
||||
if what:
|
||||
access_mode = get_level(room, nick)[0]
|
||||
text = 'define 0 %s' % what.group(1)
|
||||
com_parser(access_mode, nowname, type, room, nick, text, jid)
|
||||
return True
|
||||
|
||||
def gdict(type, jid, nick, text):
|
||||
text = reduce_spaces_all(text.encode('utf-8')).split(' ')
|
||||
if 2 <= len(text) <= 3:
|
||||
try: sl, tl, text = text
|
||||
except: sl, tl, text = [''] + text
|
||||
data = html_encode(load_page('http://translate.google.ru/translate_a/t?', {'client': 'x', 'text': text, 'hl': 'en', 'sl': sl, 'tl': tl}))
|
||||
try:
|
||||
data = json.loads(data)
|
||||
if 'dict' in data: msg = '\n%s' % '\n'.join(['%s: %s' % (L(i['pos']).upper(), ', '.join(i['terms'])) for i in data['dict'] if i['pos']])
|
||||
else: msg = L('I can\'t translate it!','%s/%s'%(jid,nick))
|
||||
except: msg = L('Command execution error.','%s/%s'%(jid,nick))
|
||||
else: msg = L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def goo_gl_raw(text, is_qr):
|
||||
url = text.strip().encode('utf-8')
|
||||
if not re.findall('^http(s?)://',url[:10]) and not is_qr: url = 'http://' + url
|
||||
if is_qr: regex = 'http://goo\.gl/[a-zA-Z0-9]+?\.qr\Z'
|
||||
else: regex = 'http://goo\.gl/[a-zA-Z0-9]+?\Z'
|
||||
if not url: msg = L('What?','%s/%s'%(jid,nick))
|
||||
elif re.match(regex, url):
|
||||
if is_qr: url = url[:-3]
|
||||
f = get_opener(url)[0]
|
||||
if L('Error! %s','%s/%s'%(jid,nick)) % '' in f: msg = f
|
||||
else: msg = urllib.unquote(f.geturl().encode('utf8')).decode('utf8')
|
||||
else:
|
||||
data = load_page(urllib2.Request('http://goo.gl/api/url', 'url=%s' % urllib.quote(url)))
|
||||
if L('Error! %s','%s/%s'%(jid,nick)) % '' in data: msg = data
|
||||
else:
|
||||
msg = json.loads(data)['short_url']
|
||||
if is_qr: msg += '.qr'
|
||||
return msg
|
||||
|
||||
def goo_gl_qr(type, jid, nick, text): send_msg(type, jid, nick, goo_gl_raw(text, True))
|
||||
|
||||
def goo_gl(type, jid, nick, text): send_msg(type, jid, nick, goo_gl_raw(text, False))
|
||||
|
||||
global execute, message_control
|
||||
|
||||
message_act_control = [define_message]
|
||||
|
||||
execute = [(3, 'gcalc', gcalc, 2, 'Google Calculator'),
|
||||
(3, 'define', define, 2, 'Definition for a word or phrase.\ndefine word - random define of word or phrase\ndefine N word - N-th define of word or phrase\ndefine a-b word - from a to b defines of word or phrase'),
|
||||
#(3, 'ggl', goo_gl, 2, 'Google URL Shortener/Unshortener'),
|
||||
#(3, 'qr', goo_gl_qr, 2, 'Google QR-code generator'),
|
||||
(3, 'gdict', gdict, 2, 'Google Dictionary\ngdict [from_language] to_language word')]
|
||||
31
plugins/here.py
Normal file
31
plugins/here.py
Normal file
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def muc_here(type, jid, nick):
|
||||
users = non_case_sort([t[1] for t in megabase if t[0]==jid])
|
||||
msg = L('I see %s participant(s): %s','%s/%s'%(jid,nick)) % (len(users), ', '.join(users))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'here', muc_here, 1, 'Current participants list')]
|
||||
50
plugins/hideroom.py
Normal file
50
plugins/hideroom.py
Normal file
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def hide_room(type, jid, nick, text):
|
||||
if type == 'groupchat': msg = L('This command available only in private!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
hmode = text.split(' ')[0]
|
||||
try: hroom = text.split(' ')[1]
|
||||
except: hroom = jid
|
||||
if hmode == 'show':
|
||||
hr = cur_execute_fetchall('select * from hiden_rooms;')
|
||||
if len(hr): msg = '%s\n%s' % (L('Hidden conferences:','%s/%s'%(jid,nick)),'\n'.join([t[0] for t in hr]))
|
||||
else: msg = L('No hidden conferences.','%s/%s'%(jid,nick))
|
||||
elif hmode == 'add':
|
||||
if not cur_execute_fetchone('select * from conference where room ilike %s;', ('%s/%%'%getRoom(hroom),)): msg = L('I am not in the %s','%s/%s'%(jid,nick)) % hroom
|
||||
elif cur_execute_fetchone('select * from hiden_rooms where room=%s',(hroom,)): msg = L('I\'m already hide a %s','%s/%s'%(jid,nick)) % hroom
|
||||
else:
|
||||
cur_execute('insert into hiden_rooms values (%s)',(hroom,))
|
||||
msg = L('%s has been hidden','%s/%s'%(jid,nick)) % hroom
|
||||
elif hmode == 'del':
|
||||
if hroom in hr:
|
||||
cur_execute('delete from hiden_rooms where room=%s',(hroom,))
|
||||
msg = L('%s will be shown','%s/%s'%(jid,nick)) % hroom
|
||||
else: msg = L('I\'m not hide room %s','%s/%s'%(jid,nick)) % hroom
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(9, 'hide', hide_room, 2, 'Hide conference.\nhide [add|del|show] [room@conference.server.tld]')]
|
||||
51
plugins/horo.py
Normal file
51
plugins/horo.py
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) ferym <ferym@jabbim.org.ru> #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
# translate: aries,taurus,gemini,cancer,leo,virgo,libra,scorpio,sagittarius,capricorn,aquarius,pisces
|
||||
horodb=['aries','taurus','gemini','cancer','leo','virgo','libra','scorpio','sagittarius','capricorn','aquarius','pisces']
|
||||
|
||||
def handler_horoscope(type, jid, nick, text):
|
||||
param = text.strip().lower()
|
||||
msg = L('What?','%s/%s'%(jid,nick))
|
||||
if param:
|
||||
if param == 'list': msg = ', '.join(['%s (%s)' % (L(t).capitalize(),t.capitalize()) for t in horodb])
|
||||
if param == 'date':
|
||||
horo_dates = ['21.03-19.04','20.04-20.05','21.05-20.06','21.06-22.07','23.07-22.08','23.08-22.09','23.09-22.10','23.10-21.11','22.11-21.12','22.12-19.01','20.01-18.02','19.02-20.03']
|
||||
msg = L('List of dates:\n%s','%s/%s'%(jid,nick)) % '\n'.join([u'%s … %s' % (horo_dates[i],L(t).capitalize()) for i,t in enumerate(horodb)])
|
||||
if type=='groupchat':
|
||||
send_msg('chat', jid, nick, msg)
|
||||
msg = L('Send for you in private','%s/%s'%(jid,nick))
|
||||
if param in [L(t) for t in horodb] or param in horodb:
|
||||
if param not in horodb: param = dict([[L(t),t] for t in horodb])[param]
|
||||
body = html_encode(load_page('http://horo.mail.ru/prediction/%s/today' % param))
|
||||
try: msg = unhtml_hard(re.findall('<div id="tm_today">(.+?)<div class="mb2">',body,re.S|re.I|re.U)[0].strip())
|
||||
except: msg = L('Unknown error!','%s/%s'%(jid,nick))
|
||||
if type=='groupchat':
|
||||
send_msg('chat', jid, nick, msg)
|
||||
msg = L('Send for you in private','%s/%s'%(jid,nick))
|
||||
send_msg(type,jid,nick,msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'horo', handler_horoscope, 2, 'Horoscope.\nhoro list - show all zodiacs.\nhoro date - show dates for zodiacs. | Author: ferym')]
|
||||
60
plugins/idle.py
Normal file
60
plugins/idle.py
Normal file
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
idle_base = []
|
||||
|
||||
def idle(type, jid, nick, text):
|
||||
global idle_base
|
||||
if not len(text): text = nick
|
||||
msg = L('I can\'t find %s','%s/%s'%(jid,nick)) % text
|
||||
for tmp in idle_base:
|
||||
if tmp[0] == jid and tmp[1] == text:
|
||||
if text == nick: msg = L('Your last activity was %s ago','%s/%s'%(jid,nick)) % un_unix(int(time.time())-tmp[3],'%s/%s'%(jid,nick))
|
||||
else: msg = L('%s\'s last ativity was %s ago','%s/%s'%(jid,nick)) % (text, un_unix(int(time.time())-tmp[3],'%s/%s'%(jid,nick)))
|
||||
if tmp[2] == 'm': msg += ' ('+L('message','%s/%s'%(jid,nick))+')'
|
||||
else: msg += ' ('+L('presence','%s/%s'%(jid,nick))+')'
|
||||
break
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def append_to_idle(room,jid,nick,type,text):
|
||||
global idle_base
|
||||
for tmp in idle_base:
|
||||
if tmp[0] == room and tmp[1] == nick:
|
||||
idle_base.remove(tmp)
|
||||
break
|
||||
idle_base.append((room,nick,'m',int(time.time())))
|
||||
|
||||
def remove_from_idle(room,jid,nick,type,text):
|
||||
global idle_base
|
||||
for tmp in idle_base:
|
||||
if tmp[0] == room and tmp[1] == nick:
|
||||
idle_base.remove(tmp)
|
||||
break
|
||||
if type != 'unavailable': idle_base.append((room,nick,'p',int(time.time())))
|
||||
|
||||
global execute
|
||||
|
||||
message_control = [append_to_idle]
|
||||
presence_control = [remove_from_idle]
|
||||
|
||||
execute = [(0, 'idle', idle, 2, 'Idle time')]
|
||||
112
plugins/inlist.py
Normal file
112
plugins/inlist.py
Normal file
@@ -0,0 +1,112 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def reban(type, jid, nick, text):
|
||||
try: lim = int(text)
|
||||
except:
|
||||
send_msg(type, jid, nick, L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick)))
|
||||
return
|
||||
global banbase,iq_request
|
||||
iqid = get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':getRoom(jid)}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'affiliation':'outcast'})])])
|
||||
iq_request[iqid]=(time.time(),reban_async,[type, jid, nick, lim],xmpp.NS_MUC_ADMIN)
|
||||
sender(i)
|
||||
|
||||
def reban_async(type, jid, nick, lim, iq_stanza):
|
||||
isa = iq_stanza[1]
|
||||
if len(isa) >= 2 and isa[1] == 'error': msg = L('Error! %s','%s/%s'%(jid,nick)) % L(isa[0].capitalize().replace('-',' '),'%s/%s'%(jid,nick))
|
||||
else:
|
||||
_trusted = get_config(getRoom(jid),'trusted_servers').split()
|
||||
_jids = [tmp.getAttr('jid') for tmp in iq_stanza[1][0].getTag('query',namespace=xmpp.NS_MUC_ADMIN).getTags('item')]
|
||||
_srv_count = {}
|
||||
for t in _jids:
|
||||
if '@' in t:
|
||||
_t = t.split('@',1)[1]
|
||||
if _t not in _trusted: _srv_count[_t] = _srv_count[_t] + 1 if _srv_count.has_key(_t) else 1
|
||||
_servers = [t for t in _jids if '@' not in t]
|
||||
_new_servers = [t for t in _srv_count.keys() if _srv_count[t] >= lim and t not in _servers]
|
||||
_need_remove = [t for t in _jids if '@' in t and t.split('@',1)[1] in _servers + _new_servers]
|
||||
_new_servers.sort()
|
||||
|
||||
_limit = get_config_int(getRoom(jid),'make_stanza_jid_count')
|
||||
nodes = []
|
||||
for t in _new_servers:
|
||||
reason = [xmpp.Node('reason',{},'Rebanned as dangerous! Found jids: %s' % _srv_count[t])]
|
||||
nodes.append(xmpp.Node('item',{'affiliation':'outcast', 'jid':t},reason))
|
||||
if len(nodes) >= _limit:
|
||||
sender(xmpp.Node('iq', {'id': get_id(), 'type': 'set', 'to':jid}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},nodes)]))
|
||||
nodes = []
|
||||
if nodes: sender(xmpp.Node('iq', {'id': get_id(), 'type': 'set', 'to':jid}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},nodes)]))
|
||||
nodes = []
|
||||
for t in _need_remove:
|
||||
nodes.append(xmpp.Node('item',{'affiliation':'none', 'jid':t},[]))
|
||||
if len(nodes) >= _limit:
|
||||
sender(xmpp.Node('iq', {'id': get_id(), 'type': 'set', 'to':jid}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},nodes)]))
|
||||
nodes = []
|
||||
if nodes: sender(xmpp.Node('iq', {'id': get_id(), 'type': 'set', 'to':jid}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},nodes)]))
|
||||
msg = L('Unbaned jids: %s\nBanned servers: %s .. %s','%s/%s'%(jid,nick)) % (len(_need_remove), len(_new_servers), ', '.join(_new_servers))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def inban(type, jid, nick, text): inlist_raw(type, jid, nick, text, 'outcast', L('Total banned: %s','%s/%s'%(jid,nick)))
|
||||
def inowner(type, jid, nick, text): inlist_raw(type, jid, nick, text, 'owner', L('Total owners: %s','%s/%s'%(jid,nick)))
|
||||
def inadmin(type, jid, nick, text): inlist_raw(type, jid, nick, text, 'admin', L('Total admins: %s','%s/%s'%(jid,nick)))
|
||||
def inmember(type, jid, nick, text): inlist_raw(type, jid, nick, text, 'member', L('Total members: %s','%s/%s'%(jid,nick)))
|
||||
|
||||
def inlist_raw(type, jid, nick, text, affil, message):
|
||||
global banbase,iq_request
|
||||
iqid = get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':getRoom(jid)}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'affiliation':affil})])])
|
||||
iq_request[iqid]=(time.time(),inlist_raw_async,[type, jid, nick, text, message],xmpp.NS_MUC_ADMIN)
|
||||
sender(i)
|
||||
|
||||
def inlist_raw_async(type, jid, nick, text, message, iq_stanza):
|
||||
isa = iq_stanza[1]
|
||||
if len(isa) >= 2 and isa[1] == 'error': msg = L('Error! %s','%s/%s'%(jid,nick)) % L(isa[0].capitalize().replace('-',' '),'%s/%s'%(jid,nick))
|
||||
else:
|
||||
bb = [[tmp.getAttr('jid'),['',tmp.getTagData('reason')][tmp.getTagData('reason') != None]] for tmp in iq_stanza[1][0].getTag('query',namespace=xmpp.NS_MUC_ADMIN).getTags('item')]
|
||||
bb.sort()
|
||||
msg = message % len(bb)
|
||||
if text != '':
|
||||
text = text.strip().split()
|
||||
if len(text) == 1: text,nt = text[0], 0
|
||||
elif text[0] == '!': text,nt = ' '.join(text[1:]), 1
|
||||
elif text[0] == '=': text,nt = ' '.join(text[1:]), 2
|
||||
else: text,nt = ' '.join(text[1:]), False
|
||||
msg += ', '
|
||||
mmsg, cnt = '', 1
|
||||
for i in bb:
|
||||
if [text.lower() in i[0].lower() or text.lower() in i[1].lower(), text.lower() not in i[0].lower(),text.lower() == i[0].lower() or text.lower() == i[1].lower()][nt]:
|
||||
mmsg += '\n%s. %s' % (cnt,i[0])
|
||||
if len(i[1]): mmsg += ' - %s' % i[1]
|
||||
cnt += 1
|
||||
if len(mmsg): msg += L('Found:','%s/%s'%(jid,nick)) + ' %s%s' % (mmsg.count('\n'),mmsg)
|
||||
else: msg += L('no matches!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(7, 'inban', inban, 2, 'Search in outcast list of conference.'),
|
||||
(7, 'inmember', inmember, 2, 'Search in members list of conference.'),
|
||||
(7, 'inadmin', inadmin, 2, 'Search in admins list of conference.'),
|
||||
(7, 'inowner', inowner, 2, 'Search in owners list of conference.'),
|
||||
(8, 'reban', reban, 2, 'Cleen up outcast list. Replace different jids from same server by one server jid\nreban <count>')]
|
||||
61
plugins/invite.py
Normal file
61
plugins/invite.py
Normal file
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def call_body(type, jid, nick, text):
|
||||
skip = 1
|
||||
if len(text):
|
||||
try:
|
||||
reason = text.split('\n')[1]
|
||||
text = text.split('\n')[0]
|
||||
except: reason = None
|
||||
fnd = cur_execute_fetchall('select jid from age where room=%s and (nick=%s or jid=%s) group by jid',(jid,text,text))
|
||||
if len(fnd) == 1:
|
||||
whojid = getRoom(unicode(fnd[0][0]))
|
||||
is_found = 0
|
||||
for tmp in megabase:
|
||||
if tmp[0] == jid and getRoom(tmp[4]) == whojid:
|
||||
is_found = 1
|
||||
break
|
||||
if is_found: msg = L('%s ishere!','%s/%s'%(jid,nick)) % text
|
||||
else:
|
||||
msg = L('Invited','%s/%s'%(jid,nick))
|
||||
skip = 0
|
||||
elif len(fnd) > 1: msg = L('I seen some peoples with this nick. Get more info!','%s/%s'%(jid,nick))
|
||||
else: msg = L('I don\'n know %s','%s/%s'%(jid,nick)) % text
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
|
||||
if skip: send_msg(type, jid, nick, msg)
|
||||
else:
|
||||
inv_msg = L('%s invite you to %s','%s/%s'%(jid,nick)) % (nick, jid)
|
||||
if reason: inv_msg += ' ' + L('because: %s','%s/%s'%(jid,nick)) % reason
|
||||
send_msg('chat',whojid, '',inv_msg)
|
||||
|
||||
inv = xmpp.Message(jid)
|
||||
inv.setTag('x', namespace=xmpp.NS_MUC_USER).addChild('invite', {'to':whojid})
|
||||
sender(inv)
|
||||
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(4, 'invite', call_body, 2, 'Invite to conference.\ninvite nick|jid\n[reason]')]
|
||||
332
plugins/iq.py
Normal file
332
plugins/iq.py
Normal file
@@ -0,0 +1,332 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
# translate: FN,NICKNAME,N.FAMILY,N.GIVEN,N.MIDDLE,ADR.LOCALITY,ADR.REGION,ADR.PCODE,ADR.CTRY,ADR.STREET,TEL.NUMBER,EMAIL.USERID,EMAIL,JABBERID,ROLE,BDAY,URL,DESC,ROLE,ORG.ORGNAME,ORG.ORGUNIT,GEO.LAT,GEO.LON,TITLE,PHOTO,uptime,seconds,users/registered,users,users/online,contacts/online,contacts,contacts/total,messages/in,messages,messages/out,memory-usage,KB,users/all-hosts/total,users/all-hosts/online,users/total
|
||||
|
||||
VCARD_LIMIT_LONG = 256
|
||||
VCARD_LIMIT_SHORT = 128
|
||||
iq_ping_minimal = GT('timeout')
|
||||
|
||||
def iq_iq_get(iq,id,room,acclvl,query,towh,al):
|
||||
if iq.getTag(name='query', namespace=xmpp.NS_VERSION) and GT('iq_version_enable'):
|
||||
pprint('*** iq:version from %s' % unicode(room),'magenta')
|
||||
i=xmpp.Iq(to=room, typ='result')
|
||||
i.setAttr(key='id', val=id)
|
||||
i.setQueryNS(namespace=xmpp.NS_VERSION)
|
||||
i.getTag('query').setTagData(tag='name', val=botName)
|
||||
i.getTag('query').setTagData(tag='version', val=botVersion)
|
||||
i.getTag('query').setTagData(tag='os', val=botOs)
|
||||
return i
|
||||
|
||||
elif iq.getTag(name='query', namespace=xmpp.NS_TIME) and GT('iq_time_enable'):
|
||||
pprint('*** iq:time from %s' % unicode(room),'magenta')
|
||||
t_utc,t_tz,t_display = nice_time(time.time(),room)
|
||||
i=xmpp.Iq(to=room, typ='result')
|
||||
i.setAttr(key='id', val=id)
|
||||
i.setQueryNS(namespace=xmpp.NS_TIME)
|
||||
i.getTag('query').setTagData(tag='utc', val=t_utc)
|
||||
i.getTag('query').setTagData(tag='tz', val=t_tz)
|
||||
i.getTag('query').setTagData(tag='display', val=t_display)
|
||||
return i
|
||||
|
||||
elif iq.getTag(name='time', namespace=xmpp.NS_URN_TIME) and GT('iq_time_enable'):
|
||||
pprint('*** iq:urn:time from %s' % unicode(room),'magenta')
|
||||
if timeofset in [-12,-11,-10]: t_tz = '-%s:00' % timeofset
|
||||
elif timeofset in range(-9,-1): t_tz = '-0%s:00' % timeofset
|
||||
elif timeofset in range(0,9): t_tz = '+0%s:00' % timeofset
|
||||
else: t_tz = '+%s:00' % timeofset
|
||||
i=xmpp.Iq(to=room, typ='result')
|
||||
i.setAttr(key='id', val=id)
|
||||
i.setTag('time',namespace=xmpp.NS_URN_TIME)
|
||||
i.getTag('time').setTagData(tag='tzo', val=t_tz)
|
||||
i.getTag('time').setTagData(tag='utc', val=str(time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())))
|
||||
return i
|
||||
|
||||
elif iq.getTag(name='ping', namespace=xmpp.NS_URN_PING) and GT('iq_ping_enable'):
|
||||
pprint('*** iq:urn:ping from %s' % unicode(room),'magenta')
|
||||
i=xmpp.Iq(to=room, typ='result')
|
||||
i.setAttr(key='id', val=id)
|
||||
return i
|
||||
|
||||
elif iq.getTag(name='query', namespace=xmpp.NS_LAST) and GT('iq_uptime_enable'):
|
||||
pprint('*** iq:uptime from %s' % unicode(room),'magenta')
|
||||
i=xmpp.Iq(to=room, typ='result')
|
||||
i.setAttr(key='id', val=id)
|
||||
i.setTag('query',namespace=xmpp.NS_LAST,attrs={'seconds':str(int(time.time())-starttime)})
|
||||
i.setTagData('query','%s (%s) [%s]' % (Settings['message'],Settings['status'],Settings['priority']))
|
||||
return i
|
||||
return None
|
||||
|
||||
def get_who_iq(text,jid,nick):
|
||||
if text == '': who = '%s/%s' % (getRoom(jid),nick)
|
||||
else:
|
||||
who = text
|
||||
for mega1 in megabase:
|
||||
if mega1[0] == jid and mega1[1] == text:
|
||||
who = '%s/%s' % (getRoom(jid),text)
|
||||
break
|
||||
return who
|
||||
|
||||
def get_caps(room,nick):
|
||||
try:
|
||||
(id_node,id_ver,id_bmver) = capses['%s/%s' % (room,nick)].split('\n')
|
||||
if id_bmver: msg = '%s %s (%s)' % (id_node,id_ver,id_bmver)
|
||||
else: msg = '%s %s' % (id_node,id_ver)
|
||||
except: msg = None
|
||||
return msg
|
||||
|
||||
def noiq_caps(type, jid, nick, text):
|
||||
text = [text,nick][text == '']
|
||||
msg = get_caps(jid,text)
|
||||
if not msg: msg = L('I can\'t get caps of %s','%s/%s'%(jid,nick)) % text
|
||||
elif len(msg) == msg.count(' ')+msg.count('\n'): msg = L('%s has empty caps!','%s/%s'%(jid,nick)) % text
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def iq_vcard(type, jid, nick, text):
|
||||
global iq_request
|
||||
if '\n' in text: text,args = text.split('\n',1)
|
||||
else: args = ''
|
||||
who,iqid = get_who_iq(text,jid,nick),get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':who}, payload = [xmpp.Node('vCard', {'xmlns': xmpp.NS_VCARD},[])])
|
||||
iq_request[iqid]=(time.time(),vcard_async,[type, jid, nick, text, args],xmpp.NS_VCARD)
|
||||
sender(i)
|
||||
|
||||
def vcard_async(type, jid, nick, text, args, is_answ):
|
||||
isa = is_answ[1]
|
||||
if len(isa) >= 2 and isa[1] == 'error': msg = L('Error! %s','%s/%s'%(jid,nick)) % L(isa[0].capitalize().replace('-',' '),'%s/%s'%(jid,nick))
|
||||
else:
|
||||
try: vc,err = isa[1].getTag('vCard',namespace=xmpp.NS_VCARD),False
|
||||
except: vc,err = L('Error! %s','%s/%s'%(jid,nick)) % L(isa[0].capitalize().replace('-',' '),'%s/%s'%(jid,nick)),True
|
||||
if not vc or unicode(vc) == '<vCard xmlns="vcard-temp" />': msg = '%s %s' % (L('vCard:','%s/%s'%(jid,nick)),L('Empty!','%s/%s'%(jid,nick)))
|
||||
elif err: msg = '%s %s' % (L('vCard:','%s/%s'%(jid,nick)),vc[:VCARD_LIMIT_LONG])
|
||||
else:
|
||||
data = []
|
||||
for t in vc.getChildren():
|
||||
if t.getChildren():
|
||||
cm = []
|
||||
for r in t.getChildren():
|
||||
if r.getData(): cm.append(('%s.%s' % (t.getName(),r.getName()),unicode(r.getData())))
|
||||
data += cm
|
||||
elif t.getData(): data.append((t.getName(),t.getData()))
|
||||
if data:
|
||||
try:
|
||||
photo_size = sys.getsizeof(get_value_from_array2(data,'PHOTO.BINVAL').decode('base64'))
|
||||
photo_type = get_value_from_array2(data,'PHOTO.TYPE')
|
||||
data_photo = L('type %s, %s','%s/%s'%(jid,nick)) % (photo_type,get_size_human(photo_size))
|
||||
data = [t for t in list(data) if t[0] not in ['PHOTO.BINVAL','PHOTO.TYPE']]
|
||||
data.append(('PHOTO',data_photo))
|
||||
except: pass
|
||||
args = args.lower()
|
||||
if not args:
|
||||
dd = get_array_from_array2(data,['NICKNAME','FN','BDAY','URL','PHOTO','DESC'])
|
||||
if dd: msg = '%s\n%s' % (L('vCard:','%s/%s'%(jid,nick)),'\n'.join(['%s: %s' % ([L(t[0]),t[0].capitalize()][L(t[0])==t[0]],[u'%s…' % t[1][:VCARD_LIMIT_LONG].strip(),t[1].strip()][len(t[1])<VCARD_LIMIT_LONG]) for t in dd]))
|
||||
else: msg = '%s %s' % (L('vCard:','%s/%s'%(jid,nick)),L('Not found!','%s/%s'%(jid,nick)))
|
||||
elif args == 'all': msg = '%s\n%s' % (L('vCard:','%s/%s'%(jid,nick)),'\n'.join(['%s: %s' % ([L(t[0]),t[0].capitalize()][L(t[0])==t[0]],[u'%s…' % t[1][:VCARD_LIMIT_SHORT].strip(),t[1].strip()][len(t[1])<VCARD_LIMIT_SHORT]) for t in data]))
|
||||
elif args == 'show':
|
||||
dd = []
|
||||
for t in data:
|
||||
if t[0] not in dd: dd.append(t[0])
|
||||
msg = '%s %s' % (L('vCard:','%s/%s'%(jid,nick)),', '.join([[t.capitalize(),'%s (%s)' % (t.capitalize(),L(t))][L(t)!=t] for t in dd]))
|
||||
else:
|
||||
args,dd = args.split('|'),[]
|
||||
for t in args:
|
||||
if ':' in t: val,loc = t.split(':',1)
|
||||
else: val,loc = t,t.upper()
|
||||
val = val.upper()
|
||||
dv = get_array_from_array2(data,(val))
|
||||
if dv: dd += [[loc,dv[0][1]]]
|
||||
if dd: msg = '%s\n%s' % (L('vCard:','%s/%s'%(jid,nick)),'\n'.join(['%s: %s' % ([L(t[0]),t[0].capitalize()][L(t[0])==t[0]],[u'%s…' % t[1][:VCARD_LIMIT_LONG],t[1]][len(t[1])<VCARD_LIMIT_LONG]) for t in dd]))
|
||||
else: msg = '%s %s' % (L('vCard:','%s/%s'%(jid,nick)),L('Not found!','%s/%s'%(jid,nick)))
|
||||
else: msg = '%s %s' % (L('vCard:','%s/%s'%(jid,nick)),L('Empty!','%s/%s'%(jid,nick)))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def iq_uptime(type, jid, nick, text):
|
||||
global iq_request
|
||||
who,iqid = get_who_iq(text,jid,nick),get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':who}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_LAST},[])])
|
||||
iq_request[iqid]=(time.time(),uptime_async,[type, jid, nick, text],xmpp.NS_LAST)
|
||||
sender(i)
|
||||
|
||||
def uptime_async(type, jid, nick, text, is_answ):
|
||||
isa = is_answ[1][0]
|
||||
try:
|
||||
msg = L('Uptime: %s','%s/%s'%(jid,nick)) % un_unix(int(get_tag_item(isa,'query','seconds')),'%s/%s'%(jid,nick))
|
||||
up_stat = esc_min(get_tag(isa,'query'))
|
||||
if len(up_stat): msg = '%s // %s' % (msg,up_stat)
|
||||
except: msg = L('I can\'t do it','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def urn_ping(type, jid, nick, text):
|
||||
global iq_request
|
||||
who,iqid = get_who_iq(text,jid,nick),get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':who}, payload = [xmpp.Node('ping', {'xmlns': xmpp.NS_URN_PING},[])])
|
||||
iq_request[iqid]=(time.time(),ping_async,[type, jid, nick, text],xmpp.NS_URN_PING)
|
||||
sender(i)
|
||||
|
||||
def ping(type, jid, nick, text):
|
||||
global iq_request
|
||||
who,iqid = get_who_iq(text,jid,nick),get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':who}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_VERSION},[])])
|
||||
iq_request[iqid]=(time.time(),ping_async,[type, jid, nick, text],xmpp.NS_VERSION)
|
||||
sender(i)
|
||||
|
||||
def ping_async(type, jid, nick, text, is_answ):
|
||||
global iq_ping_minimal
|
||||
isa = is_answ[1]
|
||||
if len(isa) >= 2 and isa[1] == 'error' and isa[0] == 'remote-server-not-found': msg = L('Error! %s','%s/%s'%(jid,nick)) % L(isa[0].capitalize().replace('-',' '),'%s/%s'%(jid,nick))
|
||||
else:
|
||||
p_digits = GT('ping_digits')
|
||||
original_ping = float(is_answ[0])
|
||||
if iq_ping_minimal > original_ping: iq_ping_minimal = original_ping
|
||||
fixed_ping = round(original_ping - iq_ping_minimal,p_digits)
|
||||
if fixed_ping <= 0: fixed_ping = original_ping
|
||||
f = '%'+'.0%sf' % p_digits
|
||||
if text in ['',nick]: msg = L('Ping from you %s sec.','%s/%s'%(jid,nick)) % f % fixed_ping
|
||||
else: msg = L('Ping from %s %s sec.','%s/%s'%(jid,nick)) % (text, f % fixed_ping)
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def iq_time(type, jid, nick, text):
|
||||
iq_time_get(type, jid, nick, text, None)
|
||||
|
||||
def iq_time_raw(type, jid, nick, text):
|
||||
iq_time_get(type, jid, nick, text, True)
|
||||
|
||||
def iq_time_get(type, jid, nick, text, mode):
|
||||
global iq_request
|
||||
who,iqid = get_who_iq(text,jid,nick),get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':who}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_TIME},[])])
|
||||
iq_request[iqid]=(time.time(),time_async,[type, jid, nick, text, mode],xmpp.NS_TIME)
|
||||
sender(i)
|
||||
|
||||
def time_async(type, jid, nick, text, mode, is_answ):
|
||||
isa = is_answ[1]
|
||||
if len(isa) == 3:
|
||||
msg = isa[0]
|
||||
if mode: msg += ', Raw time: %s, TimeZone: %s' % (isa[1],isa[2])
|
||||
else: msg = ' '.join(isa)
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def iq_utime(type, jid, nick, text):
|
||||
iq_utime_get(type, jid, nick, text, None)
|
||||
|
||||
def iq_utime_raw(type, jid, nick, text):
|
||||
iq_utime_get(type, jid, nick, text, True)
|
||||
|
||||
def iq_utime_get(type, jid, nick, text, mode):
|
||||
global iq_request
|
||||
who,iqid = get_who_iq(text,jid,nick),get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':who}, payload = [xmpp.Node('time', {'xmlns': xmpp.NS_URN_TIME},[])])
|
||||
iq_request[iqid]=(time.time(),utime_async,[type, jid, nick, text, mode],xmpp.NS_URN_TIME)
|
||||
sender(i)
|
||||
|
||||
def utime_async(type, jid, nick, text, mode, is_answ):
|
||||
isa = is_answ[1]
|
||||
if len(isa) >= 2 and isa[1] == 'error': msg = L('Error! %s','%s/%s'%(jid,nick)) % L(isa[0].capitalize().replace('-',' '),'%s/%s'%(jid,nick))
|
||||
else:
|
||||
try:
|
||||
ttup = isa[0].replace('T','-').replace('Z','').replace(':','-').split('-')+['0','0',str(tuple(time.localtime())[8])]
|
||||
lt = time.localtime(time.mktime([int(tmp.split('.',1)[0]) for tmp in ttup])+(int(isa[1].split(':')[0])*60+int(isa[1].split(':')[1]))*60)
|
||||
|
||||
timeofset = float(isa[1].replace(':','.'))
|
||||
if timeofset < 0: t_gmt = 'GMT%s' % int(timeofset)
|
||||
else: t_gmt = 'GMT+%s' % int(timeofset)
|
||||
if timeofset%1: t_gmt += ':%02d' % int((timeofset%1*60/100) * 100)
|
||||
|
||||
msg = '%02d:%02d:%02d, %02d.%s\'%s, %s, %s' % (lt[3],lt[4],lt[5],lt[2],L(wmonth[lt[1]-1],'%s/%s'%(jid,nick)),lt[0],L(wday[lt[6]],'%s/%s'%(jid,nick)),t_gmt)
|
||||
if mode: msg = '%s | %s %s' % (msg,isa[0],isa[1])
|
||||
except: msg = '%s %s' % (L('Unknown server answer!','%s/%s'%(jid,nick)),isa[0])
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def iq_version(type, jid, nick, text): iq_version_raw(type, jid, nick, text, False)
|
||||
|
||||
def iq_version_caps(type, jid, nick, text): iq_version_raw(type, jid, nick, text, True)
|
||||
|
||||
def iq_version_raw(type, jid, nick, text, with_caps):
|
||||
global iq_request
|
||||
who,iqid = get_who_iq(text,jid,nick),get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':who}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_VERSION},[])])
|
||||
iq_request[iqid]=(time.time(),version_async,[type, jid, nick, text, with_caps],xmpp.NS_VERSION)
|
||||
sender(i)
|
||||
|
||||
def version_async(type, jid, nick, text, with_caps, is_answ):
|
||||
isa = is_answ[1]
|
||||
if len(isa) >= 2 and isa[1] == 'error': msg = L('Error! %s','%s/%s'%(jid,nick)) % L(isa[0].capitalize().replace('-',' '),'%s/%s'%(jid,nick))
|
||||
else: msg = isa[0]
|
||||
if with_caps:
|
||||
caps = get_caps(jid,[text,nick][text == ''])
|
||||
if caps: msg += ' || %s' % caps
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def iq_stats(type, jid, nick, text):
|
||||
global iq_request
|
||||
if text == '':
|
||||
send_msg(type, jid, nick, L('What?','%s/%s'%(jid,nick)))
|
||||
return
|
||||
iqid = get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':text}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_STATS},[])])
|
||||
iq_request[iqid]=(time.time(),stats_async_features,[type, jid, nick, text],xmpp.NS_STATS)
|
||||
sender(i)
|
||||
|
||||
def stats_async_features(type, jid, nick, text, is_answ):
|
||||
isa = is_answ[1]
|
||||
if len(isa) >= 2 and isa[1] == 'error':
|
||||
msg = L('Error! %s','%s/%s'%(jid,nick)) % L(isa[0].capitalize().replace('-',' '),'%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
else:
|
||||
try: stats_list = [t.getAttr('name') for t in isa[1].getTag('query',namespace=xmpp.NS_STATS).getTags('stat')]
|
||||
except: stats_list = []
|
||||
if stats_list:
|
||||
iqid = get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':text}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_STATS},[xmpp.Node('stat', {'name':t},[]) for t in stats_list])])
|
||||
iq_request[iqid]=(time.time(),stats_async,[type, jid, nick, text],xmpp.NS_STATS)
|
||||
sender(i)
|
||||
else: send_msg(type, jid, nick, L('Unavailable!','%s/%s'%(jid,nick)))
|
||||
|
||||
def stats_async(type, jid, nick, text, is_answ):
|
||||
isa = is_answ[1]
|
||||
if len(isa) >= 2 and isa[1] == 'error': msg = L('Error! %s','%s/%s'%(jid,nick)) % L(isa[0].capitalize().replace('-',' '),'%s/%s'%(jid,nick))
|
||||
else:
|
||||
try: stats_list = [[L(t.getAttr('name')),L(t.getAttr('value')),L(t.getAttr('units'))] for t in isa[1].getTag('query',namespace=xmpp.NS_STATS).getTags('stat')]
|
||||
except: stats_list = []
|
||||
if stats_list:
|
||||
stats_list = ['%s: %s' % (t[0].capitalize(),t[1]) if t[2] in t[0] else '%s: %s %s' % (t[0].capitalize(),t[1],t[2]) for t in stats_list]
|
||||
msg = L('Server statistic: %s\n%s','%s/%s'%(jid,nick)) % (text,'\n'.join(stats_list))
|
||||
else: msg = L('Unavailable!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute, iq_hook
|
||||
|
||||
iq_hook = [[50,'get',iq_iq_get]]
|
||||
|
||||
execute = [(3, 'ver', iq_version, 2, 'Client version.', ['nick','jid','server']),
|
||||
(3, 'ver+', iq_version_caps, 2, 'Client version with caps.', ['nick']),
|
||||
(3, 'caps', noiq_caps, 2, 'Show caps node and version of client.', ['nick']),
|
||||
(3, 'ping_old', ping, 2, 'Ping - reply time. You can ping nick in room, jid, server or transport.', ['nick','jid','server']),
|
||||
(3, 'ping', urn_ping, 2, 'Ping - reply time. You can ping nick in room, jid, server or transport.', ['nick','jid','server']),
|
||||
(3, 'time_old', iq_time, 2, 'Client side time.', ['nick','jid']),
|
||||
(3, 'time', iq_utime, 2, 'Client side time.', ['nick','jid']),
|
||||
(3, 'time_old_raw', iq_time_raw, 2, 'Client side time + raw time format.', ['nick','jid']),
|
||||
(3, 'time_raw', iq_utime_raw, 2, 'Client side time + raw time format.', ['nick','jid']),
|
||||
(3, 'stats', iq_stats, 2, 'Users server statistic.', ['nick','jid','server']),
|
||||
(3, 'vcard_raw', iq_vcard, 2, 'vCard query. Recomends make command base alias for query needs info.\nvcard_raw [nick] - query generic info\nvcard_raw nick\nshow - show available fields\nvcard_raw nick\n[field:name|field:name] - show requested fields from vcard.', ['nick','jid','server']),
|
||||
(3, 'uptime', iq_uptime, 2, 'Server or jid uptime.', ['nick','jid','server'])]
|
||||
208
plugins/issue.py
Normal file
208
plugins/issue.py
Normal file
@@ -0,0 +1,208 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
# id, room, jid, nick, level, tags, body, status, date, comment, accept_by, accept_date
|
||||
|
||||
# translate: new,pending,accepted,rejected,removed,done,Pending by,Accepted by,Rejected by,Removed by,Mark as done by
|
||||
|
||||
issue_status = ['new','pending','accepted','rejected','removed','done']
|
||||
issue_status_show = ['','Pending by','Accepted by','Rejected by','Removed by','Mark as done by']
|
||||
issue_new_id = 0
|
||||
issue_pending_id = 1
|
||||
issue_accept_id = 2
|
||||
issue_reject_id = 3
|
||||
issue_remove_id = 4
|
||||
issue_done_id = 5
|
||||
issue_number_format = '#%04d'
|
||||
|
||||
def issue(type, room, nick, text):
|
||||
ttext = reduce_spaces_all(text)
|
||||
subc = ttext.split()
|
||||
acclvl,jid = get_level(room,nick)
|
||||
if ttext.isdigit() or (ttext and ttext[0] == '#' and ttext[1:].isdigit()) or not subc or len(subc) == 1 or subc[0] == 'show' or (acclvl <= 3 and type == 'chat'): msg,type = issue_show(subc,room,type,nick)
|
||||
elif subc[0] in ['del','delete','rm','remove']: msg = issue_remove(subc,acclvl,room,jid,nick)
|
||||
elif subc[0] == 'pending': msg = issue_pending(subc,acclvl,room,jid,nick)
|
||||
elif subc[0] == 'accept': msg = issue_accept(subc,acclvl,room,jid,nick)
|
||||
elif subc[0] == 'reject': msg = issue_reject(subc,acclvl,room,jid,nick)
|
||||
elif subc[0] == 'done': msg = issue_done(subc,acclvl,room,jid,nick)
|
||||
else: msg = issue_new(subc,acclvl,room,jid,nick,text)
|
||||
send_msg(type, room, nick, msg)
|
||||
|
||||
def issue_new(s,acclvl,room,jid,nick,text):
|
||||
tags = []
|
||||
for t in s:
|
||||
if t[0] == '*' and len(t) > 1:
|
||||
tags.append(t[1:])
|
||||
text = text.replace(t,'',1)
|
||||
else: break
|
||||
s = s[len(tags):]
|
||||
if not s: return L('No issue\'s body!','%s/%s'%(room,nick))
|
||||
tags = ' '.join(tags)
|
||||
body = text.strip()
|
||||
try: id = cur_execute_fetchone('select count(*) from issues where room=%s',(room,))[0] + 1
|
||||
except: id = 1
|
||||
tbody = cur_execute_fetchall('select id from issues where room=%s and body ilike %s',(room,'%%%s%%' % body))
|
||||
if tbody: return L('I know same issue(s): %s','%s/%s'%(room,nick)) % ', '.join(issue_number_format % t for t in zip(*tbody)[0])
|
||||
stts = cur_execute('insert into issues values (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)', (id, room, getRoom(jid), nick, acclvl, tags, body, issue_new_id, int(time.time()),'','',0))
|
||||
if stts == True: return L('Added issue %s','%s/%s'%(room,nick)) % issue_number_format % id
|
||||
else: return str(stts)
|
||||
|
||||
def issue_show(s,room,type,nick):
|
||||
if len(s) > 1 and s[0] == 'show': s = s[1]
|
||||
elif len(s) == 1 and s[0] == 'show': s = '%'
|
||||
elif s: s = s[0]
|
||||
else: s = '%'
|
||||
|
||||
if s.isdigit() or (s[0] == '#' and s[1:].isdigit()): s = s.replace('#','')
|
||||
|
||||
s_original = s
|
||||
|
||||
if s.isdigit(): iss = cur_execute_fetchall('select id,nick,tags,body,status,comment,accept_by,accept_date from issues where room=%s and id=%s order by id;',(room,int(s)))
|
||||
elif s[0] == '*': iss = cur_execute_fetchall('select id,nick,tags,body,status,comment,accept_by,accept_date from issues where room=%s and tags ilike %s and status<%s order by id;',(room,'%%%s%%' % s[1:],issue_reject_id))
|
||||
else:
|
||||
if s != '%': s = '%%%s%%' % s
|
||||
iss = cur_execute_fetchall('select id,nick,tags,body,status,comment,accept_by,accept_date from issues where room=%s and (tags ilike %s or body ilike %s or comment ilike %s or nick ilike %s) and status<%s order by id;',(room,s,s,s,s,issue_reject_id))
|
||||
if iss:
|
||||
tm = []
|
||||
if len(iss) > 1 and type == 'groupchat':
|
||||
send_msg(type, room, nick, L('Sent in private message','%s/%s'%(room,nick)))
|
||||
type = 'chat'
|
||||
for t in iss:
|
||||
if t[2]: tmp = '%s (%s) *%s | %s\n%s' % (issue_number_format % t[0],L(issue_status[t[4]],'%s/%s'%(room,nick)),' *'.join(t[2].split()),L('Created by %s','%s/%s'%(room,nick)) % t[1],t[3])
|
||||
else: tmp = '%s (%s) %s\n%s' % (issue_number_format % t[0],L(issue_status[t[4]],'%s/%s'%(room,nick)),L('Created by %s','%s/%s'%(room,nick)) % t[1],t[3])
|
||||
if t[4]:
|
||||
tmp = '%s\n%s %s [%s]' % (tmp,L(issue_status_show[t[4]],'%s/%s'%(room,nick)),t[6],disp_time(t[7],'%s/%s'%(room,nick)))
|
||||
if t[5]: tmp += L(', by reason: %s','%s/%s'%(room,nick)) % t[5]
|
||||
tm.append(tmp)
|
||||
return L('Issue(s) list:\n%s','%s/%s'%(room,nick)) % '\n\n'.join(tm), type
|
||||
elif s_original == '%': return L('Issues not found!','%s/%s'%(room,nick)), type
|
||||
else: return L('Issues with match \'%s\' not found!','%s/%s'%(room,nick)) % s_original, type
|
||||
|
||||
def issue_remove(s,acclvl,room,jid,nick):
|
||||
if len(s) > 1: id = s[1]
|
||||
else: return L('Which issue need remove?','%s/%s'%(room,nick))
|
||||
if id.isdigit() or id[0] == '#':
|
||||
try: id = int(id.replace('#',''))
|
||||
except: return L('You must use numeric issue id.','%s/%s'%(room,nick))
|
||||
iss = cur_execute_fetchall('select jid,level,status from issues where room=%s and id=%s;',(room,id))
|
||||
else: return L('You must use numeric issue id.','%s/%s'%(room,nick))
|
||||
if iss:
|
||||
if iss[0][2] != issue_remove_id:
|
||||
if acclvl >= 7 or iss[0][0] == jid:
|
||||
if len(s) > 2: cmt = ' '.join(s[2:])
|
||||
else: cmt = ''
|
||||
cur_execute('update issues set status=%s,accept_by=%s,accept_date=%s,comment=%s where room=%s and id=%s', (issue_remove_id,nick,int(time.time()),cmt,room,id))
|
||||
return L('Issue %s removed!','%s/%s'%(room,nick)) % issue_number_format % id
|
||||
else: return L('There is not Your issue or You have no rights to remove it.','%s/%s'%(room,nick))
|
||||
else: return L('Issue %s was removed earlier!','%s/%s'%(room,nick)) % issue_number_format % id
|
||||
else: return L('Issue %s not found!','%s/%s'%(room,nick)) % issue_number_format % id
|
||||
|
||||
def issue_accept(s,acclvl,room,jid,nick):
|
||||
if len(s) > 1: id = s[1]
|
||||
else: return L('Which issue need accept?','%s/%s'%(room,nick))
|
||||
if id.isdigit() or id[0] == '#':
|
||||
try: id = int(id.replace('#',''))
|
||||
except: return L('You must use numeric issue id.','%s/%s'%(room,nick))
|
||||
iss = cur_execute_fetchall('select jid,level,status,tags from issues where room=%s and id=%s;',(room,id))
|
||||
else: return L('You must use numeric issue id.','%s/%s'%(room,nick))
|
||||
if iss:
|
||||
if acclvl >= 7 or iss[0][0] == jid or iss[0][1] <= acclvl:
|
||||
if len(s) > 2:
|
||||
tags = iss[0][3].split()
|
||||
cnt = 2
|
||||
for t in s[2:]:
|
||||
if t[0] == '*' and len(t) > 1:
|
||||
if t[1:] not in tags: tags.append(t[1:])
|
||||
else: tags.remove(t[1:])
|
||||
cnt += 1
|
||||
else: break
|
||||
s = s[cnt:]
|
||||
tags = ' '.join(tags)
|
||||
cmt = ' '.join(s)
|
||||
else: cmt,tags = '',iss[0][3]
|
||||
cur_execute('update issues set status=%s,accept_by=%s,accept_date=%s,comment=%s,tags=%s where room=%s and id=%s', (issue_accept_id,nick,int(time.time()),cmt,tags,room,id))
|
||||
if iss[0][2] != issue_accept_id: return L('Issue %s accepted!','%s/%s'%(room,nick)) % issue_number_format % id
|
||||
else: return L('Issue %s was accepted earlier!','%s/%s'%(room,nick)) % issue_number_format % id
|
||||
else: return L('There is not Your issue or You have no rights to accept it.','%s/%s'%(room,nick))
|
||||
else: return L('Issue %s not found!','%s/%s'%(room,nick)) % issue_number_format % id
|
||||
|
||||
def issue_reject(s,acclvl,room,jid,nick):
|
||||
if len(s) > 1: id = s[1]
|
||||
else: return L('Which issue need reject?','%s/%s'%(room,nick))
|
||||
if id.isdigit() or id[0] == '#':
|
||||
try: id = int(id.replace('#',''))
|
||||
except: return L('You must use numeric issue id.','%s/%s'%(room,nick))
|
||||
iss = cur_execute_fetchall('select jid,level,status from issues where room=%s and id=%s;',(room,id))
|
||||
else: return L('You must use numeric issue id.','%s/%s'%(room,nick))
|
||||
if iss:
|
||||
if iss[0][2] != issue_reject_id:
|
||||
if acclvl >= 7 or iss[0][0] == jid or iss[0][1] <= acclvl:
|
||||
if len(s) > 2: cmt = ' '.join(s[2:])
|
||||
else: cmt = ''
|
||||
cur_execute('update issues set status=%s,accept_by=%s,accept_date=%s,comment=%s where room=%s and id=%s', (issue_reject_id,nick,int(time.time()),cmt,room,id))
|
||||
return L('Issue %s rejected!','%s/%s'%(room,nick)) % issue_number_format % id
|
||||
else: return L('There is not Your issue or You have no rights to reject it.','%s/%s'%(room,nick))
|
||||
else: return L('Issue %s was rejected earlier!','%s/%s'%(room,nick)) % issue_number_format % id
|
||||
else: return L('Issue %s not found!','%s/%s'%(room,nick)) % issue_number_format % id
|
||||
|
||||
def issue_pending(s,acclvl,room,jid,nick):
|
||||
if len(s) > 1: id = s[1]
|
||||
else: return L('Which issue is pending?','%s/%s'%(room,nick))
|
||||
if id.isdigit() or id[0] == '#':
|
||||
try: id = int(id.replace('#',''))
|
||||
except: return L('You must use numeric issue id.','%s/%s'%(room,nick))
|
||||
iss = cur_execute_fetchall('select jid,level,status from issues where room=%s and id=%s;',(room,id))
|
||||
else: return L('You must use numeric issue id.','%s/%s'%(room,nick))
|
||||
if iss:
|
||||
if iss[0][2] != issue_reject_id:
|
||||
if acclvl >= 7 or iss[0][0] == jid or iss[0][1] <= acclvl:
|
||||
if len(s) > 2: cmt = ' '.join(s[2:])
|
||||
else: cmt = ''
|
||||
cur_execute('update issues set status=%s,accept_by=%s,accept_date=%s,comment=%s where room=%s and id=%s', (issue_pending_id,nick,int(time.time()),cmt,room,id))
|
||||
return L('Issue %s is mark as pending!','%s/%s'%(room,nick)) % issue_number_format % id
|
||||
else: return L('There is not Your issue or You have no rights to mark as pending.','%s/%s'%(room,nick))
|
||||
else: return L('Issue %s was marked as pending earlier!','%s/%s'%(room,nick)) % issue_number_format % id
|
||||
else: return L('Issue %s not found!','%s/%s'%(room,nick)) % issue_number_format % id
|
||||
|
||||
def issue_done(s,acclvl,room,jid,nick):
|
||||
if len(s) > 1: id = s[1]
|
||||
else: return L('Which issue is done?','%s/%s'%(room,nick))
|
||||
if id.isdigit() or id[0] == '#':
|
||||
try: id = int(id.replace('#',''))
|
||||
except: return L('You must use numeric issue id.','%s/%s'%(room,nick))
|
||||
iss = cur_execute_fetchall('select jid,level,status from issues where room=%s and id=%s;',(room,id))
|
||||
else: return L('You must use numeric issue id.','%s/%s'%(room,nick))
|
||||
if iss:
|
||||
if iss[0][2] != issue_reject_id:
|
||||
if acclvl >= 7 or iss[0][0] == jid or iss[0][1] <= acclvl:
|
||||
if len(s) > 2: cmt = ' '.join(s[2:])
|
||||
else: cmt = ''
|
||||
cur_execute('update issues set status=%s,accept_by=%s,accept_date=%s,comment=%s where room=%s and id=%s', (issue_done_id,nick,int(time.time()),cmt,room,id))
|
||||
return L('Issue %s marked as done!','%s/%s'%(room,nick)) % issue_number_format % id
|
||||
else: return L('There is not Your issue or You have no rights to mark as done.','%s/%s'%(room,nick))
|
||||
else: return L('Issue %s was marked as done earlier!','%s/%s'%(room,nick)) % issue_number_format % id
|
||||
else: return L('Issue %s not found!','%s/%s'%(room,nick)) % issue_number_format % id
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'issue', issue, 2, 'Issues\nissue [[[show|pending|accept|reject|delete|done] id] reason] - actions with issue\nissue *tag1 *tag2 some text - add issue `some text` with tags tag1 and tag2')]
|
||||
64
plugins/istrue.py
Normal file
64
plugins/istrue.py
Normal file
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def is_valid(type, jid, nick, text):
|
||||
if text == '': text = nick
|
||||
ru_lit, en_lit, caps_lit = 0, 0, 0
|
||||
for tmp in text:
|
||||
if re.match('[a-z]|[A-Z]',tmp): en_lit+=1
|
||||
elif re.match(u'[а-яё]|[А-ЯЁ]',tmp): ru_lit+=1
|
||||
if re.match(u'[A-Z]|[А-ЯЁ]',tmp): caps_lit+=1
|
||||
lt = len(text)
|
||||
if ru_lit<en_lit: idx, hl = float(ru_lit)/en_lit, 1
|
||||
elif ru_lit>en_lit: idx, hl = float(en_lit)/ru_lit, 2
|
||||
else: idx, hl = 0.5, None
|
||||
if (ru_lit == lt or en_lit == lt) and float(caps_lit)/lt <= 0.5: msg = L('100% True-nick!','%s/%s'%(jid,nick))
|
||||
elif ru_lit+en_lit == 0: msg = L('Nicks without letters isn\'t true!','%s/%s'%(jid,nick))
|
||||
elif ru_lit+en_lit+text.count(' ')+text.count('.') == lt: msg = L('Valid of nick is - %s%s','%s/%s'%(jid,nick)) % (100-int(idx*100), '%!')
|
||||
elif not ru_lit or not en_lit: msg = L('Normal nick, but left symbols in fireplace.','%s/%s'%(jid,nick))
|
||||
else: msg = L('Valid of nick is - %s%s','%s/%s'%(jid,nick)) % (int(float(ru_lit+en_lit)/lt*100-int(idx*100)), '%!')
|
||||
if float(caps_lit)/lt > 0.5: msg += ' ' + L('Many caps - %s%s','%s/%s'%(jid,nick)) % (int(float(caps_lit)/lt*100), '%!')
|
||||
if ru_lit+en_lit:
|
||||
msg += ' ' + L('Dominate letters:','%s/%s'%(jid,nick)) + ' '
|
||||
if hl == 1: msg += L('Latin','%s/%s'%(jid,nick))
|
||||
elif hl == 2: msg += L('Cyrillic','%s/%s'%(jid,nick))
|
||||
else: msg += L('Equally','%s/%s'%(jid,nick))
|
||||
|
||||
def repl(t): return '[%s]' % t.group()
|
||||
msg += ' - %s' % re.sub([u'([а-яё]+)','([a-z]+)'][hl==1],repl,text,flags=re.S|re.I|re.U)
|
||||
|
||||
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def is_true(type, jid, nick, text):
|
||||
if text == '': msg = L('And?','%s/%s'%(jid,nick))
|
||||
else:
|
||||
idx = 0
|
||||
for tmp in text: idx += ord(tmp)
|
||||
msg = L('Expression is true for %s%s','%s/%s'%(jid,nick)) % (idx % 100, '%')
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'true', is_true, 2, 'Check truth of expession.'),
|
||||
(3, 'valid', is_valid, 2, 'Check different languages symbols in nick.')]
|
||||
35
plugins/jc.py
Normal file
35
plugins/jc.py
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def jc(type, jid, nick, text):
|
||||
if not len(text): text = getName(jid)
|
||||
try:
|
||||
body = json.loads(html_encode(load_page('http://jc.jabber.ru/search.html?%s'.encode("utf-8") % (urllib.urlencode({'json':'1', 'search':text.encode("utf-8")})))))
|
||||
if body['result']: msg = L('Found:','%s/%s'%(jid,nick)) + ''.join(['\n%s. %s [%s] %s' % ([t['raiting'],'-'][t['raiting']==''],t['description'],t['jid'],t['current']) for t in body['result']])
|
||||
else: msg = L('Not found.','%s/%s'%(jid,nick))
|
||||
except: msg = L('Error!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'jc', jc, 2, 'Show information about conference from jc.jabber.ru.\njc [address]')]
|
||||
121
plugins/jidcatcher.py
Normal file
121
plugins/jidcatcher.py
Normal file
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
JIDCATCHER_DEFAULT_LIMIT = 10
|
||||
|
||||
def info_search(type, jid, nick, text):
|
||||
msg = L('What I must find?','%s/%s'%(jid,nick))
|
||||
if text:
|
||||
if '\n' in text:
|
||||
text,lim = text.split('\n',1)
|
||||
try:
|
||||
lim = int(lim)
|
||||
if lim < 100 or lim > 1: raise
|
||||
except: lim = JIDCATCHER_DEFAULT_LIMIT
|
||||
else: lim = JIDCATCHER_DEFAULT_LIMIT
|
||||
cur_execute('delete from jid where server ilike %s',('<temporary>%',))
|
||||
ttext = '%%%s%%' % text
|
||||
tma = cur_execute_fetchall('select * from jid where login ilike %s or server ilike %s or resourse ilike %s order by login limit %s',(ttext,ttext,ttext,lim))
|
||||
if tma: msg = '%s\n%s' % (L('Found:','%s/%s'%(jid,nick)),'\n'.join(['%s. %s@%s/%s' % tuple([tma.index(tt)+1]+list(tt)) for tt in tma]))
|
||||
else: msg = L('\'%s\' not found!','%s/%s'%(jid,nick)) % text
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def info_res(type, jid, nick, text):
|
||||
cur_execute('delete from jid where server ilike %s',('<temporary>%',))
|
||||
if text.lower() == 'count':
|
||||
tlen = cur_execute_fetchall('select count(*) from (select resourse,count(*) from jid group by resourse) tmp;')[0][0]
|
||||
text,jidbase = '',''
|
||||
else:
|
||||
text1 = '%%%s%%' % text
|
||||
tlen = cur_execute_fetchall('select count(*) from (select resourse,count(*) from jid where resourse ilike %s group by resourse) tmp;',(text1,))[0][0]
|
||||
jidbase = cur_execute_fetchall('select resourse,count(*) from jid where resourse ilike %s group by resourse order by -count(*),resourse limit %s',(text1,JIDCATCHER_DEFAULT_LIMIT))
|
||||
if not tlen: msg = L('\'%s\' not found!','%s/%s'%(jid,nick)) % text
|
||||
else:
|
||||
if text: msg = L('Found resources: %s','%s/%s'%(jid,nick)) % tlen
|
||||
else: msg = L('Total resources: %s','%s/%s'%(jid,nick)) % tlen
|
||||
if jidbase: msg += '\n%s' % '\n'.join(['%s. %s\t%s' % tuple([jidbase.index(jj)+1]+list(jj)) for jj in jidbase])
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def info_serv(type, jid, nick, text):
|
||||
cur_execute('delete from jid where server ilike %s',('<temporary>%',))
|
||||
|
||||
if '\n' in text:
|
||||
text,lim = text.split('\n',1)
|
||||
try:
|
||||
lim = int(lim)
|
||||
if lim > 100 or lim < 1: raise
|
||||
except: lim = JIDCATCHER_DEFAULT_LIMIT
|
||||
else: lim = JIDCATCHER_DEFAULT_LIMIT
|
||||
|
||||
if text == 'count':
|
||||
tlen = cur_execute_fetchone('select count(*) from (select server,count(*) from jid group by server) tmp;')[0]
|
||||
text,jidbase = '',''
|
||||
else:
|
||||
text1 = '%%%s%%' % text
|
||||
if base_type == 'pgsql': reqv = 'select * from (select row_number() over(order by -count(*)),server,count(*) from jid group by server order by -count(*),server) tmp where tmp.server ilike %s order by tmp.row_number;'
|
||||
elif base_type == 'mysql': reqv = 'select * from (select @i:=@i+1 as itr,sr,cn from (select server as sr,count(*) as cn from jid group by server order by -count(*)) as t1,(select @i:=0) as t2) as t3 where sr like %s'
|
||||
elif base_type == 'sqlite3':
|
||||
# TODO: It's works not properly. Need fix record's numbers!
|
||||
reqv = 'select row_number(),sr,cn from (select server as sr,count(*) as cn from jid group by server order by -cn) where sr like %s order by -cn'
|
||||
jidbase = cur_execute_fetchall(reqv,(text1,))
|
||||
tlen = len(jidbase)
|
||||
jidbase = jidbase[:lim]
|
||||
if not tlen: msg = L('\'%s\' not found!','%s/%s'%(jid,nick)) % text
|
||||
else:
|
||||
if text: msg = L('Found servers: %s','%s/%s'%(jid,nick)) % tlen
|
||||
else: msg = L('Total servers: %s','%s/%s'%(jid,nick)) % tlen
|
||||
if jidbase: msg = '%s\n%s' %(msg,'\n'.join(['%s. %s [%s]' % (int(jj[0]),jj[1],jj[2]) for jj in jidbase]))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
#room number date
|
||||
|
||||
def info_top(type, jid, nick, text):
|
||||
if text: room = text
|
||||
else: room = getRoom(jid)
|
||||
cnf = cur_execute_fetchone('select count ,time from top where room=%s',(room,))
|
||||
if cnf: msg = L('Max count of members: %s %s','%s/%s'%(jid,nick)) % (cnf[0], '(%s)' % disp_time(cnf[1],'%s/%s'%(jid,nick)))
|
||||
else: msg = L('Statistic not found!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def jidcatcher_presence(room,jid,nick,type,text):
|
||||
if jid != 'None' and not jid.startswith('<temporary>'):
|
||||
tmp = (getName(jid),getServer(jid),getResourse(jid))
|
||||
try:
|
||||
tmpp = cur_execute_fetchone('select login from jid where login=%s and server=%s and resourse=%s',tmp)
|
||||
if not tmpp: cur_execute('insert into jid values (%s,%s,%s)', tmp)
|
||||
except: pass
|
||||
|
||||
cnt = len(['' for t in megabase if t[0]==room])
|
||||
cnf = cur_execute_fetchone('select count from top where room=%s',(room,))
|
||||
if cnf:
|
||||
if cnt > cnf[0]: cur_execute('update top set count =%s, time=%s where room=%s;',(cnt,int(time.time()),room))
|
||||
else: cur_execute('insert into top values (%s,%s,%s);',(room,cnt,int(time.time())))
|
||||
|
||||
global execute, presence_control
|
||||
|
||||
presence_control = [jidcatcher_presence]
|
||||
|
||||
execute = [(4, 'res', info_res, 2, 'Without parameters show top10 resources for all conferences, where bot is present.\nwith parameters - search in resources base\ncount - number of results.'),
|
||||
(6, 'serv', info_serv, 2, 'Wihtout parameters show all servers freom where joined in rooms, where bot is present\nwith parameters - search on servers base\ncount - show number of results.'),
|
||||
(9, 'search', info_search, 2, 'Search in internal jids base.'),
|
||||
(2, 'top', info_top, 2, 'Conference\'s activity.')]
|
||||
165
plugins/juick.py
Normal file
165
plugins/juick.py
Normal file
@@ -0,0 +1,165 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
JUICK_JID = 'juick@juick.com'
|
||||
|
||||
# Список последних сообщений:
|
||||
JUICK_MESSAGES = 'http://api.juick.com/messages'
|
||||
|
||||
JUICK_MESSAGES_REQUEST = '%s?' % JUICK_MESSAGES
|
||||
# Поиск по сообщениям: search=<запрос>
|
||||
# Фильтрация по тегу: tag=<тег>
|
||||
# Фильтрация по типу контента: media=all | media=photo | media=video
|
||||
# Последние сообщения пользователя: user_id=<uid> | user_id=<uid>&tag=<тег>
|
||||
# Для списков сообщений выводится одна «страница». Для вывода дополнительных «страниц»: параметры before_mid, page
|
||||
# before_mid=<id последнего загруженного сообщения>&page=<page>
|
||||
|
||||
# Просмотр сообщения с комментариями
|
||||
JUICK_THREAD = 'http://api.juick.com/thread?' # mid=<message ID>
|
||||
|
||||
# Получение UserID по нику:
|
||||
JUICK_USERS = 'http://api.juick.com/users?' # uname=ugnich
|
||||
|
||||
# Популярные теги:
|
||||
JUICK_TAGS = 'http://api.juick.com/tags'
|
||||
|
||||
# Все теги пользователя:
|
||||
JUICK_TAGS_USER = '%s?' % JUICK_TAGS # user_id=<uid>
|
||||
|
||||
JUICK_URL = 'http://juick.com/%s'
|
||||
|
||||
def juick(type, jid, nick, text):
|
||||
text = text.strip()
|
||||
topt = text.split(' ',1)
|
||||
topt[0] = topt[0].lower()
|
||||
try: prm = topt[1].strip()
|
||||
except: prm = ''
|
||||
if topt[0] == 'msg' and prm: juick_msg(type, jid, nick, prm)
|
||||
elif topt[0] == 'tags': juick_tags(type, jid, nick, prm)
|
||||
elif topt[0] == 'search': juick_search(type, jid, nick, prm)
|
||||
elif topt[0] == 'user': juick_user(type, jid, nick, prm)
|
||||
else:
|
||||
try: tmpt = re.findall('(^[^@]#?[0-9]+)',text)[0]
|
||||
except: tmpt = ''
|
||||
if tmpt: juick_msg(type, jid, nick, text)
|
||||
elif text and text[0] == '@': juick_user(type, jid, nick, text)
|
||||
else: send_msg(type, jid, nick, L('Smoke help about command!','%s/%s'%(jid,nick)))
|
||||
|
||||
def juick_user(type, jid, nick, text):
|
||||
if text and text[0] == '@': text = text[1:]
|
||||
try: result = json.loads(html_encode(load_page(JUICK_MESSAGES_REQUEST, {'user_id':str(json.loads(html_encode(load_page(JUICK_USERS, {'uname': text})).replace('\t',' '*8))[0]['uid'])})).replace('\t',' '*8))
|
||||
except:
|
||||
send_msg(type, jid, nick, L('User @%s not found!','%s/%s'%(jid,nick)) % text)
|
||||
return
|
||||
tp = []
|
||||
for t in result[:GT('juick_user_post_limit')]:
|
||||
tm = '#%s' % t['mid']
|
||||
if t.has_key('tags'): tm = '%s *%s' % (tm, ' *'.join(t['tags']))
|
||||
tm = '%s | %s' % (tm,replacer(t['body'][:GT('juick_user_post_size')].replace('\n',' \\ ')+['',u'…'][len(t['body']) > GT('juick_user_post_size')]))
|
||||
if t.has_key('replies'): tm = '%s %s' % (tm, L('Replies: %s','%s/%s'%(jid,nick)) % t['replies'])
|
||||
tp.append(tm)
|
||||
msg = L('Found: %s','%s/%s'%(jid,nick)) % '%s\n%s' % (text,'\n'.join(tp))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def juick_search(type, jid, nick, text):
|
||||
result = json.loads(html_encode(load_page(JUICK_MESSAGES_REQUEST, {'search': text})).replace('\t',' '*8))
|
||||
tp = []
|
||||
for t in result[:GT('juick_user_post_limit')]:
|
||||
tm = '#%s @%s: %s' % (t['mid'],replacer(t['user']['uname']),replacer(t['body'][:GT('juick_user_post_size')].replace('\n',' \\ ')+['',u'…'][len(t['body']) > GT('juick_user_post_size')]))
|
||||
if t.has_key('replies'): tm = '%s | %s' % (tm, L('Replies: %s','%s/%s'%(jid,nick)) % t['replies'])
|
||||
if t.has_key('tags'): tm = '%s | *%s' % (tm, ' *'.join(t['tags']))
|
||||
tp.append(tm)
|
||||
msg = L('Found: %s','%s/%s'%(jid,nick)) % '\n%s' % '\n'.join(tp)
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def juick_tags(type, jid, nick, text):
|
||||
if text and text[0] == '@': text = text[1:]
|
||||
try:
|
||||
if text: hdr,url,params = L('Popular tags of @%s:','%s/%s'%(jid,nick)) % text,JUICK_TAGS_USER,{'user_id':str(json.loads(html_encode(load_page(JUICK_USERS, {'uname': text})).replace('\t',' '*8))[0]['uid'])}
|
||||
else: hdr,url,params = L('Popular tags:','%s/%s'%(jid,nick)),JUICK_TAGS,{}
|
||||
result = json.loads(html_encode(load_page(url,params)).replace('\t',' '*8))
|
||||
tags = [((t['messages'],replacer(t['tag']))) for t in result]
|
||||
tags.sort(reverse=True)
|
||||
msg = '%s %s' % (hdr,', '.join(['%s [%s]' % (t[1],t[0]) for t in tags[:GT('juick_user_tags_limit')]]))
|
||||
except:
|
||||
if text: msg = L('User @%s not found!','%s/%s'%(jid,nick)) % text
|
||||
else: msg = L('Unknown error!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def juick_msg(type, jid, nick, text):
|
||||
j_mid,j_rid = re.findall('#?([0-9]+)\/?([0-9]+)?',text)[0]
|
||||
if j_rid:
|
||||
try: j_rid = int(j_rid)
|
||||
except: j_rid = 0
|
||||
else: j_rid = 0
|
||||
try: j_replies = int(text.split()[1])
|
||||
except: j_replies = GT('juick_msg_answers_default')
|
||||
try: result = json.loads(html_encode(load_page(JUICK_THREAD, {'mid': j_mid})).replace('\t',' '*8))
|
||||
except:
|
||||
send_msg(type, jid, nick, L('Message #%s is not found!','%s/%s'%(jid,nick)) % j_mid)
|
||||
return
|
||||
if j_rid:
|
||||
found = False
|
||||
for t in result:
|
||||
if t.has_key('rid') and t['rid'] == j_rid:
|
||||
result,found = t,True
|
||||
break
|
||||
if not found:
|
||||
send_msg(type, jid, nick, L('Message #%s is not found!','%s/%s'%(jid,nick)) % '%s/%s' % (j_mid,j_rid))
|
||||
return
|
||||
else: result=result[0]
|
||||
uname = replacer(result['user']['uname'])
|
||||
try: tags = '*%s' % ' *'.join([replacer(t) for t in result['tags']])
|
||||
except: tags = ''
|
||||
body = replacer(result['body'])
|
||||
timestamp = result['timestamp']
|
||||
mid = str(result['mid'])
|
||||
try: replies = L('Replies: %s','%s/%s'%(jid,nick)) % result['replies']
|
||||
except: replies = 0
|
||||
if result.has_key('video'):
|
||||
media = result['video']
|
||||
media = L('Attach: %s','%s/%s'%(jid,nick)) % media[media.keys()[0]]
|
||||
elif result.has_key('photo'): media = L('Attach: %s','%s/%s'%(jid,nick)) % result['photo']['medium']
|
||||
else: media = ''
|
||||
try: replyto = result['replyto']
|
||||
except: replyto = ''
|
||||
try: mid2 = '%s#%s' % (mid,result['rid'])
|
||||
except: mid2 = mid
|
||||
if replyto:
|
||||
if replies: msg = '@%s: %s\n%s\n#%s -> #%s/%s, %s, %s, %s' % (uname,tags,body,mid2.replace('#','/'),mid,replyto,timestamp,replies,JUICK_URL % mid2)
|
||||
else: msg = '@%s: %s\n%s\n#%s -> #%s/%s, %s, %s' % (uname,tags,body,mid2.replace('#','/'),mid,replyto,timestamp,JUICK_URL % mid2)
|
||||
else:
|
||||
if replies: msg = '@%s: %s\n%s\n#%s, %s, %s, %s' % (uname,tags,body,mid2.replace('#','/'),timestamp,replies,JUICK_URL % mid2)
|
||||
else: msg = '@%s: %s\n%s\n#%s, %s, %s' % (uname,tags,body,mid2.replace('#','/'),timestamp,JUICK_URL % mid2)
|
||||
if media: msg = '%s\n%s' % (msg,media)
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def juick_post(type, jid, nick, text):
|
||||
send_msg('chat', JUICK_JID, '', text)
|
||||
time.sleep(1.2)
|
||||
send_msg(type, jid, nick, L('Message posted to Juick.','%s/%s'%(jid,nick)))
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'juick', juick, 2, 'Miniblogs http://juick.com\njuick [msg][#]post - show post\njuick tags [user] - show popular tags\njuick search [text] - search text\njuick [user] @username - show messages of user'),
|
||||
(9, 'juick_post', juick_post, 2, 'Send message to blog at juick.com')]
|
||||
271
plugins/karma.py
Normal file
271
plugins/karma.py
Normal file
@@ -0,0 +1,271 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
last_karma = {}
|
||||
|
||||
def karma(type, jid, nick, text):
|
||||
arg = text.split(' ',1)
|
||||
try: arg1 = arg[1]
|
||||
except: arg1 = None
|
||||
a0l = arg[0].lower()
|
||||
|
||||
karma_comm = {'show': [karma_show, (jid, nick, arg1)],
|
||||
'top+': [karma_top, (jid, nick, arg1, None)],
|
||||
'top-': [karma_top, (jid, nick, arg1, True)],
|
||||
'set': [karma_set, (jid, nick, arg1)],
|
||||
'clear': [karma_clear, (jid, nick, arg1)]}
|
||||
|
||||
if karma_comm.has_key(a0l): msg = karma_comm[a0l][0](*karma_comm[a0l][1])
|
||||
else: msg = karma_show(jid, nick, text)
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def karma_top(jid, nick, text, order):
|
||||
try: lim = int(text)
|
||||
except: lim = GT('karma_show_default_limit')
|
||||
if lim < 1: lim = 1
|
||||
elif lim > GT('karma_show_max_limit'): lim = GT('karma_show_max_limit')
|
||||
if order: stat = cur_execute_fetchall('select jid,karma from karma where room=%s order by karma',(jid,))
|
||||
else: stat = cur_execute_fetchall('select jid,karma from karma where room=%s order by -karma',(jid,))
|
||||
if stat == None: return L('In this room karma is not changed!','%s/%s'%(jid,nick))
|
||||
msg, cnt = '', 1
|
||||
for tmp in stat:
|
||||
tmp2 = get_nick_by_jid(jid, tmp[0])
|
||||
if tmp2:
|
||||
msg += '\n%s. %s\t%s' % (cnt,tmp2,karma_val(int(tmp[1])))
|
||||
cnt += 1
|
||||
if cnt > lim: break
|
||||
if len(msg): return L('Top karma: %s','%s/%s'%(jid,nick)) % msg
|
||||
else: return L('Karma for members is present not changed!','%s/%s'%(jid,nick))
|
||||
|
||||
def karma_size_wrong(room):
|
||||
k_size = int(config_prefs['karma_limit_size'][3])
|
||||
put_config(jid,'karma_limit_size',k_size)
|
||||
return k_size
|
||||
|
||||
def karma_get_limit(room,nick):
|
||||
room = getRoom(room)
|
||||
(acclvl, jid) = get_level(room,nick)
|
||||
if acclvl >= 7: return -1,-1
|
||||
k_log = cur_execute_fetchone('select log from karma_limits where room=%s and jid=%s',(room,getRoom(jid)))
|
||||
k_size = get_config(room,'karma_limit_size')
|
||||
if ''.join(re.findall('[-0-9, []]*', k_size)) != k_size: k_size = karma_size_wrong(room)
|
||||
if len(json.loads(k_size)) != 2: k_size = karma_size_wrong(room)
|
||||
k_size = json.loads(k_size)
|
||||
k_limit = [k_size[0],k_size[1]][acclvl >= 4]
|
||||
k_val = k_limit
|
||||
if k_log:
|
||||
k_log = json.loads(k_log[0])
|
||||
for tmp in k_log:
|
||||
if (time.time() - tmp) < 86400: k_val -= 1
|
||||
k_log.sort()
|
||||
else: k_log = [0]
|
||||
return k_val, k_limit, k_log[0]
|
||||
|
||||
def karma_show(jid, nick, text):
|
||||
if text == None or text == '' or text == nick: text, atext = nick, L('Your','%s/%s'%(jid,nick))
|
||||
else: atext = text
|
||||
karmajid = getRoom(get_level(jid,text)[1])
|
||||
if karmajid == 'None': return L('I\'m not sure, but %s not is here.','%s/%s'%(jid,nick)) % atext
|
||||
else:
|
||||
lim_text = ''
|
||||
if get_config(getRoom(jid),'karma_limit'):
|
||||
k_val = karma_get_limit(jid,text)[0]
|
||||
if k_val >= 0: lim_text = '. ' + L('Karma limit is %s','%s/%s'%(jid,nick)) % k_val
|
||||
stat = cur_execute_fetchone('select karma from karma where room=%s and jid=%s',(jid,karmajid))
|
||||
if stat == None: return L('%s have a clear karma','%s/%s'%(jid,nick)) % atext + lim_text
|
||||
else: return L('%s karma is %s','%s/%s'%(jid,nick)) % (atext, karma_val(int(stat[0]))) + lim_text
|
||||
|
||||
def karma_set(jid, nick, text):
|
||||
if cur_execute_fetchone('select * from commonoff where room=%s and cmd=%s',(jid,'karma')): return
|
||||
k_acc = get_level(jid,nick)[0]
|
||||
try:
|
||||
if '\n' in text: text,val = text.split('\n',1)
|
||||
else: text,val = text.split(' ',1)
|
||||
if k_acc >= 9:
|
||||
val = int(val)
|
||||
jid, karmajid = getRoom(jid), getRoom(get_level(jid,text)[1])
|
||||
if karmajid == getRoom(selfjid): return
|
||||
elif karmajid == 'None': return L('You can\'t change karma in outdoor conference!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
cur_execute('delete from karma where room=%s and jid=%s',(jid,karmajid))
|
||||
cur_execute('insert into karma values (%s,%s,%s)',(jid,karmajid,val))
|
||||
val = karma_val(val)
|
||||
return L('You changes %s\'s karma to %s','%s/%s'%(jid,nick)) % (text,val)
|
||||
else: return L('You can\'t change karma!','%s/%s'%(jid,nick))
|
||||
except: return L('incorrect digital parameter','%s/%s'%(jid,nick)).capitalize()
|
||||
|
||||
def karma_clear(jid, nick, text):
|
||||
if cur_execute_fetchone('select * from commonoff where room=%s and cmd=%s',(jid,'karma')): return
|
||||
k_acc = get_level(jid,nick)[0]
|
||||
if k_acc >= 9:
|
||||
if '\n' in text: (param,text) = text.split('\n',1)
|
||||
else: param = ''
|
||||
jid, karmajid = getRoom(jid), getRoom(get_level(jid,text)[1])
|
||||
if karmajid == getRoom(selfjid): return
|
||||
elif karmajid == 'None': return L('You can\'t change karma in outdoor conference!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
if param in ['','all','karma','limits']:
|
||||
if param in ['','all','karma']: cur_execute('delete from karma where room=%s and jid=%s',(jid,karmajid))
|
||||
if param in ['all','limits']: cur_execute('delete from karma_limits where room=%s and jid=%s',(jid,karmajid))
|
||||
return L('You clear karma for %s','%s/%s'%(jid,nick)) % text
|
||||
else: return L('Wrong arguments!','%s/%s'%(jid,nick))
|
||||
else: return L('You can\'t change karma!','%s/%s'%(jid,nick))
|
||||
|
||||
def karma_get_access(room,jid):
|
||||
stat = cur_execute_fetchone('select karma from karma where room=%s and jid=%s',(room,jid))
|
||||
if stat == None: return None
|
||||
if int(stat[0]) < GT('karma_limit'): return None
|
||||
return True
|
||||
|
||||
def karma_val(val): return ['%+2d' % val,'0'][val==0]
|
||||
|
||||
def karma_correct(room):
|
||||
def karma_correct_diff(vm,ac):
|
||||
lim_up = [GT('karma_discret_lim_up')]
|
||||
lim_dn = [GT('karma_discret_lim_dn')]
|
||||
kd,rs = GT('karma_discret'),[]
|
||||
def validate_mass(m):
|
||||
for t in range(0,len(m)-1):
|
||||
if abs(m[t]-m[t+1]) < kd or m[t] >= m[t+1]: return False
|
||||
return True
|
||||
def karma_blur_mass(vm):
|
||||
vm = lim_dn + vm + lim_up
|
||||
nm = []
|
||||
for t in range(0,len(vm)-2): nm.append(int((vm[t]+vm[t+1]+vm[t+2])/3))
|
||||
return nm
|
||||
while not validate_mass(vm): vm = karma_blur_mass(vm)
|
||||
for t in range(0,len(ac)): rs.append([vm[t],ac[t]])
|
||||
return rs
|
||||
tm,ac,vm,nm = config_group_karma[2],[],[],[]
|
||||
for t in tm:
|
||||
df = re.findall(r'karma_action_[0-9](.*)',t)
|
||||
if df:
|
||||
ac += df
|
||||
tvm = get_config_int(room,t)
|
||||
vm.append(tvm)
|
||||
nm.append(t)
|
||||
vm = karma_correct_diff(vm,ac)
|
||||
for t in range(0,len(nm)): put_config(room,nm[t],str(vm[t][0]))
|
||||
return vm
|
||||
|
||||
def karma_action_do(room,text,action):
|
||||
nick = getResourse(cur_execute_fetchone('select room from conference where room ilike %s',('%s/%%'%room,))[0])
|
||||
action = action.replace('ban','outcast')
|
||||
act = {'outcast':muc_affiliation,'none':muc_affiliation,'member':muc_affiliation,
|
||||
'kick':muc_role,'participant':muc_role,'visitor':muc_role,'moderator':muc_role}
|
||||
act[action]('chat',room,nick,'%s\n%s' % (text,get_config(room,'karma_action_reason')),action.replace('kick','none'),0)
|
||||
|
||||
def karma_change(room,jid,nick,type,text,value):
|
||||
global last_karma
|
||||
if type == 'chat': msg = L('You can\'t change karma in private!','%s/%s'%(room,nick))
|
||||
else:
|
||||
last_karma_text = last_karma.pop('%s/%s' % (room,jid), None)
|
||||
if last_karma_text:
|
||||
karma_text, karma_count = last_karma_text
|
||||
last_karma['%s/%s' % (room,jid)] = (karma_text, karma_count + 1)
|
||||
if karma_text == text and karma_count >= 2: return
|
||||
else: last_karma['%s/%s' % (room,jid)] = (text, 1)
|
||||
if cur_execute_fetchone('select * from commonoff where room=%s and cmd=%s',(room,'karma')): return
|
||||
if ': ' in text: (text,other) = text.split(': ',1)
|
||||
elif ', ' in text: (text,other) = text.split(', ',1)
|
||||
else: return
|
||||
if len(other) > 2 and get_config(getRoom(room),'karma_hard'): return
|
||||
k_acc = get_level(room,nick)[0]
|
||||
if k_acc < 0: return
|
||||
if k_acc >= 4 or karma_get_access(room,getRoom(jid)):
|
||||
jid, karmajid = getRoom(jid), getRoom(get_level(room,text)[1])
|
||||
if karmajid == getRoom(selfjid): return
|
||||
elif karmajid == 'None': msg = L('You can\'t change karma in outdoor conference!','%s/%s'%(room,nick))
|
||||
elif karmajid == jid: msg = L('You can\'t change own karma!','%s/%s'%(room,nick))
|
||||
elif get_config(getRoom(jid),'karma_limit') and karma_get_limit(room,nick)[0] == 0: msg = L('Karma limit is %s','%s/%s'%(room,nick)) % L('over','%s/%s'%(room,nick)) + '. ' + L('Please wait: %s','%s/%s'%(room,nick)) % un_unix(int(86400-(time.time() - karma_get_limit(room,nick)[2])),'%s/%s'%(room,nick))
|
||||
else:
|
||||
stat = cur_execute_fetchone('select last from karma_commiters where room=%s and jid=%s and karmajid=%s',(room,jid,karmajid))
|
||||
karma_valid, karma_time = None, int(time.time())
|
||||
if stat == None: karma_valid = True
|
||||
elif karma_time - int(stat[0]) >= GT('karma_timeout')[k_acc]: karma_valid = True
|
||||
if karma_valid:
|
||||
if k_acc < 7:
|
||||
k_log = cur_execute_fetchone('select log from karma_limits where room=%s and jid=%s',(room,jid))
|
||||
k_size = get_config(room,'karma_limit_size')
|
||||
if ''.join(re.findall('[-0-9, []]*', k_size)) != k_size: k_size = karma_size_wrong(room)
|
||||
if len(json.loads(k_size)) != 2: k_size = karma_size_wrong(room)
|
||||
k_size = json.loads(k_size)
|
||||
k_limit = [k_size[0],k_size[1]][k_acc >= 4]
|
||||
k_val = k_limit
|
||||
if k_log:
|
||||
k_log = json.loads(k_log[0])
|
||||
for tmp in k_log:
|
||||
if time.time() - tmp < 86400: k_val -= 1
|
||||
k_log = str([karma_time] + k_log[:k_limit-1])
|
||||
cur_execute('update karma_limits set log=%s where room=%s and jid=%s',(k_log,room,jid))
|
||||
else: cur_execute('insert into karma_limits values (%s,%s,%s)',(room,jid,'[%s]' % karma_time))
|
||||
if stat: cur_execute('update karma_commiters set last=%s where room=%s and jid=%s and karmajid=%s',(karma_time,room,jid,karmajid))
|
||||
else: cur_execute('insert into karma_commiters values (%s,%s,%s,%s)',(room,jid,karmajid,karma_time))
|
||||
stat = cur_execute_fetchone('select karma from karma where room=%s and jid=%s',(room,karmajid))
|
||||
if stat:
|
||||
stat = stat[0]+value
|
||||
cur_execute('delete from karma where room=%s and jid=%s',(room,karmajid))
|
||||
else: stat = value
|
||||
cur_execute('insert into karma values (%s,%s,%s)',(room,karmajid,stat))
|
||||
msg = L('You changes %s\'s karma to %s. Next time to change across: %s','%s/%s'%(room,nick)) % (text,karma_val(stat),un_unix(GT('karma_timeout')[k_acc],'%s/%s'%(room,nick)))
|
||||
pprint('karma change in %s for %s to %s' % (room,text,stat),'green')
|
||||
am = None
|
||||
if get_config(room,'karma_action'):
|
||||
kmass = karma_correct(room)
|
||||
for t in kmass:
|
||||
if t[0] <= 0 and stat <= t[0]:
|
||||
am = (room,text,t[1])
|
||||
break
|
||||
elif t[0] > 0 and stat >= t[0]: am = (room,text,t[1])
|
||||
if am:
|
||||
karma_action_do(*am)
|
||||
pprint('karma action in %s for %s is %s' % am,'bright_green')
|
||||
else: msg = L('Time from last change %s\'s karma is very small. Please wait %s','%s/%s'%(room,nick)) % (text,un_unix(int(stat[0])+GT('karma_timeout')[k_acc]-karma_time,'%s/%s'%(room,nick)))
|
||||
if get_config(room,'karma_limit'):
|
||||
k_val = karma_get_limit(room,nick)[0]
|
||||
if k_val >= 0: msg += '. ' + L('Karma limit is %s','%s/%s'%(room,nick)) % [L('over','%s/%s'%(room,nick)), k_val][k_val > 0]
|
||||
else: msg = L('You can\'t change karma!','%s/%s'%(room,nick))
|
||||
send_msg(type, room, nick, msg)
|
||||
|
||||
def karma_check(room,jid,nick,type,text):
|
||||
if getRoom(jid) == getRoom(selfjid): return
|
||||
if len(unicode(text)) < 5: return
|
||||
while len(text) and text[-1:] == ' ': text = text[:-1]
|
||||
if text[-3:] == ' +1':
|
||||
karma_change(room,jid,nick,type,text,1)
|
||||
return True
|
||||
elif text[-3:] == ' -1':
|
||||
karma_change(room,jid,nick,type,text,-1)
|
||||
return True
|
||||
|
||||
def karma_clear_log(room,jid,nick,type,arr):
|
||||
global last_karma
|
||||
if type == 'unavailable': last_karma.pop('%s/%s' % (room,jid), None)
|
||||
|
||||
global execute, message_control,presence_control
|
||||
|
||||
presence_control = [karma_clear_log]
|
||||
|
||||
message_act_control = [karma_check]
|
||||
|
||||
execute = [(3, 'karma', karma, 2, 'Karma.\nkarma [show] nick\nkarma top+|- [count]\nFor change karma: nick: +1\nnick: -1')]
|
||||
52
plugins/kinopoisk.py
Normal file
52
plugins/kinopoisk.py
Normal file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) Vit@liy <vitaliy@root.ua> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
kinopoisk_error_string = '<META HTTP-EQUIV="Pragma" CONTENT="no-cache">'
|
||||
|
||||
def kinopoisk(type, jid, nick, text):
|
||||
text=text.strip()
|
||||
if len(text) > 2:
|
||||
query=urllib.quote(text.encode('cp1251'))
|
||||
data = html_encode(load_page('http://m.kinopoisk.ru/search/'+query))
|
||||
if kinopoisk_error_string in data: msg = unhtml_hard(re.findall(kinopoisk_error_regexp,data,re.I+re.U+re.S)[0])
|
||||
else:
|
||||
temp_urls = re.findall('<a href="http://m.kinopoisk.ru/movie/(\d+?)/">(.+?)</a>', data)
|
||||
if temp_urls:
|
||||
msg = L('Found:','%s/%s'%(jid,nick))
|
||||
for n, t_u in enumerate(temp_urls):
|
||||
rs = ''
|
||||
if n < 3:
|
||||
try:
|
||||
r = load_page('http://www.kinopoisk.ru/rating/%s.xml' % t_u[0])
|
||||
r = re.findall('>([\.\d]+?)<', r)
|
||||
rs = ' (KP: %s / IMDB: %s)' % (r[0], r[1])
|
||||
except:
|
||||
pass
|
||||
msg += '\nhttp://www.kinopoisk.ru/film/%s/ - %s%s' % (t_u[0], t_u[1], rs)
|
||||
else: msg = L('Not found!','%s/%s'%(jid,nick))
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type,jid,nick,msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(0, 'film', kinopoisk, 2, 'Search in www.kinopoisk.ru. Example:\nfilm film_name')]
|
||||
47
plugins/known.py
Normal file
47
plugins/known.py
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def known(type, jid, nick, text):
|
||||
count = 10
|
||||
if '\n' in text:
|
||||
try:
|
||||
t_count = text.split('\n')[1].strip().lower()
|
||||
if t_count == 'all': count = 0
|
||||
else: count = int(t_count)
|
||||
except: pass
|
||||
text = text.split('\n',1)[0]
|
||||
if not text.strip(): text = nick
|
||||
real_jid = cur_execute_fetchone('select jid from age where room=%s and (nick=%s or jid=%s) order by status,-time',(jid,text,text.lower()))
|
||||
if real_jid:
|
||||
if count: lst = cur_execute_fetchall('select nick from age where room=%s and jid=%s and nick!=%s order by status,-time limit %s',(jid,real_jid[0],text,count))
|
||||
else: lst = cur_execute_fetchall('select nick from age where room=%s and jid=%s and nick!=%s order by status,-time',(jid,real_jid[0],text))
|
||||
if lst: nicks = ', '.join([t[0] for t in lst])
|
||||
else: nicks = text
|
||||
if text == nick: msg = '%s %s' % (L('I know you as:','%s/%s'%(jid,nick)),nicks)
|
||||
else: msg = '%s %s' % (L('I know %s as:','%s/%s'%(jid,nick)) % text,nicks)
|
||||
else: msg = L('Not found!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'known', known, 2, 'Show user\'s nick changes.\nknown <nick>\n[count|all]')]
|
||||
208
plugins/lastfm.py
Normal file
208
plugins/lastfm.py
Normal file
@@ -0,0 +1,208 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
global execute, lf_api, lfm_url
|
||||
|
||||
lfm_url = 'http://ws.audioscrobbler.com/2.0/'
|
||||
|
||||
def last_text_cnt(text,c):
|
||||
text = reduce_spaces_all(text).split(' ')
|
||||
try: cnt = int(text[1])
|
||||
except: cnt = GT('lastfm_max_limit')
|
||||
cnt += c
|
||||
text = text[0]
|
||||
return text,cnt
|
||||
|
||||
def last_check_ascii(type, jid, nick, text):
|
||||
for tmp in text:
|
||||
if tmp > '~' or tmp < ' ':
|
||||
send_msg(type, jid, nick, L('Error!','%s/%s'%(jid,nick)))
|
||||
return True
|
||||
return None
|
||||
|
||||
def last_time_short(tm):
|
||||
tm = time.localtime(tm)
|
||||
tnow = time.localtime()
|
||||
if tm[0] != tnow[0]: form = '%d.%m.%Y %H:%M'
|
||||
elif tm[1]!=tnow[1] or tm[2]!=tnow[2]: form = '%d.%m %H:%M'
|
||||
else: form = '%H:%M'
|
||||
return str(time.strftime(form,tm))
|
||||
|
||||
def last_date_now(body):
|
||||
if 'nowplaying=\"true\"' in body: return 'now'
|
||||
else:
|
||||
try: return last_time_short(int(get_subtag(get_tag_full(body,'date'),'uts')))
|
||||
except: return 'Unknown'
|
||||
|
||||
def lastonetrack(type, jid, nick, text):
|
||||
if not text: text = nick
|
||||
if last_check_ascii(type, jid, nick, text): return
|
||||
ms = lf_api('user.getrecenttracks',text, '<track')
|
||||
if len(ms): cnt = len(ms)
|
||||
else: cnt = 0
|
||||
if cnt >=2: msg = L('Last track %s: %s - %s %s','%s/%s'%(jid,nick)) % (text,get_tag(ms[1],'artist'),get_tag(ms[1],'name'),'['+last_date_now(ms[1])+']')
|
||||
else: msg = L('Unavailable!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def lf_api(method, user, splitter):
|
||||
user = reduce_spaces_all(user.lower().encode('utf-8').replace('\\x','%')).replace(' ','%20')
|
||||
link = '%s?method=%s&user=%s&api_key=%s' % (lfm_url,method,user,GT('lfm_api'))
|
||||
return rss_replace(html_encode(load_page(link))).split(splitter)
|
||||
|
||||
def lasttracks(type, jid, nick, text):
|
||||
if not text: text = nick
|
||||
if last_check_ascii(type, jid, nick, text): return
|
||||
text,cnt = last_text_cnt(text,1)
|
||||
ms = lf_api('user.getrecenttracks',text, '<track')
|
||||
msg = L('Last tracks %s:','%s/%s'%(jid,nick)) % text
|
||||
for a in ms[1:cnt]: msg += '\n[%s] %s - %s' % (last_date_now(a),get_tag(a,'artist'),get_tag(a,'name'))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def lastfriends(type, jid, nick, text):
|
||||
if not text: text = nick
|
||||
if last_check_ascii(type, jid, nick, text): return
|
||||
ms = lf_api('user.getfriends',text, '<user')
|
||||
msg = L('Friends %s:','%s/%s'%(jid,nick)) % text
|
||||
for a in ms[1:]:
|
||||
rn = get_tag(a,'realname')
|
||||
if rn: msg += ' %s (%s),' % (get_tag(a,'name'),rn)
|
||||
else: msg += ' %s,' % get_tag(a,'name')
|
||||
msg = msg[:-1]
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def lastloved(type, jid, nick, text):
|
||||
if not text: text = nick
|
||||
if last_check_ascii(type, jid, nick, text): return
|
||||
text,cnt = last_text_cnt(text,1)
|
||||
ms = lf_api('user.getlovedtracks',text, '<track')
|
||||
msg = L('Loved tracks %s:','%s/%s'%(jid,nick)) % text
|
||||
for a in ms[1:cnt]: msg += '\n[%s] %s - %s' % (last_date_now(a),get_tag(a.split('<artist')[1],'name'),get_tag(a,'name'))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def lastneighbours(type, jid, nick, text):
|
||||
if not text: text = nick
|
||||
if last_check_ascii(type, jid, nick, text): return
|
||||
text,cnt = last_text_cnt(text,1)
|
||||
ms = lf_api('user.getneighbours',text, '<user')
|
||||
msg = L('Neighbours %s:','%s/%s'%(jid,nick)) % text
|
||||
for a in ms[1:cnt]: msg += '\n%s - %s' % (get_tag(a,'match'),get_tag(a,'name'))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def lastplaylist(type, jid, nick, text):
|
||||
if not text: text = nick
|
||||
if last_check_ascii(type, jid, nick, text): return
|
||||
text,cnt = last_text_cnt(text,2)
|
||||
ms = lf_api('user.getplaylists',text, '<playlist')
|
||||
msg = L('Playlists %s:','%s/%s'%(jid,nick)) % text
|
||||
for a in ms[2:cnt]: msg += '\n[%s] %s (%s) - %s - %s' % (get_tag(a,'id'),get_tag(a,'title'),get_tag(a,'description'),get_tag(a,'size'),get_tag(a,'duration'))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def topalbums(type, jid, nick, text):
|
||||
if not text: text = nick
|
||||
if last_check_ascii(type, jid, nick, text): return
|
||||
text,cnt = last_text_cnt(text,1)
|
||||
ms = lf_api('user.gettopalbums',text, '<album')
|
||||
msg = L('Top albums %s:','%s/%s'%(jid,nick)) % text
|
||||
for a in ms[1:cnt]: msg += '\n[%s] %s - %s' % (get_tag(a,'playcount'),get_tag(a.split('<artist')[1],'name'),get_tag(a,'name'))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def topartists(type, jid, nick, text):
|
||||
if not text: text = nick
|
||||
if last_check_ascii(type, jid, nick, text): return
|
||||
text,cnt = last_text_cnt(text,1)
|
||||
ms = lf_api('user.gettopartists',text, '<artist')
|
||||
msg = L('Top artists %s:','%s/%s'%(jid,nick)) % text
|
||||
for a in ms[1:cnt]: msg += '\n[%s] %s' % (get_tag(a,'playcount'),get_tag(a,'name'))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def toptags(type, jid, nick, text):
|
||||
if not text: text = nick
|
||||
if last_check_ascii(type, jid, nick, text): return
|
||||
text,cnt = last_text_cnt(text,1)
|
||||
ms = lf_api('user.gettoptags',text, '<tag')
|
||||
msg = L('Top tags %s:','%s/%s'%(jid,nick)) % text
|
||||
for a in ms[1:cnt]: msg += '\n[%s] %s - %s' % (get_tag(a,'count'),get_tag(a,'name'),get_tag(a,'url'))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def toptracks(type, jid, nick, text):
|
||||
if not text: text = nick
|
||||
if last_check_ascii(type, jid, nick, text): return
|
||||
text,cnt = last_text_cnt(text,1)
|
||||
ms = lf_api('user.gettoptracks',text, '<track')
|
||||
if cnt > len(ms): cnt = len(ms)
|
||||
msg = L('Top tracks %s:','%s/%s'%(jid,nick)) % text
|
||||
for a in ms[1:cnt]:
|
||||
b = a.split('<artist')
|
||||
msg += '\n[%s] %s - %s' % (get_tag(a,'playcount'),get_tag(b[1],'name'),get_tag(a,'name'))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def tasteometer(type, jid, nick, text):
|
||||
if not text: text = nick
|
||||
if last_check_ascii(type, jid, nick, text): return
|
||||
text = reduce_spaces_all(text.lower().encode('utf-8').replace('\\x','%')).split(' ',1)
|
||||
try: (user1,user2) = text
|
||||
except:
|
||||
send_msg(type, jid, nick, L('Need two users','%s/%s'%(jid,nick)))
|
||||
return
|
||||
link = '%s?method=tasteometer.compare&type1=user&type2=user&value1=%s&value2=%s&api_key=%s' % (lfm_url,user1,user2,GT('lfm_api'))
|
||||
lfxml = html_encode(load_page(link))
|
||||
scor = get_tag(lfxml,'score')
|
||||
try: scor = float(scor)
|
||||
except: scor = 0
|
||||
if scor <= 0: msg = L('Tastes of %s and %s - soo different!','%s/%s'%(jid,nick)) % (user1,user2)
|
||||
else:
|
||||
msg,msg2 = L('Match tastes of %s and %s - %s','%s/%s'%(jid,nick)) % (user1,user2,str(int(scor*100))+'%'),''
|
||||
lfxml = lfxml.split('<artist')
|
||||
cnt = len(lfxml)
|
||||
for a in lfxml[2:cnt]: msg2 += '%s, ' % get_tag(a,'name')
|
||||
if len(msg2): msg += '\n%s' % L('Artists: %s','%s/%s'%(jid,nick)) % msg2[:-2]
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def no_api(type, jid, nick): send_msg(type, jid, nick, L('Not found LastFM api','%s/%s'%(jid,nick)))
|
||||
|
||||
exec_yes = [(3, 'lasttracks', lasttracks, 2, 'Last scrobled tracks'),
|
||||
(3, 'last', lastonetrack, 2, 'Last scrobled track'),
|
||||
(3, 'lastfriends', lastfriends, 2, 'Last friends'),
|
||||
(3, 'lastloved', lastloved, 2, 'Last loved tracks'),
|
||||
(3, 'lastneighbours', lastneighbours, 2, 'Last neighbours'),
|
||||
(3, 'lastplaylist', lastplaylist, 2, 'Last playlist'),
|
||||
(3, 'topalbums', topalbums, 2, 'Top albums'),
|
||||
(3, 'topartists', topartists, 2, 'Top artists'),
|
||||
(3, 'toptags', toptags, 2, 'Top tags'),
|
||||
(3, 'toptracks', toptracks, 2, 'Top tracks'),
|
||||
(3, 'tasteometer', tasteometer, 2, 'Music tastes')]
|
||||
|
||||
exec_no = [(3, 'lasttracks', no_api, 1, 'Not found LastFM api'),
|
||||
(3, 'last', no_api, 1, 'Not found LastFM api'),
|
||||
(3, 'lastfriends', no_api, 1, 'Not found LastFM api'),
|
||||
(3, 'lastloved', no_api, 1, 'Not found LastFM api'),
|
||||
(3, 'lastneighbours', no_api, 1, 'Not found LastFM api'),
|
||||
(3, 'lastplaylist', no_api, 1, 'Not found LastFM api'),
|
||||
(3, 'topalbums', no_api, 1, 'Not found LastFM api'),
|
||||
(3, 'topartists', no_api, 1, 'Not found LastFM api'),
|
||||
(3, 'toptags', no_api, 1, 'Not found LastFM api'),
|
||||
(3, 'toptracks', no_api, 1, 'Not found LastFM api'),
|
||||
(3, 'tasteometer', no_api, 1, 'Not found LastFM api')]
|
||||
|
||||
execute = [exec_no,exec_yes][len(GT('lfm_api')) >= 30]
|
||||
|
||||
243
plugins/logger.py
Normal file
243
plugins/logger.py
Normal file
@@ -0,0 +1,243 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# Copyright (C) Vit@liy <vitaliy@root.ua> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
# translate: chat_log_join,away_log_join,xa_log_join,dnd_log_join,online_log_join,chat_log_change,away_log_change,xa_log_change,dnd_log_change,online_log_change
|
||||
|
||||
smile_dictionary = {}
|
||||
last_log_file = {}
|
||||
last_log_presence = {}
|
||||
log_header = ['','<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><link href="%s" rel="stylesheet" type="text/css" /><title>\n' % logs_css_path][GT('html_logs_enable')]
|
||||
|
||||
if not os.path.exists(log_folder % ''): os.mkdir(log_folder % '')
|
||||
if not os.path.exists(public_log % ''): os.mkdir(public_log % '')
|
||||
if not os.path.exists(system_log % '') and GT('syslogs_enable'): os.mkdir(system_log % '')
|
||||
|
||||
for smilepack in smiles_dirs_case:
|
||||
smile_dictionary[smilepack] = {}
|
||||
if smilepack[0] != '.':
|
||||
data = readfile(os.path.join(sm_f,smilepack,smile_descriptor))
|
||||
for icon in re.findall('<icon>((?:\s|.)+?)</icon>', data):
|
||||
img = re.search('<object mime="image/.+?">(.+?)</object>', icon).group(1)
|
||||
for pattern in re.findall('<text.*?>(.+?)</text>', icon): smile_dictionary[smilepack][pattern.replace('<','<').replace('>','>')] = img
|
||||
|
||||
def smile_replace(room, text):
|
||||
global smile_dictionary
|
||||
smilepack = smiles_dirs_case[smiles_dirs.index(get_config(getRoom(room),'smiles'))]
|
||||
newtext = ' %s ' % text.replace('<br/>',' <br/> ').replace(' ', ' ')
|
||||
for smile in sorted(smile_dictionary[smilepack], key = lambda x: len(x))[::-1]:
|
||||
tmp_smile = ' %s ' % html_escape(smile.decode('utf-8')).replace('&', '&')
|
||||
while tmp_smile in newtext:
|
||||
sm_tag = ' <img src="%s" alt="%s"> ' % ('../../../%s/%s/%s' % (smile_folder, smilepack, smile_dictionary[smilepack][smile]),smile.decode('utf-8'))
|
||||
newtext = newtext.replace(tmp_smile, sm_tag)
|
||||
return newtext.replace(' <br/>','<br/>').replace('<br/> ','<br/>')[1:-1]
|
||||
|
||||
def initial_log_users(room,ott):
|
||||
txt = []
|
||||
for tmp in megabase:
|
||||
if tmp[0] == room: txt.append(tmp[1])
|
||||
txt = non_case_sort(txt)
|
||||
log_body = ['[%s] ' % ott,'<p><a id="%s" name="%s" href="#%s" class="time">%s</a> ' % (ott,ott,ott,ott)][GT('html_logs_enable')]
|
||||
log_body += ['*** ','<span class="status">'][GT('html_logs_enable')]
|
||||
log_body += L('Users: %s (%s)') % (', '.join(txt),len(txt))
|
||||
log_body += '\n%s' % ['','</span></p>'][GT('html_logs_enable')]
|
||||
return log_body
|
||||
|
||||
def append_message_to_log(room,jid,nick,type,text):
|
||||
global public_log, system_log
|
||||
lr = cur_execute_fetchone('select * from log_rooms where room=%s;',(room,))
|
||||
if lr:
|
||||
if GT('html_logs_enable'): text,jid,nick = html_escape(text).replace('\n','<br/>'), html_escape(jid), html_escape(nick)
|
||||
if type == 'groupchat' and text != 'None':
|
||||
if get_config(getRoom(room),'smiles') != 'off': ptext = smile_replace(room, text)
|
||||
else: ptext = text
|
||||
msg_logger(room,jid,nick,type,ptext,public_log)
|
||||
if type == 'chat': nick = 'chat >>> %s' % nick
|
||||
if GT('syslogs_enable'): msg_logger(room,jid,nick,type,text,system_log)
|
||||
|
||||
def write_log_with_end(curr_path,curr_file,log_body,log_he):
|
||||
global last_log_file
|
||||
if not os.path.isfile(curr_file):
|
||||
fl = open(curr_file, 'a')
|
||||
fl.write(log_he.encode('utf-8'))
|
||||
fl.write(log_body.encode('utf-8'))
|
||||
try:
|
||||
ll = last_log_file[curr_path]
|
||||
if os.path.isfile(ll):
|
||||
ender = ['\n','</div></div><br/>%s</body></html>' % GT('html_logs_end_text')][GT('html_logs_enable')]
|
||||
fle = open(ll, 'a')
|
||||
fle.write(ender.encode('utf-8'))
|
||||
fle.close()
|
||||
except: pass
|
||||
else:
|
||||
fl = open(curr_file, 'a')
|
||||
fl.write(log_body.encode('utf-8'))
|
||||
fl.close()
|
||||
last_log_file[curr_path] = curr_file
|
||||
|
||||
def msg_logger(room,jid,nick,type,text,logfile):
|
||||
if GT('chatlogs_logs_gmt'): lt = tuple(time.gmtime())
|
||||
else: lt = tuple(time.localtime())
|
||||
curr_path = logfile % room
|
||||
if not os.path.exists(curr_path): os.mkdir(curr_path)
|
||||
curr_path = '%s/%s' % (curr_path,lt[0])
|
||||
if not os.path.exists(curr_path): os.mkdir(curr_path)
|
||||
curr_path = '%s/%02d' % (curr_path,lt[1])
|
||||
if not os.path.exists(curr_path): os.mkdir(curr_path)
|
||||
curr_file = ['%s/%02d.txt','%s/%02d.html'][GT('html_logs_enable')] % (curr_path,lt[2])
|
||||
ott = onlytimeadd(lt)
|
||||
log_body = ['[%s] ' % ott,'<p><a id="%s" name="%s" href="#%s" class="time">%s</a> ' % (ott,ott,ott,ott)][GT('html_logs_enable')]
|
||||
if nick == '': log_body += ['*** %s\n','<span class="topic">%s</span></p>'][GT('html_logs_enable')] % text
|
||||
else:
|
||||
if text[:4] == '/me ': log_body += ['*%s %s\n','<span class="me">%s %s</span></p>\n'][GT('html_logs_enable')] % (nick,text[4:])
|
||||
else:
|
||||
if '<br/>' + ' '*8 in text:
|
||||
msg_type = '<span class="nick">%s: </span><span class="paste">%s</span></p>\n'
|
||||
if not text.startswith('<br/>'): text = '<br/>%s' % text
|
||||
text = text.replace(' '*8,'<span style="padding: 0px 16px;"> </span>')
|
||||
elif ' '*8 in text:
|
||||
no_tab_text,cnt = [],0
|
||||
for t in text.split('<br/>'):
|
||||
if not ' '*8 in t:
|
||||
no_tab_text.append(t)
|
||||
cnt += 1
|
||||
else: break
|
||||
text = '<br/>'.join(text.split('<br/>')[cnt:])
|
||||
no_tab_text = '<br/>'.join(no_tab_text)
|
||||
|
||||
msg_type = '<span class="nick">%s: </span><span class="text">' + no_tab_text + '%s</span></p>\n'
|
||||
|
||||
text = '<table border="0" class="text" cellpadding="0" cellspacing="0"><tr><td> %s' % text
|
||||
text = text.replace(' '*8,'</td><td> ')
|
||||
text = '%s</tr></table>' % text
|
||||
text = text.replace('<br/>','</td></tr><tr><td> ')
|
||||
|
||||
else: msg_type = '<span class="nick">%s: </span><span class="text">%s</span></p>\n'
|
||||
log_body += ['%s: %s\n',msg_type][GT('html_logs_enable')] % (nick,text)
|
||||
lht = '%s - %02d/%02d/%02d' % (room,lt[0],lt[1],lt[2])
|
||||
log_he = ['%s\t\thttp://isida-bot.com\n\n' % lht,log_header+lht+'</title></head><body><div class="main"><div class="top"><div class="heart"><a href="http://isida-bot.com">http://isida-bot.com</a></div><div class="conference">'+lht+'</div></div><div class="container">\n'][GT('html_logs_enable')]
|
||||
try: log_he += initial_log_users(room,ott) + ['[%s] ' % ott,'<p><a id="%s" name="%s" href="#%s" class="time">%s</a> ' % (ott,ott,ott,ott)][GT('html_logs_enable')] + ['*** %s\n','<span class="topic">%s</span></p>'][GT('html_logs_enable')] % [topics[room],html_escape(topics[room]).replace('\n','<br/>')][GT('html_logs_enable')]
|
||||
except: pass
|
||||
write_log_with_end(logfile+room,curr_file,log_body,log_he)
|
||||
|
||||
def append_presence_to_log(room,jid,nick,type,mass):
|
||||
global public_log, system_log
|
||||
lr = cur_execute_fetchone('select * from log_rooms where room=%s;',(room,))
|
||||
if lr:
|
||||
# (text, role, affiliation, exit_type, exit_message, show, priority, not_found)
|
||||
try: llp = [last_log_presence[room+jid+nick],None][type == 'unavailable']
|
||||
except: llp = None
|
||||
last_log_presence[room+jid+nick] = mass
|
||||
if mass == llp: return
|
||||
if GT('html_logs_enable'): jid,nick = html_escape(jid), html_escape(nick)
|
||||
presence_logger(room,jid,nick,type,mass,0,public_log)
|
||||
if GT('syslogs_enable'): presence_logger(room,jid,nick,type,mass,1,system_log)
|
||||
|
||||
def presence_logger(room,jid,nick,type,mass,mode,logfile):
|
||||
role,affiliation = [mass[1],html_escape(mass[1])][GT('html_logs_enable')], [mass[2],html_escape(mass[2])][GT('html_logs_enable')]
|
||||
if nick[:11] != '<temporary>' and role != 'None' and affiliation != 'None':
|
||||
text,exit_type = [mass[0],html_escape(mass[0])][GT('html_logs_enable')],mass[3]
|
||||
if GT('html_logs_enable') and text[:20] == '<br>&nbsp;': text = ' %s' % text[20:]#text = correct_html(text)
|
||||
try: em = mass[4].split('\r')[0]
|
||||
except: em = mass[4]
|
||||
exit_message,show = [em,html_escape(em)][GT('html_logs_enable')], [mass[5],html_escape(mass[5])][GT('html_logs_enable')]
|
||||
priority,not_found = mass[6],mass[7]
|
||||
if not_found == 1 and not GT('aff_role_logs_enable'): return
|
||||
if not_found == 2 and not GT('status_logs_enable'): return
|
||||
if GT('chatlogs_logs_gmt'): lt = tuple(time.gmtime())
|
||||
else: lt = tuple(time.localtime())
|
||||
curr_path = logfile % room
|
||||
if not os.path.exists(curr_path): os.mkdir(curr_path)
|
||||
curr_path = '%s/%s' % (curr_path,lt[0])
|
||||
if not os.path.exists(curr_path): os.mkdir(curr_path)
|
||||
curr_path = '%s/%02d' % (curr_path,lt[1])
|
||||
if not os.path.exists(curr_path): os.mkdir(curr_path)
|
||||
curr_file = ['%s/%02d.txt','%s/%02d.html'][GT('html_logs_enable')] % (curr_path,lt[2])
|
||||
ott = onlytimeadd(lt)
|
||||
log_body = ['[%s] ' % ott,'<p><a id="%s" name="%s" href="#%s" class="time">%s</a> ' % (ott,ott,ott,ott)][GT('html_logs_enable')]
|
||||
if type == 'unavailable':
|
||||
log_body += ['*** %s','<span class="unavailable">%s'][GT('html_logs_enable')] % nick
|
||||
if mode and jid != 'None': log_body += ' (%s)' % jid
|
||||
if len(exit_type): log_body += ' %s' % exit_type
|
||||
else: log_body += ' %s' % L('leave')
|
||||
if exit_message != '': log_body += ' (%s)' % exit_message
|
||||
if mode and '\r' in mass[4]: log_body += ', %s %s' % (L('Client:'),mass[4].split('\r')[1])
|
||||
log_body += '%s\n' % ['','</span></p>'][GT('html_logs_enable')]
|
||||
else:
|
||||
log_body += ['*** %s','<span class="status">%s'][GT('html_logs_enable')] % nick
|
||||
if not_found == 0:
|
||||
if mode and jid != 'None': log_body += ' (%s)' % jid
|
||||
log_body += ' %s %s' % (L('join as'),L("%s/%s" % (role,affiliation)))
|
||||
status_type = '%s_log_join'
|
||||
elif not_found == 1:
|
||||
log_body += ' %s %s' % (L('now is'),L("%s/%s" % (role,affiliation)))
|
||||
if exit_message: log_body += ' (%s)' % exit_message
|
||||
elif not_found == 2: status_type = '%s_log_change'
|
||||
if not_found == 0 or not_found == 2:
|
||||
status_mask = ' %s' if not_found else ', %s'
|
||||
if show != 'None': log_body += status_mask % L(status_type % show).replace(status_type % '','')
|
||||
else: log_body += status_mask % L(status_type % "online").replace(status_type % '','')
|
||||
if priority != 'None': log_body += ' [%s]' % priority
|
||||
else: log_body += ' [0]'
|
||||
if text != 'None': log_body += ' (%s)' % text
|
||||
log_body += '%s\n' % ['','</span></p>'][GT('html_logs_enable')]
|
||||
lht = '%s - %02d/%02d/%02d' % (room,lt[0],lt[1],lt[2])
|
||||
log_he = ['%s\t\thttp://isida-bot.com\n\n' % lht,log_header+lht+'</title></head><body><div class="main"><div class="top"><div class="heart"><a href="http://isida-bot.com">http://isida-bot.com</a></div><div class="conference">'+lht+'</div></div><div class="container">\n'][GT('html_logs_enable')]
|
||||
try: log_he += initial_log_users(room,ott) + ['[%s] ' % ott,'<p><a id="%s" name="%s" href="#%s" class="time">%s</a> ' % (ott,ott,ott,ott)][GT('html_logs_enable')] + ['*** %s\n','<span class="topic">%s</span></p>'][GT('html_logs_enable')] % [topics[room],html_escape(topics[room]).replace('\n','<br/>')][GT('html_logs_enable')]
|
||||
except: pass
|
||||
write_log_with_end(logfile+room,curr_file,log_body,log_he)
|
||||
|
||||
global execute
|
||||
|
||||
message_control = [append_message_to_log]
|
||||
presence_control = [append_presence_to_log]
|
||||
|
||||
def log_room(type, jid, nick, text):
|
||||
if type == 'groupchat': msg = L('This command available only in private!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
text = text.strip().lower().split(' ',1)
|
||||
hmode = text[0]
|
||||
try: hroom = text[1]
|
||||
except: hroom = jid
|
||||
if not hmode:
|
||||
if cur_execute_fetchone('select * from log_rooms where room=%s;',(hroom,)): msg = L('Logs for %s enabled.','%s/%s'%(jid,nick)) % hroom
|
||||
else: msg = L('Logs for %s disabled.','%s/%s'%(jid,nick)) % hroom
|
||||
elif hmode == 'show':
|
||||
lr = cur_execute_fetchall('select * from log_rooms;')
|
||||
if lr: msg = '%s\n%s' % (L('Logged conferences:','%s/%s'%(jid,nick)),'\n'.join([t[0] for t in lr]))
|
||||
else: msg = L('Logs are turned off in all conferences.','%s/%s'%(jid,nick))
|
||||
elif hmode == 'add':
|
||||
if not cur_execute_fetchall('select * from conference where room ilike %s;', ('%s/%%'%getRoom(hroom),)): msg = L('I am not in the %s','%s/%s'%(jid,nick)) % hroom
|
||||
elif cur_execute_fetchone('select * from log_rooms where room=%s;',(hroom,)): msg = L('Logs for %s already enabled.','%s/%s'%(jid,nick)) % hroom
|
||||
else:
|
||||
cur_execute('insert into log_rooms values (%s);',(hroom,))
|
||||
msg = L('Logs for %s enabled.','%s/%s'%(jid,nick)) % hroom
|
||||
elif hmode == 'del':
|
||||
if cur_execute_fetchone('select * from log_rooms where room=%s;',(hroom,)):
|
||||
cur_execute('delete from log_rooms where room=%s;',(hroom,))
|
||||
msg = L('Logs for %s disabled.','%s/%s'%(jid,nick)) % hroom
|
||||
else: msg = L('Logs for %s not enabled.','%s/%s'%(jid,nick)) % hroom
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
execute = [(9, 'log', log_room, 2, 'Logging history conference.\nlog [add|del|show][ room@conference.server.tld]')]
|
||||
1971
plugins/main.py
Normal file
1971
plugins/main.py
Normal file
File diff suppressed because it is too large
Load Diff
49
plugins/md5.py
Normal file
49
plugins/md5.py
Normal file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def md5body(type, jid, nick, text):
|
||||
if len(text): msg = hashlib.md5(text.encode('utf-8')).hexdigest()
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def hashbody(type, jid, nick, text):
|
||||
text = reduce_spaces_all(text)
|
||||
if not len(text): text = nick
|
||||
try: msg = hashes['%s/%s' % (jid,text)]
|
||||
except: msg = L('Nick %s not found!','%s/%s'%(jid,nick)) % text
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def findhash(type, jid, nick, text):
|
||||
text = reduce_spaces_all(text)
|
||||
if text:
|
||||
h = [t for t in hashes if hashes[t]==text]
|
||||
if h: msg = L('Found: %s','%s/%s'%(jid,nick)) % '\n%s' % '\n'.join(h)
|
||||
else: msg = L('Not found: %s','%s/%s'%(jid,nick)) % text
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'md5', md5body, 2, 'Calculate phrase md5 sum.'),
|
||||
(4, 'hashbody', hashbody, 2, 'Show presence-hash of nick'),
|
||||
(6, 'findhash', findhash, 2, 'Show room and nick by presence-hash')]
|
||||
251
plugins/muc.py
Normal file
251
plugins/muc.py
Normal file
@@ -0,0 +1,251 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
visitors_list = {}
|
||||
visitors_list_lock = False
|
||||
|
||||
# -------------- affiliation -----------------
|
||||
|
||||
def global_ban(type, jid, nick, text):
|
||||
text = text.lower()
|
||||
hroom = getRoom(jid)
|
||||
al = get_level(jid,nick)[0]
|
||||
if al == 9: af = 'owner'
|
||||
else: af = get_affiliation(jid,nick)
|
||||
if af != 'owner': msg = L('This command available only for conference owner!','%s/%s'%(jid,nick))
|
||||
elif text == 'show' and al == 9:
|
||||
ir = cur_execute_fetchone('select * from ignore_ban;')
|
||||
if len(ir): msg = '%s\n%s' % (L('Global ban is off in:','%s/%s'%(jid,nick)),'\n'.join([t[0] for t in ir]))
|
||||
else: msg = L('Global ban enable without limits!','%s/%s'%(jid,nick))
|
||||
elif text == 'del' and af == 'owner':
|
||||
if cur_execute_fetchone('select * from ignore_ban where room=%s' % (hroom,)): msg = L('Conference %s already deleted from global ban list!','%s/%s'%(jid,nick)) % hroom
|
||||
else:
|
||||
cur_execute('insert inro ignore_ban values (%s)' % (hroom,))
|
||||
msg = L('Conference %s has been deleted from global ban list!','%s/%s'%(jid,nick)) % hroom
|
||||
elif text == 'add' and af == 'owner':
|
||||
if cur_execute_fetchone('select * from ignore_ban where room=%s' % (hroom,)):
|
||||
cur_execute('delete from ignore_ban where room=%s' % (hroom,))
|
||||
msg = L('Conference %s has been added from global ban list!','%s/%s'%(jid,nick)) % hroom
|
||||
else: msg = L('Conference %s already exist in global ban list!','%s/%s'%(jid,nick)) % hroom
|
||||
else:
|
||||
if al == 9:
|
||||
if cur_execute_fetchone('select * from ignore_ban where room=%s' % (hroom,)): msg = L('Your conference will be ignored for global ban!','%s/%s'%(jid,nick))
|
||||
elif '@' not in text or '.' not in text: msg = L('I need jid!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
reason = L('banned global by %s from %s','%s/%s'%(jid,nick)) % (nick, jid)
|
||||
br = [t[0] for t in cur_execute_fetchall("select room from conference where split_part(room,'/',1) not in (select room from ignore_ban as igb);")]
|
||||
for tmp in br:
|
||||
i = xmpp.Node('iq', {'id': get_id(), 'type': 'set', 'to':getRoom(tmp)}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'affiliation':'outcast', 'jid':unicode(text)},[xmpp.Node('reason',{},reason)])])])
|
||||
sender(i)
|
||||
time.sleep(0.1)
|
||||
msg = L('jid %s has been banned in %s conferences.','%s/%s'%(jid,nick)) % (text, len(br))
|
||||
else: msg = L('Command temporary blocked!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def muc_tempo_ban(type, jid, nick, text):
|
||||
text,mute = text.strip().split('\n'),False
|
||||
if text:
|
||||
cmd, par = text[0].lower().split(' ',1) if ' ' in text[0] else (text[0].lower().split(' ',1)[0],'')
|
||||
if cmd == 'show':
|
||||
if not par: par = '%'
|
||||
tb = cur_execute_fetchall('select jid,time from tmp_ban where room=%s and jid ilike %s',(jid,par))
|
||||
if tb: msg = L('Found: %s','%s/%s'%(jid,nick)) % '\n%s' % '\n'.join([['%s\t%s' % (ub[0],un_unix(ub[1]-int(time.time()),'%s/%s'%(jid,nick))),'%s\t< %s' % (ub[0],un_unix(GT('schedule_time'),'%s/%s'%(jid,nick)))][ub[1] < int(time.time())] for ub in tb])
|
||||
else: msg = L('Not found.','%s/%s'%(jid,nick))
|
||||
|
||||
elif cmd == 'del':
|
||||
if par:
|
||||
tb = cur_execute_fetchall('select jid,time from tmp_ban where room=%s and jid ilike %s',(jid,par))
|
||||
if tb:
|
||||
msg = L('Removed: %s','%s/%s'%(jid,nick)) % '\n%s' % '\n'.join([['%s\t%s' % (ub[0],un_unix(ub[1]-int(time.time()),'%s/%s'%(jid,nick))),'%s\t< %s' % (ub[0],un_unix(GT('schedule_time'),'%s/%s'%(jid,nick)))][ub[1] < int(time.time())] for ub in tb])
|
||||
for ub in tb: sender(xmpp.Node('iq', {'id': get_id(), 'type': 'set', 'to':jid}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'affiliation':'none', 'jid':getRoom(unicode(ub[0]))},[])])]))
|
||||
cur_execute('delete from tmp_ban where room=%s and jid ilike %s',(jid,par))
|
||||
else: msg = L('Not found.','%s/%s'%(jid,nick))
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
|
||||
else:
|
||||
try: ban_time = int(text[1][:-1]) * {'s':1, 'm':60, 'h':3600, 'd':86400}[text[1][-1].lower()]
|
||||
except: ban_time = None
|
||||
if ban_time:
|
||||
reason = ' '.join(text[2:])
|
||||
if not reason: reason = L('No reason!','%s/%s'%(jid,nick))
|
||||
reason = L('ban on %s since %s because: %s','%s/%s'%(jid,nick)) % (un_unix(ban_time,'%s/%s'%(jid,nick)), timeadd(tuple(time.localtime())), reason)
|
||||
who,msg = text[0],L('done','%s/%s'%(jid,nick))
|
||||
try: whojid = getRoom([t[4] for t in megabase if t[0]==jid and t[1]==who][0])
|
||||
except: whojid = None
|
||||
if not whojid:
|
||||
fnd = cur_execute_fetchall('select jid from age where room=%s and (nick=%s or jid=%s) group by jid',(jid,who,who))
|
||||
if len(fnd) == 1: whojid = getRoom(fnd[0][0])
|
||||
elif len(fnd) > 1: msg = L('I seen different people with this nick!','%s/%s'%(jid,nick))
|
||||
else: msg,whojid = L('I don\'n know %s, and use as is!','%s/%s'%(jid,nick)) % who,who
|
||||
if whojid:
|
||||
sender(xmpp.Node('iq', {'id': get_id(), 'type': 'set', 'to':jid}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'affiliation':'outcast', 'jid':unicode(whojid)},[xmpp.Node('reason',{},reason)])])]))
|
||||
was_banned = cur_execute_fetchone('select time from tmp_ban where room=%s and jid=%s;',(jid,whojid))
|
||||
if was_banned:
|
||||
cur_execute('delete from tmp_ban where room=%s and jid=%s;',(jid,whojid))
|
||||
ban_tm = was_banned[0]-int(time.time())
|
||||
if ban_tm > 0: ban_nm = L('old ban time is %s','%s/%s'%(jid,nick)) % un_unix(ban_tm,'%s/%s'%(jid,nick))
|
||||
else: ban_nm = L('just passed!','%s/%s'%(jid,nick))
|
||||
msg = L('Updated: %s','%s/%s'%(jid,nick)) % ban_nm
|
||||
cur_execute('insert into tmp_ban values (%s,%s,%s)',(jid,whojid,ban_time+int(time.time())))
|
||||
if who == nick: mute = True
|
||||
else: msg = L('Time format error!','%s/%s'%(jid,nick))
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
|
||||
if not mute: send_msg(type, jid, nick, msg)
|
||||
|
||||
def muc_ban(type, jid, nick,text): muc_affiliation(type, jid, nick, text, 'outcast',0)
|
||||
def muc_banjid(type, jid, nick,text): muc_affiliation(type, jid, nick, text, 'outcast',1)
|
||||
def muc_none(type, jid, nick,text): muc_affiliation(type, jid, nick, text, 'none',0)
|
||||
def muc_nonejid(type, jid, nick,text): muc_affiliation(type, jid, nick, text, 'none',1)
|
||||
def muc_member(type, jid, nick,text): muc_affiliation(type, jid, nick, text, 'member',0)
|
||||
def muc_memberjid(type, jid, nick,text): muc_affiliation(type, jid, nick, text, 'member',1)
|
||||
|
||||
def muc_affiliation(type, jid, nick, text, aff, is_jid):
|
||||
nowname = get_xnick(jid)
|
||||
xtype = get_xtype(jid)
|
||||
if xtype == 'owner':
|
||||
if is_start: return
|
||||
else: send_msg(type, jid, nick, L('Command is locked!','%s/%s'%(jid,nick)))
|
||||
elif len(text):
|
||||
skip = None
|
||||
if '\n' in text: who, reason = text.split('\n',1)[0], text.split('\n',1)[1]
|
||||
else: who, reason = text, []
|
||||
if reason: reason = [xmpp.Node('reason',{},reason)]
|
||||
whojid = [unicode(get_level(jid,who)[1]),who][is_jid]
|
||||
if whojid != 'None': sender(xmpp.Node('iq', {'id': get_id(), 'type': 'set', 'to':jid}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'affiliation':aff, 'jid':whojid},reason)])]))
|
||||
else: send_msg(type, jid, nick, L('I don\'t know %s','%s/%s'%(jid,nick)) % who)
|
||||
else: send_msg(type, jid, nick, L('What?','%s/%s'%(jid,nick)))
|
||||
|
||||
def muc_ban_past(type, jid, nick,text): muc_affiliation_past(type, jid, nick, text, 'outcast')
|
||||
def muc_none_past(type, jid, nick,text): muc_affiliation_past(type, jid, nick, text, 'none')
|
||||
def muc_member_past(type, jid, nick,text): muc_affiliation_past(type, jid, nick, text, 'member')
|
||||
|
||||
def muc_affiliation_past(type, jid, nick, text, aff):
|
||||
nowname = get_xnick(jid)
|
||||
xtype = get_xtype(jid)
|
||||
if xtype == 'owner':
|
||||
if is_start: return
|
||||
else: msg, text = L('Command is locked!','%s/%s'%(jid,nick)), ''
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
if len(text):
|
||||
skip = None
|
||||
if '\n' in text: who, reason = text.split('\n',1)[0], text.split('\n',1)[1]
|
||||
else: who, reason = text, []
|
||||
if reason: reason = [xmpp.Node('reason',{},reason)]
|
||||
fnd = cur_execute_fetchall('select jid from age where room=%s and (nick=%s or jid=%s) group by jid',(jid,who,who))
|
||||
if len(fnd) == 1: msg, whojid = L('done','%s/%s'%(jid,nick)), getRoom(unicode(fnd[0][0]))
|
||||
elif len(fnd) > 1:
|
||||
whojid = getRoom(get_level(jid,who)[1])
|
||||
if whojid != 'None': msg = L('done','%s/%s'%(jid,nick))
|
||||
else: msg, skip = L('I seen some peoples with this nick. Get more info!','%s/%s'%(jid,nick)), True
|
||||
else:
|
||||
msg = L('I don\'n know %s, and use as is!','%s/%s'%(jid,nick)) % who
|
||||
whojid = who
|
||||
else: skip = True
|
||||
if skip: send_msg(type, jid, nick, msg)
|
||||
else:
|
||||
i = xmpp.Node('iq', {'id': get_id(), 'type': 'set', 'to':jid}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'affiliation':aff, 'jid':unicode(whojid)},reason)])])
|
||||
sender(i)
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def muc_kick(type, jid, nick, text): muc_role(type, jid, nick, text, 'none',1)
|
||||
def muc_participant(type, jid, nick, text): muc_role(type, jid, nick, text, 'participant',1)
|
||||
def muc_visitor(type, jid, nick, text): muc_role(type, jid, nick, text, 'visitor',1)
|
||||
def muc_moderator(type, jid, nick, text): muc_role(type, jid, nick, text, 'moderator',1)
|
||||
|
||||
def muc_role(type, jid, nick, text, role, unused):
|
||||
nowname = get_xnick(jid)
|
||||
xtype = get_xtype(jid)
|
||||
if xtype == 'owner':
|
||||
if is_start: return
|
||||
else: send_msg(type, jid, nick, L('Command is locked!','%s/%s'%(jid,nick)))
|
||||
elif len(text):
|
||||
skip = None
|
||||
if '\n' in text: who, reason = text.split('\n',1)[0], text.split('\n',1)[1]
|
||||
else: who, reason = text, []
|
||||
if reason: reason = [xmpp.Node('reason',{},reason)]
|
||||
whojid = unicode(get_level(jid,who)[1])
|
||||
if whojid != 'None': sender(xmpp.Node('iq', {'id': get_id(), 'type': 'set', 'to':jid}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'role':role, 'nick':who},reason)])]))
|
||||
else: send_msg(type, jid, nick, L('I don\'t know %s','%s/%s'%(jid,nick)) % who)
|
||||
else: send_msg(type, jid, nick, L('What?','%s/%s'%(jid,nick)))
|
||||
|
||||
def check_unban():
|
||||
tt = int(time.time())
|
||||
ul = cur_execute_fetchall('select room,jid from tmp_ban where time<%s;',(tt,))
|
||||
if ul:
|
||||
for t in ul: sender(xmpp.Node('iq', {'id': get_id(), 'type': 'set', 'to':t[0]}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'affiliation':'none', 'jid':getRoom(unicode(t[1]))},[])])]))
|
||||
cur_execute('delete from tmp_ban where time<%s;',(tt,))
|
||||
|
||||
def visitors_list_lock_wait():
|
||||
while visitors_list_lock: time.sleep(0.05)
|
||||
return True
|
||||
|
||||
def check_visitor():
|
||||
global visitors_list, visitors_list_lock
|
||||
visitors_list_lock = visitors_list_lock_wait()
|
||||
ITT = int(time.time())
|
||||
for t in visitors_list:
|
||||
room = t.split('/')[0]
|
||||
VISITOR_ACT = get_config(getRoom(room),'visitor_action')
|
||||
if VISITOR_ACT != 'off' and ITT > visitors_list[t]:
|
||||
reason = [xmpp.Node('reason',{},L('Too long was without voice!',t))]
|
||||
if VISITOR_ACT == 'kick': sender(xmpp.Node('iq', {'id': get_id(), 'type': 'set', 'to':room}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'role':'none', 'nick':t.split('/',1)[1]},reason)])]))
|
||||
else: sender(xmpp.Node('iq', {'id': get_id(), 'type': 'set', 'to':room}, payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'affiliation':'outcast', 'jid':get_jid_by_nick(t.split('/',1))},reason)])]))
|
||||
visitors_list_lock = False
|
||||
|
||||
def visitor_presence(room,jid,nick,type,mass):
|
||||
global visitors_list, visitors_list_lock
|
||||
if getRoom(jid) == getRoom(Settings['jid']): return
|
||||
if type == 'error': return
|
||||
elif type == 'unavailable':
|
||||
visitors_list_lock = visitors_list_lock_wait()
|
||||
try: visitors_list.pop('%s/%s' % (room,nick))
|
||||
except: pass
|
||||
visitors_list_lock = False
|
||||
if mass[1] == 'visitor':
|
||||
visitors_list_lock = visitors_list_lock_wait()
|
||||
visitors_list['%s/%s' % (room,nick)] = int(time.time()) + get_config_int(getRoom(room),'visitor_action_time')
|
||||
visitors_list_lock = False
|
||||
|
||||
global execute, timer, presence_control
|
||||
|
||||
timer = [check_unban,check_visitor]
|
||||
presence_control = [visitor_presence]
|
||||
|
||||
execute = [(7, 'ban_past', muc_ban_past, 2, 'Ban user.'),
|
||||
(7, 'ban', muc_ban, 2, 'Ban user.'),
|
||||
(7, 'banjid', muc_banjid, 2, 'Ban user by jid.'),
|
||||
(7, 'unban', muc_none, 2, 'Unban user.'),
|
||||
(7, 'unbanjid', muc_nonejid, 2, 'Unban user by jid.'),
|
||||
(7, 'tban', muc_tempo_ban, 2, 'Temporary ban.\ntban show|del [jid] - show/del temporary bans\ntban nick\ntimeD|H|M|S\nreason - ban nick for time because reason.'),
|
||||
(7, 'none_past', muc_none_past, 2, 'Remove user affiliation.'),
|
||||
(7, 'none', muc_none, 2, 'Remove user affiliation.'),
|
||||
(7, 'nonejid', muc_nonejid, 2, 'Remove user affiliation.'),
|
||||
(7, 'member_past', muc_member_past, 2, 'Get member affiliation.'),
|
||||
(7, 'member', muc_member, 2, 'Get member affiliation.'),
|
||||
(7, 'memberjid', muc_memberjid, 2, 'Get member affiliation.'),
|
||||
(7, 'kick', muc_kick, 2, 'Kick user.'),
|
||||
(7, 'participant', muc_participant, 2, 'Change role to participant.'),
|
||||
(7, 'visitor', muc_visitor, 2, 'Revoke voice.'),
|
||||
(7, 'moderator', muc_moderator, 2, 'Grant moderator.'),
|
||||
(8, 'global_ban', global_ban, 2, 'Global ban. Available only for confernce owner.\nglobal_ban del - remove conference from banlist,\nglobal_ban add - add conference into banlist,\nglobal_ban <jid> - ban jid in all rooms, where bot is admin.')]
|
||||
603
plugins/mucfilter.py
Normal file
603
plugins/mucfilter.py
Normal file
@@ -0,0 +1,603 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
muc_filter_fast_join = {}
|
||||
muc_filter_last_notify = 0
|
||||
muc_filter_events = []
|
||||
|
||||
def muc_pprint(*param):
|
||||
global muc_filter_events,muc_filter_last_notify
|
||||
pprint(*param)
|
||||
if GT('muc_filter_notify'):
|
||||
_notify_count = GT('muc_filter_notify_count')
|
||||
muc_filter_events = [time.time()] + muc_filter_events[:_notify_count-1]
|
||||
if len(muc_filter_events) == _notify_count \
|
||||
and muc_filter_events[0] - muc_filter_events[-1] < GT('muc_filter_notify_peroid') \
|
||||
and muc_filter_last_notify + GT('muc_filter_notify_wait') < time.time():
|
||||
pprint('*** MUC-Filter notify event!')
|
||||
muc_filter_last_notify = time.time()
|
||||
muc_filter_events = []
|
||||
_jids = GT('muc_filter_notify_jids').split()
|
||||
for t in _jids:
|
||||
if t.strip(): send_msg('chat', t.strip(), '', 'MUC-Filter notify event!')
|
||||
|
||||
def muc_filter_set(iq,id,room,acclvl,query,towh,al):
|
||||
msg_xmpp = iq.getTag('query', namespace=xmpp.NS_MUC_FILTER)
|
||||
if msg_xmpp:
|
||||
msg,mute,mute_type,mute_room = get_tag(unicode(msg_xmpp),'query'),None,'groupchat',room
|
||||
jid = rss_replace(get_tag_item(msg,'message','from'))
|
||||
nick = rss_replace(unicode(get_nick_by_jid_res(room,jid)))
|
||||
rn = '%s/%s' % (room,nick)
|
||||
mute_reason = L('Warning! Your message are blocked by policy of room!',rn)
|
||||
if msg[:2] == '<m':
|
||||
if '<body>' in msg and '</body>' in msg:
|
||||
to_nick = getResourse(get_tag_item(msg,'message','to'))
|
||||
tojid = rss_replace(getRoom(get_level(room,to_nick)[1]))
|
||||
skip_owner = is_owner(jid)
|
||||
gr = getRoom(room)
|
||||
type = get_tag_item(msg,'message','type')
|
||||
if type == 'chat' and not skip_owner:
|
||||
tmp = cur_execute_fetchall('select * from muc_lock where room=%s and jid=%s', (room,tojid))
|
||||
if tmp:
|
||||
mute,mute_type,mute_room,mute_reason = True,'chat', '%s/%s' % (room,to_nick),L('Warning! This participant don\'t want to receive private messages!',rn)
|
||||
muc_pprint('MUC-Filter pmlock: %s/%s [%s] > %s: %s' % (room,nick,jid,to_nick,get_tag(msg,'body')),'brown')
|
||||
if skip_owner: pass
|
||||
elif get_config(gr,'muc_filter') and not mute:
|
||||
body = get_tag(msg,'body')
|
||||
|
||||
# Mute all private messages
|
||||
if not mute and msg and type == 'chat' and get_config(gr,'muc_filter_mute_chat'):
|
||||
muc_pprint('MUC-Filter lock private: %s/%s [%s] > %s: %s' % (room,nick,jid,to_nick,get_tag(msg,'body')),'brown')
|
||||
try: cnt = mute_msg['%s|%s' % (gr,jid)]
|
||||
except: cnt = 1
|
||||
act = get_config(gr,'muc_filter_mute_repeat_action')
|
||||
if act != 'off':
|
||||
if cnt >= get_config_int(gr,'muc_filter_mute_repeat'):
|
||||
muc_pprint('MUC-Filter mute repeat action (%s): %s %s [%s]' % (act,gr,jid,cnt),'brown')
|
||||
msg = muc_filter_action(act,jid,room,L('Muted messages count overflow!',rn))
|
||||
else: mute_msg['%s|%s' % (gr,jid)] = cnt + 1
|
||||
mute,mute_type,mute_room,mute_reason = True,'chat', '%s/%s' % (room,to_nick),L('You couldn\'t send private messages! Don\'t repeat!',rn)
|
||||
|
||||
# Mute all public messages
|
||||
if not mute and msg and type == 'groupchat' and get_config(gr,'muc_filter_mute_groupchat'):
|
||||
muc_pprint('MUC-Filter lock public: %s/%s [%s] > %s' % (room,nick,jid,get_tag(msg,'body')),'brown')
|
||||
try: cnt = mute_msg['%s|%s' % (gr,jid)]
|
||||
except: cnt = 1
|
||||
act = get_config(gr,'muc_filter_mute_repeat_action')
|
||||
if act != 'off':
|
||||
if cnt >= get_config_int(gr,'muc_filter_mute_repeat'):
|
||||
muc_pprint('MUC-Filter mute repeat action (%s): %s %s [%s]' % (act,gr,jid,cnt),'brown')
|
||||
msg = muc_filter_action(act,jid,room,L('Muted messages count overflow!',rn))
|
||||
else: mute_msg['%s|%s' % (gr,jid)] = cnt + 1
|
||||
mute,mute_reason = True,L('You couldn\'t send public messages! Don\'t repeat!',rn)
|
||||
|
||||
# Mute newbie
|
||||
if not mute and msg and get_config(gr,'muc_filter_newbie'):
|
||||
in_base = cur_execute_fetchall('select sum(sum) from (select sum(age) from age where jid=%s and room=%s union all select %s-time from age where jid=%s and room=%s and status=0) as sum_age;',(getRoom(jid),gr,int(time.time()),getRoom(jid),gr))
|
||||
if not in_base: nmute = True
|
||||
else:
|
||||
newbie_time = get_config(gr,'muc_filter_newbie_time')
|
||||
if newbie_time.isdigit(): newbie_time = int(newbie_time)
|
||||
else: newbie_time = 60
|
||||
if in_base[0][0] < newbie_time: nmute = True
|
||||
else: nmute = False
|
||||
if nmute:
|
||||
try: cnt = newbie_msg['%s|%s' % (gr,jid)]
|
||||
except: cnt = 1
|
||||
muc_pprint('MUC-Filter mute newbie: %s %s [%s] %s' % (gr,jid,cnt,body),'brown')
|
||||
act = get_config(gr,'muc_filter_newbie_repeat_action')
|
||||
if act != 'off':
|
||||
if cnt >= get_config_int(gr,'muc_filter_newbie_repeat'):
|
||||
muc_pprint('MUC-Filter mute newbie repeat action (%s): %s %s [%s]' % (act,gr,jid,cnt),'brown')
|
||||
msg = muc_filter_action(act,jid,room,L('Messages count overflow from newbie!',rn))
|
||||
else: newbie_msg['%s|%s' % (gr,jid)] = cnt + 1
|
||||
mute,mute_reason = True,L('Your messages are blocked %ssec. after first join! Please, wait quiet!',rn) % newbie_time
|
||||
|
||||
# New Line
|
||||
if not mute and msg and get_config(gr,'muc_filter_newline_msg') != 'off':
|
||||
act = get_config(gr,'muc_filter_newline_msg')
|
||||
try:
|
||||
nline_count = get_config_int(gr,'muc_filter_newline_msg_count')
|
||||
if not 2 <= nline_count <= 50: raise
|
||||
except:
|
||||
nline_count = int(config_prefs['muc_filter_newline_msg_count'][3])
|
||||
put_config(gr,'muc_filter_newline_msg_count',str(nline_count))
|
||||
if body.count('\n') >= nline_count:
|
||||
muc_pprint('MUC-Filter msg new line (%s): %s [%s] %s' % (act,jid,room,nick+'|'+body.replace('\n','[LF]')),'brown')
|
||||
if act == 'replace':
|
||||
body = body.replace('\n',' ')
|
||||
msg = msg.replace(get_tag_full(msg,'body'),'<body>%s</body>' % body)
|
||||
elif act == 'mute': mute,mute_reason = True,L('Blocked by content!',rn)
|
||||
else: msg = muc_filter_action(act,jid,room,L('Blocked by content!',rn))
|
||||
|
||||
# Reduce spaces
|
||||
if not mute and msg and get_config(gr,'muc_filter_reduce_spaces_msg') and ' ' in body:
|
||||
muc_pprint('MUC-Filter msg reduce spaces: %s [%s] %s' % (jid,room,nick+'|'+body),'brown')
|
||||
body = reduce_spaces_all(body)
|
||||
msg = msg.replace(get_tag_full(msg,'body'),'<body>%s</body>' % body)
|
||||
|
||||
# AD-Block filter
|
||||
need_raw = True
|
||||
if not mute and msg and get_config(gr,'muc_filter_adblock') != 'off':
|
||||
f = []
|
||||
for reg in adblock_regexp:
|
||||
tmp = re.findall(reg,body,re.S|re.I|re.U)
|
||||
if tmp: f = f + tmp
|
||||
if f:
|
||||
act = get_config(gr,'muc_filter_adblock')
|
||||
need_raw = False
|
||||
muc_pprint('MUC-Filter msg adblock (%s): %s [%s] %s' % (act,jid,room,body),'brown')
|
||||
if act == 'replace':
|
||||
for tmp in f: body = body.replace(tmp,[GT('censor_text')*len(tmp),GT('censor_text')][len(GT('censor_text'))>1])
|
||||
msg = msg.replace(get_tag_full(msg,'body'),'<body>%s</body>' % body)
|
||||
elif act == 'mute': mute,mute_reason = True,L('AD-Block!',rn)
|
||||
else: msg = muc_filter_action(act,jid,room,L('AD-Block!',rn))
|
||||
|
||||
# Raw AD-Block filter
|
||||
if not mute and msg and need_raw and get_config(gr,'muc_filter_adblock_raw') != 'off':
|
||||
rawbody = match_for_raw(body,u'[a-zа-я0-9@.]*',gr)
|
||||
if rawbody:
|
||||
f = []
|
||||
for reg in adblock_regexp:
|
||||
tmp = re.findall(reg,rawbody,re.S|re.I|re.U)
|
||||
if tmp: f = f + tmp
|
||||
if f:
|
||||
act = get_config(gr,'muc_filter_adblock_raw')
|
||||
muc_pprint('MUC-Filter msg raw adblock (%s): %s [%s] %s' % (act,jid,room,body),'brown')
|
||||
if act == 'mute': mute,mute_reason = True,L('Raw AD-Block!',rn)
|
||||
else: msg = muc_filter_action(act,jid,room,L('Raw AD-Block!',rn))
|
||||
|
||||
# Repeat message filter
|
||||
if not mute and msg and get_config(gr,'muc_filter_repeat') != 'off':
|
||||
grj = getRoom(jid)
|
||||
try: lm = last_msg_base[grj]
|
||||
except: lm = None
|
||||
if lm:
|
||||
rep_to = GT('muc_filter_repeat_time')
|
||||
try: lmt = last_msg_time_base[grj]
|
||||
except: lmt = 0
|
||||
if rep_to+lmt > time.time():
|
||||
action = False
|
||||
if body == lm: action = True
|
||||
elif lm in body:
|
||||
try: muc_repeat[grj] += 1
|
||||
except: muc_repeat[grj] = 1
|
||||
if muc_repeat[grj] >= (GT('muc_filter_repeat_count')-1): action = True
|
||||
else: muc_repeat[grj] = 0
|
||||
if action:
|
||||
act = get_config(gr,'muc_filter_repeat')
|
||||
muc_pprint('MUC-Filter msg repeat (%s): %s [%s] %s' % (act,jid,room,body),'brown')
|
||||
if act == 'mute': mute,mute_reason = True,L('Repeat message block!',rn)
|
||||
else: msg = muc_filter_action(act,jid,room,L('Repeat message block!',rn))
|
||||
else: muc_repeat[grj] = 0
|
||||
last_msg_base[grj] = body
|
||||
last_msg_time_base[grj] = time.time()
|
||||
|
||||
# Match filter
|
||||
if not mute and msg and get_config(gr,'muc_filter_match') != 'off' and len(body) >= GT('muc_filter_match_view'):
|
||||
tbody,warn_match,warn_space = body.split(),0,0
|
||||
for tmp in tbody:
|
||||
cnt = 0
|
||||
for tmp2 in tbody:
|
||||
if tmp in tmp2: cnt += 1
|
||||
if cnt > GT('muc_filter_match_count'): warn_match += 1
|
||||
if not len(tmp): warn_space += 1
|
||||
if warn_match > GT('muc_filter_match_warning_match') or warn_space > GT('muc_filter_match_warning_space') or '\n'*GT('muc_filter_match_warning_nn') in body:
|
||||
act = get_config(gr,'muc_filter_match')
|
||||
muc_pprint('MUC-Filter msg matcher (%s): %s [%s] %s' % (act,jid,room,body),'brown')
|
||||
if act == 'mute': mute,mute_reason = True,L('Match message block!',rn)
|
||||
else: msg = muc_filter_action(act,jid,room,L('Match message block!',rn))
|
||||
|
||||
# Censor filter
|
||||
need_raw = True
|
||||
if not mute and msg and get_config(gr,'muc_filter_censor') != 'off' and esc_min2(body) != to_censore(esc_min2(body),gr):
|
||||
act = get_config(gr,'muc_filter_censor')
|
||||
need_raw = False
|
||||
muc_pprint('MUC-Filter msg censor (%s): %s [%s] %s' % (act,jid,room,body),'brown')
|
||||
if act == 'replace': msg = msg.replace(get_tag_full(msg,'body'),'<body>%s</body>' % esc_max2(to_censore(esc_min2(body),gr)))
|
||||
elif act == 'mute': mute,mute_reason = True,L('Blocked by censor!',rn)
|
||||
else: msg = muc_filter_action(act,jid,room,L('Blocked by censor!',rn))
|
||||
|
||||
# Raw censor filter
|
||||
if not mute and msg and need_raw and get_config(gr,'muc_filter_censor_raw') != 'off':
|
||||
rawbody = match_for_raw(body,u'[a-zа-я0-9]*',gr)
|
||||
if rawbody and rawbody != to_censore(rawbody,gr):
|
||||
act = get_config(gr,'muc_filter_censor_raw')
|
||||
muc_pprint('MUC-Filter msg raw censor (%s): %s [%s] %s' % (act,jid,room,body),'brown')
|
||||
if act == 'mute': mute,mute_reason = True,L('Blocked by raw censor!',rn)
|
||||
else: msg = muc_filter_action(act,jid,room,L('Blocked by raw censor!',rn))
|
||||
|
||||
# Large message filter
|
||||
if not mute and msg and get_config(gr,'muc_filter_large') != 'off' and len(body) > GT('muc_filter_large_message_size'):
|
||||
act = get_config(gr,'muc_filter_large')
|
||||
muc_pprint('MUC-Filter msg large message (%s): %s [%s] %s' % (act,jid,room,body),'brown')
|
||||
if act == 'paste' or act == 'truncate':
|
||||
url = paste_text(rss_replace(body),room,jid)
|
||||
if act == 'truncate': body = u'%s[…] %s' % (body[:GT('muc_filter_large_message_size')],url)
|
||||
else: body = L('Large message%s %s',rn) % (u'…',url)
|
||||
msg = msg.replace(get_tag_full(msg,'body'),'<body>%s</body>' % body)
|
||||
elif act == 'mute': mute,mute_reason = True,L('Large message block!',rn)
|
||||
else: msg = muc_filter_action(act,jid,room,L('Large message block!',rn))
|
||||
|
||||
if mute: msg = unicode(xmpp.Message(to=jid,body=mute_reason,typ=mute_type,frm=mute_room))
|
||||
else: msg = None
|
||||
|
||||
elif msg[:2] == '<p':
|
||||
jid = rss_replace(get_tag_item(msg,'presence','from'))
|
||||
gr = getRoom(room)
|
||||
if server_hash_list.has_key('%s/%s' % (gr,getServer(jid))) or server_hash_list.has_key('%s/%s' % (gr,getRoom(jid))):
|
||||
muc_pprint('MUC-Filter drop by previous ban: %s %s' % (room,jid),'brown')
|
||||
return True
|
||||
|
||||
tojid = rss_replace(get_tag_item(msg,'presence','to'))
|
||||
if is_owner(jid): pass
|
||||
elif get_config(gr,'muc_filter') and not mute:
|
||||
show = ['online',get_tag(msg,'show')][int('<show>' in msg and '</show>' in msg)]
|
||||
if show not in ['chat','online','away','xa','dnd']: msg = msg.replace(get_tag_full(msg,'show'), '<show>online</show>')
|
||||
status = ['',get_tag(msg,'status')][int('<status>' in msg and '</status>' in msg)]
|
||||
nick = ['',tojid[tojid.find('/')+1:]]['/' in tojid]
|
||||
newjoin = True
|
||||
for tmp in megabase:
|
||||
if tmp[0] == gr and tmp[4] == jid:
|
||||
newjoin = False
|
||||
break
|
||||
|
||||
# Drop presences without history
|
||||
if not mute and newjoin and get_config(gr,'muc_filter_history'):
|
||||
try: v = not sum([int(t) for t in msg_xmpp.getTag('presence').getTag('x',attrs={'xmlns':xmpp.NS_MUC}).getTag('history').getAttrs().values()])
|
||||
except: v = False
|
||||
if v:
|
||||
muc_pprint('MUC-Filter history: %s/%s %s' % (gr,nick,jid),'brown')
|
||||
msg,mute = unicode(xmpp.Node('presence', {'from': tojid, 'type': 'error', 'to':jid}, payload = ['replace_it',xmpp.Node('error', {'type': 'auth','code':'403'}, payload=[xmpp.Node('forbidden',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[]),xmpp.Node('text',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[L('Deny by history request!',rn)])])])).replace('replace_it',get_tag(msg,'presence')),True
|
||||
if get_config(gr,'muc_filter_history_ban'):
|
||||
muc_pprint('MUC-Filter history ban: %s/%s %s' % (gr,nick,jid),'brown')
|
||||
sender(xmpp.Node('iq',{'id': get_id(), 'type': 'set', 'to':gr},payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'affiliation':'outcast', 'jid':jid},[xmpp.Node('reason',{},'Banned by empty history at %s' % timeadd(tuple(time.localtime())))])])]))
|
||||
|
||||
# Fast join filter
|
||||
if not mute and newjoin and get_config(gr,'muc_filter_fast_join'):
|
||||
_itt = int(time.time())
|
||||
if muc_filter_fast_join.has_key(gr):
|
||||
_cnt = get_config_int(gr,'muc_filter_fast_join_count')
|
||||
_time = get_config_int(gr,'muc_filter_fast_join_time')
|
||||
muc_filter_fast_join[gr] = [_itt] + muc_filter_fast_join[gr][:_cnt-1]
|
||||
if len(muc_filter_fast_join[gr]) == _cnt and (muc_filter_fast_join[gr][0] - muc_filter_fast_join[gr][-1]) <= _time:
|
||||
muc_pprint('MUC-Filter fast join: %s/%s %s' % (gr,nick,jid),'brown')
|
||||
msg,mute = unicode(xmpp.Node('presence', {'from': tojid, 'type': 'error', 'to':jid}, payload = ['replace_it',xmpp.Node('error', {'type': 'auth','code':'403'}, payload=[xmpp.Node('forbidden',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[]),xmpp.Node('text',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[L('Deny by fast join! Try again later!',rn)])])])).replace('replace_it',get_tag(msg,'presence')),True
|
||||
else: muc_filter_fast_join[gr] = [_itt]
|
||||
|
||||
# Validate items
|
||||
if not mute and msg and get_config(gr,'muc_filter_validate_action') != 'off':
|
||||
is_valid = True
|
||||
validate_limit = get_config_int(gr,'muc_filter_validate_count')
|
||||
validate_count = 0
|
||||
id_node,id_ver,id_hash = 'empty','empty','empty'
|
||||
if get_config(gr,'muc_filter_validate_nick'):
|
||||
iv,vc = validate_nick(nick,validate_limit)
|
||||
validate_count += vc
|
||||
if validate_count > validate_limit or not iv: is_valid = False
|
||||
if is_valid and get_config(gr,'muc_filter_validate_login'):
|
||||
iv,vc = validate_nick(getName(jid),validate_limit)
|
||||
validate_count += vc
|
||||
if validate_count > validate_limit or not iv: is_valid = False
|
||||
if is_valid and get_config(gr,'muc_filter_validate_resource'):
|
||||
iv,vc = validate_nick(getResourse(jid),validate_limit)
|
||||
validate_count += vc
|
||||
if validate_count > validate_limit or not iv: is_valid = False
|
||||
if is_valid:
|
||||
msg_xmpp_tmp = msg_xmpp.getTag('presence')
|
||||
caps_error = False
|
||||
try: id_node = get_eval_item(msg_xmpp_tmp,'getTag("c",namespace=xmpp.NS_CAPS).getAttr("node")').decode('utf-8')
|
||||
except: id_node,caps_error = get_eval_item(msg_xmpp_tmp,'getTag("c",namespace=xmpp.NS_CAPS).getAttr("node")'),True
|
||||
try: id_ver = get_eval_item(msg_xmpp_tmp,'getTag("c",namespace=xmpp.NS_CAPS).getAttr("ver")').decode('utf-8')
|
||||
except: id_ver,caps_error = get_eval_item(msg_xmpp_tmp,'getTag("c",namespace=xmpp.NS_CAPS).getAttr("ver")'),True
|
||||
try: id_hash = get_eval_item(msg_xmpp_tmp,'getTag("c",namespace=xmpp.NS_CAPS).getAttr("hash")').decode('utf-8')
|
||||
except: id_hash,caps_error = get_eval_item(msg_xmpp_tmp,'getTag("c",namespace=xmpp.NS_CAPS).getAttr("hash")'),True
|
||||
if caps_error: writefile(slog_folder % 'bad_stanza_%s.txt' % int(time.time()),unicode(msg_xmpp).encode('utf-8'))
|
||||
if get_config(gr,'muc_filter_validate_caps_node'):
|
||||
iv,vc = validate_nick(id_node,validate_limit)
|
||||
validate_count += vc
|
||||
if validate_count > validate_limit or not iv: is_valid = False
|
||||
if is_valid and get_config(gr,'muc_filter_validate_caps_version') and [len(id_ver),id_hash] in [[24,'md5'],[28,'sha-1']] and not id_ver.endswith('='):
|
||||
iv,vc = validate_nick(id_ver,validate_limit)
|
||||
validate_count += vc
|
||||
if validate_count > validate_limit or not iv: is_valid = False
|
||||
if not is_valid:
|
||||
act = get_config(gr,'muc_filter_validate_action')
|
||||
muc_pprint('MUC-Filter invalid items [%s]: %s/%s %s [%s] %s %s %s' % (act,gr,nick,jid,validate_count,id_node,id_ver,id_hash),'brown')
|
||||
msg,mute = unicode(xmpp.Node('presence', {'from': tojid, 'type': 'error', 'to':jid}, payload = ['replace_it',xmpp.Node('error', {'type': 'auth','code':'403'}, payload=[xmpp.Node('forbidden',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[]),xmpp.Node('text',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[L('Deny by validation!',rn)])])])).replace('replace_it',get_tag(msg,'presence')),True
|
||||
tmp_server = getServer(jid)
|
||||
tmp2_server = '%s/%s' % (gr,tmp_server)
|
||||
if act == 'ban' and not server_hash_list.has_key('%s/%s' % (gr,getRoom(jid))):
|
||||
server_hash_list['%s/%s' % (gr,getRoom(jid))] = time.time()
|
||||
sender(xmpp.Node('iq',{'id': get_id(), 'type': 'set', 'to':gr},payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'affiliation':'outcast', 'jid':jid},[xmpp.Node('reason',{},'Banned by invalid items at %s' % timeadd(tuple(time.localtime())))])])]))
|
||||
elif act == 'ban server' and tmp_server not in get_config(gr,'muc_filter_validate_ban_server_exception').split() and not server_hash_list.has_key(tmp2_server):
|
||||
server_hash_list[tmp2_server] = time.time()
|
||||
sender(xmpp.Node('iq',{'id': get_id(), 'type': 'set', 'to':gr},payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'affiliation':'outcast', 'jid':tmp_server},[xmpp.Node('reason',{},'Banned by invalid items at %s' % timeadd(tuple(time.localtime())))])])]))
|
||||
tmp_notify = get_config(gr,'muc_filter_validate_ban_server_notify_jid')
|
||||
if len(tmp_notify):
|
||||
for tmp in tmp_notify.split():
|
||||
if len(tmp): send_msg('chat', tmp, '', L('Server %s was banned in %s',rn) % (tmp_server,gr))
|
||||
|
||||
|
||||
# Lock by caps
|
||||
if not mute and msg and get_config(gr,'muc_filter_caps_list') != 'off':
|
||||
caps_error = False
|
||||
if get_config(gr,'muc_filter_caps_list') == 'white': caps_list,caps_negate = 'muc_filter_caps_white',True
|
||||
else: caps_list,caps_negate = 'muc_filter_caps_black',False
|
||||
c_list = [t.strip() for t in get_config(gr,caps_list).split('\n') if t and not t.startswith('#')]
|
||||
if c_list:
|
||||
msg_xmpp_tmp = msg_xmpp.getTag('presence')
|
||||
id_node,id_ver = 'error!','error!'
|
||||
try: id_node = get_eval_item(msg_xmpp_tmp,'getTag("c",namespace=xmpp.NS_CAPS).getAttr("node")').decode('utf-8')
|
||||
except: id_node,caps_error = get_eval_item(msg_xmpp_tmp,'getTag("c",namespace=xmpp.NS_CAPS).getAttr("node")'),True
|
||||
try: id_ver = get_eval_item(msg_xmpp_tmp,'getTag("c",namespace=xmpp.NS_CAPS).getAttr("ver")').decode('utf-8')
|
||||
except: id_ver,caps_error = get_eval_item(msg_xmpp_tmp,'getTag("c",namespace=xmpp.NS_CAPS).getAttr("ver")'),True
|
||||
try:
|
||||
id_bmver = msg_xmpp_tmp.getAttr('ver').decode('utf-8')
|
||||
if id_bmver or id_bmver == '': id_bmver = '%s_' % id_bmver
|
||||
else: id_bmver = ''
|
||||
except: id_bmver = ''
|
||||
c_caps = '%s %s %s' % (id_node,id_ver,id_bmver)
|
||||
if caps_matcher(c_caps,c_list) ^ caps_negate:
|
||||
muc_pprint('MUC-Filter caps node lock (%s): %s/%s %s %s' % (['black','white'][caps_negate],gr,nick,jid,c_caps),'brown')
|
||||
msg,mute = unicode(xmpp.Node('presence', {'from': tojid, 'type': 'error', 'to':jid}, payload = ['replace_it',xmpp.Node('error', {'type': 'auth','code':'403'}, payload=[xmpp.Node('forbidden',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[]),xmpp.Node('text',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[L('Deny by node lock!',rn)])])])).replace('replace_it',get_tag(msg,'presence')),True
|
||||
if caps_error: writefile(slog_folder % 'bad_stanza_%s.txt' % int(time.time()),unicode(msg_xmpp).encode('utf-8'))
|
||||
|
||||
# Hash lock
|
||||
if not mute and msg and get_config(gr,'muc_filter_deny_hash'):
|
||||
hashes_list = reduce_spaces_all(get_config(gr,'muc_filter_deny_hash_list').replace(',',' ').replace(';',' ').replace('|',' ')).split()
|
||||
if hashes_list:
|
||||
msg_xmpp_tmp = msg_xmpp.getTag('presence')
|
||||
#id_node = id_ver = id_lang = id_photo = id_avatar = 'error!'
|
||||
id_ver,id_lang,id_photo,id_avatar = 'error!','error!','error!','error!'
|
||||
hash_error = False
|
||||
#try: id_node = get_eval_item(msg_xmpp_tmp,'getTag("c",namespace=xmpp.NS_CAPS).getAttr("node")').decode('utf-8')
|
||||
#except: id_node,hash_error = get_eval_item(msg_xmpp_tmp,'getTag("c",namespace=xmpp.NS_CAPS).getAttr("node")'),True
|
||||
try: id_ver = get_eval_item(msg_xmpp_tmp,'getTag("c",namespace=xmpp.NS_CAPS).getAttr("ver")').decode('utf-8')
|
||||
except: id_ver,hash_error = get_eval_item(msg_xmpp_tmp,'getTag("c",namespace=xmpp.NS_CAPS).getAttr("ver")'),True
|
||||
try:
|
||||
id_bmver = msg_xmpp_tmp.getAttr('ver').decode('utf-8')
|
||||
if id_bmver or id_bmver == '': id_bmver = '%s_' % id_bmver
|
||||
else: id_bmver = ''
|
||||
except: id_bmver = ''
|
||||
try: id_lang = get_eval_item(msg_xmpp_tmp,'getAttr("xml:lang")').decode('utf-8')
|
||||
except: id_lang,hash_error = get_eval_item(msg_xmpp_tmp,'getAttr("xml:lang")'),True
|
||||
try: id_photo = get_eval_item(msg_xmpp_tmp,'getTag("x",namespace=xmpp.NS_VCARD_UPDATE).getTagData("photo")').decode('utf-8')
|
||||
except: id_photo,hash_error = get_eval_item(msg_xmpp_tmp,'getTag("x",namespace=xmpp.NS_VCARD_UPDATE).getTagData("photo")'),True
|
||||
try: id_avatar = get_eval_item(msg_xmpp_tmp,'getTag("x",namespace=xmpp.NS_AVATAR).getTagData("hash")').decode('utf-8')
|
||||
except: id_avatar,hash_error = get_eval_item(msg_xmpp_tmp,'getTag("x",namespace=xmpp.NS_AVATAR).getTagData("hash")'),True
|
||||
|
||||
hash_body = '<'.join([unicode(tmp) for tmp in id_avatar,id_photo,id_ver,id_bmver,id_lang]) + '<<'
|
||||
if hash_error:
|
||||
writefile(slog_folder % 'bad_stanza_%s.txt' % int(time.time()),unicode(msg_xmpp).encode('utf-8'))
|
||||
hash_body = parser(hash_body.decode('utf-8'))
|
||||
|
||||
current_hash = hashlib.md5(hash_body.encode('utf-8')).digest().encode('base64').replace('\n','')
|
||||
hashes['%s/%s' % (gr,nick)] = current_hash
|
||||
if current_hash in hashes_list:
|
||||
muc_pprint('MUC-Filter hash lock: %s/%s %s %s' % (gr,nick,jid,current_hash),'brown')
|
||||
msg,mute = unicode(xmpp.Node('presence', {'from': tojid, 'type': 'error', 'to':jid}, payload = ['replace_it',xmpp.Node('error', {'type': 'auth','code':'403'}, payload=[xmpp.Node('forbidden',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[]),xmpp.Node('text',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[L('Deny by hash lock!',rn)])])])).replace('replace_it',get_tag(msg,'presence')),True
|
||||
tmp_server = getServer(jid)
|
||||
tmp2_server = '%s/%s' % (gr,tmp_server)
|
||||
if get_config(gr,'muc_filter_hash_ban_by_rejoin') and not server_hash.has_key(tmp2_server):
|
||||
if user_hash.has_key('%s/%s' % (gr,getRoom(jid))):
|
||||
user_hash.pop('%s/%s' % (gr,getRoom(jid)))
|
||||
sender(xmpp.Node('iq',{'id': get_id(), 'type': 'set', 'to':gr},payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'affiliation':'outcast', 'jid':jid},[xmpp.Node('reason',{},'Banned by hash activity at %s' % timeadd(tuple(time.localtime())))])])]))
|
||||
muc_pprint('MUC-Filter ban by hash lock: %s/%s' % (gr,nick),'brown')
|
||||
else: user_hash['%s/%s' % (gr,getRoom(jid))] = time.time()
|
||||
if get_config(gr,'muc_filter_hash_ban_server_by_rejoin'):
|
||||
if tmp_server not in get_config(gr,'muc_filter_hash_ban_server_by_rejoin_exception').split():
|
||||
tmp_rejoins = get_config_int(gr,'muc_filter_hash_ban_server_by_rejoin_rejoins')
|
||||
if server_hash.has_key(tmp2_server): server_hash[tmp2_server] = [time.time()] + server_hash[tmp2_server][:tmp_rejoins-1]
|
||||
else: server_hash[tmp2_server] = [time.time()]
|
||||
tmp_times = server_hash[tmp2_server]
|
||||
if len(tmp_times) == tmp_rejoins and tmp_times[0]-tmp_times[-1] <= get_config_int(gr,'muc_filter_hash_ban_server_by_rejoin_timeout') and not server_hash_list.has_key(tmp2_server):
|
||||
server_hash_list[tmp2_server] = time.time()
|
||||
sender(xmpp.Node('iq',{'id': get_id(), 'type': 'set', 'to':gr},payload = [xmpp.Node('query', {'xmlns': xmpp.NS_MUC_ADMIN},[xmpp.Node('item',{'affiliation':'outcast', 'jid':tmp_server},[xmpp.Node('reason',{},'Banned by hash activity at %s' % timeadd(tuple(time.localtime())))])])]))
|
||||
muc_pprint('MUC-Filter server ban by hash lock: %s %s' % (gr,tmp_server),'brown')
|
||||
tmp_notify = get_config(gr,'muc_filter_hash_ban_server_by_rejoin_notify_jid')
|
||||
if len(tmp_notify):
|
||||
for tmp in tmp_notify.split():
|
||||
if len(tmp): send_msg('chat', tmp, '', L('Server %s was banned in %s',rn) % (tmp_server,gr))
|
||||
else: pprint('User hash: %s %s/%s %s' % (current_hash,gr,nick,jid),'white')
|
||||
|
||||
# Blacklist
|
||||
if not mute and msg and get_config(gr,'muc_filter_blacklist'):
|
||||
bl_jid = get_config(gr,'muc_filter_blacklist_rules_jid')
|
||||
try: re.compile(bl_jid)
|
||||
except: bl_jid = None
|
||||
bl_nick = get_config(gr,'muc_filter_blacklist_rules_nick')
|
||||
try: re.compile(bl_nick)
|
||||
except: bl_nick = None
|
||||
is_bl = None
|
||||
if bl_jid and re.findall(bl_jid,jid,re.S|re.I|re.U): is_bl = True
|
||||
if not nick or (not is_bl and bl_nick and re.findall(bl_nick,nick,re.S|re.I|re.U)): is_bl = True
|
||||
if is_bl:
|
||||
muc_pprint('MUC-Filter blacklist: %s/%s %s' % (gr,nick,jid),'brown')
|
||||
msg,mute = unicode(xmpp.Node('presence', {'from': tojid, 'type': 'error', 'to':jid}, payload = ['replace_it',xmpp.Node('error', {'type': 'auth','code':'403'}, payload=[xmpp.Node('forbidden',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[]),xmpp.Node('text',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[L('Deny by blacklist!',rn)])])])).replace('replace_it',get_tag(msg,'presence')),True
|
||||
|
||||
# Whitelist
|
||||
if not mute and msg and get_config(gr,'muc_filter_whitelist') and newjoin:
|
||||
in_base = cur_execute_fetchone('select jid from age where room=%s and jid=%s',(gr,getRoom(jid)))
|
||||
if not in_base:
|
||||
muc_pprint('MUC-Filter whitelist: %s/%s %s' % (gr,nick,jid),'brown')
|
||||
msg,mute = unicode(xmpp.Node('presence', {'from': tojid, 'type': 'error', 'to':jid}, payload = ['replace_it',xmpp.Node('error', {'type': 'auth','code':'403'}, payload=[xmpp.Node('forbidden',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[]),xmpp.Node('text',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[L('Deny by whitelist!',rn)])])])).replace('replace_it',get_tag(msg,'presence')),True
|
||||
|
||||
# AD-Block filter
|
||||
need_raw = True
|
||||
if not mute and msg and get_config(gr,'muc_filter_adblock_prs') != 'off':
|
||||
fs,fn = [],[]
|
||||
for reg in adblock_regexp:
|
||||
tmps = [None,re.findall(reg,status,re.S|re.I|re.U)][status != '']
|
||||
tmpn = [None,re.findall(reg,nick,re.S|re.I|re.U)][nick != '']
|
||||
if tmps: fs = fs + tmps
|
||||
if tmpn: fn = fn + tmpn
|
||||
if fs:
|
||||
need_raw = False
|
||||
act = get_config(gr,'muc_filter_adblock_prs')
|
||||
muc_pprint('MUC-Filter adblock prs status (%s): %s [%s] %s' % (act,jid,room,status),'brown')
|
||||
if act == 'replace':
|
||||
for tmp in fs: status = status.replace(tmp,[GT('censor_text')*len(tmp),GT('censor_text')][len(GT('censor_text'))>1])
|
||||
msg = msg.replace(get_tag_full(msg,'status'),'<status>%s</status>' % status)
|
||||
elif newjoin: msg,mute = unicode(xmpp.Node('presence', {'from': tojid, 'type': 'error', 'to':jid}, payload = ['replace_it',xmpp.Node('error', {'type': 'auth','code':'403'}, payload=[xmpp.Node('forbidden',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[]),xmpp.Node('text',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[L('AD-Block!',rn)])])])).replace('replace_it',get_tag(msg,'presence')),True
|
||||
elif act == 'mute': msg,mute = None,True
|
||||
else: msg = muc_filter_action(act,jid,room,L('AD-Block!',rn))
|
||||
if fn and msg:
|
||||
need_raw = False
|
||||
act = get_config(gr,'muc_filter_adblock_prs')
|
||||
muc_pprint('MUC-Filter adblock prs nick (%s): %s [%s] %s' % (act,jid,room,nick),'brown')
|
||||
if act == 'replace':
|
||||
for tmp in fn: nick = nick.replace(tmp,[GT('censor_text')*len(tmp),GT('censor_text')][len(GT('censor_text'))>1])
|
||||
msg = msg.replace(esc_max2(tojid),'%s/%s' % (tojid.split('/',1)[0],nick))
|
||||
elif newjoin: msg,mute = unicode(xmpp.Node('presence', {'from': tojid, 'type': 'error', 'to':jid}, payload = ['replace_it',xmpp.Node('error', {'type': 'auth','code':'403'}, payload=[xmpp.Node('forbidden',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[]),xmpp.Node('text',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[L('AD-Block!',rn)])])])).replace('replace_it',get_tag(msg,'presence')),True
|
||||
elif act == 'mute': msg,mute = None,True
|
||||
else: msg = muc_filter_action(act,jid,room,L('AD-Block!',rn))
|
||||
|
||||
# Raw AD-Block filter
|
||||
if not mute and msg and need_raw and get_config(gr,'muc_filter_adblock_prs_raw') != 'off':
|
||||
rawstatus = match_for_raw(status,u'[a-zа-я0-9@.]*',gr)
|
||||
rawnick = match_for_raw(nick,u'[a-zа-я0-9@.]*',gr)
|
||||
fs,fn = [],[]
|
||||
for reg in adblock_regexp:
|
||||
tmps = [None,re.findall(reg,rawstatus,re.S|re.I|re.U)][status != '']
|
||||
tmpn = [None,re.findall(reg,rawnick,re.S|re.I|re.U)][nick != '']
|
||||
if tmps: fs = fs + tmps
|
||||
if tmpn: fn = fn + tmpn
|
||||
if rawstatus and fs:
|
||||
act = get_config(gr,'muc_filter_adblock_prs_raw')
|
||||
muc_pprint('MUC-Filter raw adblock prs status (%s): %s [%s] %s' % (act,jid,room,status),'brown')
|
||||
if newjoin: msg,mute = unicode(xmpp.Node('presence', {'from': tojid, 'type': 'error', 'to':jid}, payload = ['replace_it',xmpp.Node('error', {'type': 'auth','code':'403'}, payload=[xmpp.Node('forbidden',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[]),xmpp.Node('text',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[L('AD-Block!',rn)])])])).replace('replace_it',get_tag(msg,'presence')),True
|
||||
elif act == 'mute': msg,mute = None,True
|
||||
else: msg = muc_filter_action(act,jid,room,L('Raw AD-Block!',rn))
|
||||
if rawnick and fn and msg:
|
||||
act = get_config(gr,'muc_filter_adblock_prs_raw')
|
||||
muc_pprint('MUC-Filter raw adblock prs nick (%s): %s [%s] %s' % (act,jid,room,nick),'brown')
|
||||
if newjoin: msg,mute = unicode(xmpp.Node('presence', {'from': tojid, 'type': 'error', 'to':jid}, payload = ['replace_it',xmpp.Node('error', {'type': 'auth','code':'403'}, payload=[xmpp.Node('forbidden',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[]),xmpp.Node('text',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[L('AD-Block!',rn)])])])).replace('replace_it',get_tag(msg,'presence')),True
|
||||
elif act == 'mute': msg,mute = None,True
|
||||
else: msg = muc_filter_action(act,jid,room,L('Raw AD-Block!',rn))
|
||||
|
||||
# New Line
|
||||
if not mute and msg and get_config(gr,'muc_filter_newline') != 'off':
|
||||
act = get_config(gr,'muc_filter_newline')
|
||||
try:
|
||||
nline_count = get_config_int(gr,'muc_filter_newline_count')
|
||||
if not 2 <= nline_count <= 50: raise
|
||||
except:
|
||||
nline_count = int(config_prefs['muc_filter_newline_count'][3])
|
||||
put_config(gr,'muc_filter_newline_count',str(nline_count))
|
||||
if status.count('\n') >= nline_count:
|
||||
muc_pprint('MUC-Filter prs new line (%s): %s [%s] %s' % (act,jid,room,nick+'|'+status.replace('\n','[CR]').replace('\r','[LF]')),'brown')
|
||||
if act == 'replace':
|
||||
status = reduce_spaces_all(status.replace('\n',' ').replace('\r',' '))
|
||||
msg = msg.replace(get_tag_full(msg,'status'),'<status>%s</status>' % status)
|
||||
elif newjoin: msg,mute = unicode(xmpp.Node('presence', {'from': tojid, 'type': 'error', 'to':jid}, payload = ['replace_it',xmpp.Node('error', {'type': 'auth','code':'403'}, payload=[xmpp.Node('forbidden',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[]),xmpp.Node('text',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[L('Blocked by content!',rn)])])])).replace('replace_it',get_tag(msg,'presence')),True
|
||||
elif act == 'mute': msg,mute = None,True
|
||||
else: msg = muc_filter_action(act,jid,room,L('Blocked by content!',rn))
|
||||
|
||||
# Reduce spaces
|
||||
if not mute and msg and get_config(gr,'muc_filter_reduce_spaces_prs') and (' ' in status or ' ' in nick):
|
||||
muc_pprint('MUC-Filter prs reduce spaces: %s [%s] %s' % (jid,room,nick+'|'+status),'brown')
|
||||
if len(status):
|
||||
status = reduce_spaces_all(status)
|
||||
msg = msg.replace(get_tag_full(msg,'status'),'<status>%s</status>' % status).replace(esc_max2(tojid),'%s/%s' % (tojid.split('/',1)[0],reduce_spaces_all(esc_max2(nick))))
|
||||
else: msg = msg.replace(esc_max2(tojid),'%s/%s' % (tojid.split('/',1)[0],reduce_spaces_all(esc_max2(nick))))
|
||||
|
||||
# Censor filter
|
||||
need_raw = True
|
||||
if not mute and msg and get_config(gr,'muc_filter_censor_prs') != 'off' and '%s|%s' % (esc_min2(status),esc_min2(nick)) != to_censore('%s|%s' % (esc_min2(status),esc_min2(nick)),gr):
|
||||
act = get_config(gr,'muc_filter_censor_prs')
|
||||
need_raw = False
|
||||
muc_pprint('MUC-Filter prs censor (%s): %s [%s] %s' % (act,jid,room,'%s|%s' % (status,nick)),'brown')
|
||||
if act == 'replace':
|
||||
if len(status):
|
||||
status = esc_max2(to_censore(esc_min2(status),gr))
|
||||
msg = msg.replace(get_tag_full(msg,'status'),'<status>%s</status>' % status).replace(esc_max2(tojid),'%s/%s' % (tojid.split('/',1)[0],to_censore(esc_max2(nick),gr)))
|
||||
else: msg = msg.replace(esc_max2(tojid),'%s/%s' % (tojid.split('/',1)[0],to_censore(esc_max2(nick),gr)))
|
||||
elif newjoin: msg,mute = unicode(xmpp.Node('presence', {'from': tojid, 'type': 'error', 'to':jid}, payload = ['replace_it',xmpp.Node('error', {'type': 'auth','code':'403'}, payload=[xmpp.Node('forbidden',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[]),xmpp.Node('text',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[L('Blocked by censor!',rn)])])])).replace('replace_it',get_tag(msg,'presence')),True
|
||||
elif act == 'mute': msg,mute = None,True
|
||||
else: msg = muc_filter_action(act,jid,room,L('Blocked by censor!',rn))
|
||||
|
||||
# Raw censor filter
|
||||
if not mute and msg and need_raw and get_config(gr,'muc_filter_censor_prs_raw') != 'off':
|
||||
rawstatus = match_for_raw(status,u'[a-zа-я0-9]*',gr)
|
||||
rawnick = match_for_raw(nick,u'[a-zа-я0-9]*',gr)
|
||||
if (rawstatus or rawnick) and '%s|%s' % (rawstatus,rawnick) != to_censore('%s|%s' % (rawstatus,rawnick),gr):
|
||||
act = get_config(gr,'muc_filter_censor_prs_raw')
|
||||
muc_pprint('MUC-Filter prs raw censor (%s): %s [%s] %s' % (act,jid,room,nick+'|'+status),'brown')
|
||||
if newjoin: msg,mute = unicode(xmpp.Node('presence', {'from': tojid, 'type': 'error', 'to':jid}, payload = ['replace_it',xmpp.Node('error', {'type': 'auth','code':'403'}, payload=[xmpp.Node('forbidden',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[]),xmpp.Node('text',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[L('Blocked by censor!',rn)])])])).replace('replace_it',get_tag(msg,'presence')),True
|
||||
elif act == 'mute': msg,mute = None,True
|
||||
else: msg = muc_filter_action(act,jid,room,L('Blocked by raw censor!',rn))
|
||||
|
||||
# Large status filter
|
||||
if not mute and msg and get_config(gr,'muc_filter_large_status') != 'off' and len(esc_min2(status)) > GT('muc_filter_large_status_size'):
|
||||
act = get_config(gr,'muc_filter_large_status')
|
||||
muc_pprint('MUC-Filter large status (%s): %s [%s] %s' % (act,jid,room,status),'brown')
|
||||
if act == 'truncate': msg = msg.replace(get_tag_full(msg,'status'),u'<status>%s…</status>' % esc_max2(esc_min2(status)[:GT('muc_filter_large_status_size')]))
|
||||
elif newjoin: msg,mute = unicode(xmpp.Node('presence', {'from': tojid, 'type': 'error', 'to':jid}, payload = ['replace_it',xmpp.Node('error', {'type': 'auth','code':'403'}, payload=[xmpp.Node('forbidden',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[]),xmpp.Node('text',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[L('Large status block!',rn)])])])).replace('replace_it',get_tag(msg,'presence')),True
|
||||
elif act == 'mute': msg,mute = None,True
|
||||
else: msg = muc_filter_action(act,jid,room,L('Large status block!',rn))
|
||||
|
||||
# Large nick filter
|
||||
if not mute and msg and get_config(gr,'muc_filter_large_nick') != 'off' and len(esc_min2(nick)) > GT('muc_filter_large_nick_size'):
|
||||
act = get_config(gr,'muc_filter_large_nick')
|
||||
if act == 'truncate': msg = msg.replace(esc_max2(tojid),u'%s/%s…' % (tojid.split('/',1)[0],esc_max2(esc_min2(nick)[:GT('muc_filter_large_nick_size')])))
|
||||
elif newjoin: msg,mute = unicode(xmpp.Node('presence', {'from': tojid, 'type': 'error', 'to':jid}, payload = ['replace_it',xmpp.Node('error', {'type': 'auth','code':'403'}, payload=[xmpp.Node('forbidden',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[]),xmpp.Node('text',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[L('Large nick block!',rn)])])])).replace('replace_it',get_tag(msg,'presence')),True
|
||||
elif act == 'mute': msg,mute = None,True
|
||||
else: msg = muc_filter_action(act,jid,room,L('Large nick block!',rn))
|
||||
|
||||
# Rejoin filter
|
||||
if not mute and msg and get_config(gr,'muc_filter_rejoin') and newjoin:
|
||||
ttojid = '%s|%s' % (getRoom(tojid),getRoom(jid))
|
||||
try: muc_rejoins[ttojid] = [muc_rejoins[ttojid],muc_rejoins[ttojid][1:]][len(muc_rejoins[ttojid])==GT('muc_filter_rejoin_count')] + [int(time.time())]
|
||||
except: muc_rejoins[ttojid] = []
|
||||
if len(muc_rejoins[ttojid]) == GT('muc_filter_rejoin_count'):
|
||||
tmo = muc_rejoins[ttojid][GT('muc_filter_rejoin_count')-1] - muc_rejoins[ttojid][0]
|
||||
if tmo < GT('muc_filter_rejoin_timeout'):
|
||||
msg,mute = unicode(xmpp.Node('presence', {'from': tojid, 'type': 'error', 'to':jid}, payload = ['replace_it',xmpp.Node('error', {'type': 'auth','code':'403'}, payload=[xmpp.Node('forbidden',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[]),xmpp.Node('text',{'xmlns':'urn:ietf:params:xml:ns:xmpp-stanzas'},[L('To many rejoins! Wait %s sec.',rn) % GT('muc_filter_rejoin_timeout')])])])).replace('replace_it',get_tag(msg,'presence')),True
|
||||
muc_pprint('MUC-Filter rejoin: %s [%s] %s' % (jid,room,nick),'brown')
|
||||
|
||||
# Status filter
|
||||
if not mute and msg and get_config(gr,'muc_filter_repeat_prs') != 'off' and not newjoin:
|
||||
ttojid = '%s|%s' % (getRoom(tojid),getRoom(jid))
|
||||
try: muc_statuses[ttojid] = [muc_statuses[ttojid],muc_statuses[ttojid][1:]][len(muc_statuses[ttojid])==GT('muc_filter_status_count')] + [int(time.time())]
|
||||
except: muc_statuses[ttojid] = []
|
||||
if len(muc_statuses[ttojid]) == GT('muc_filter_status_count'):
|
||||
tmo = muc_statuses[ttojid][GT('muc_filter_status_count')-1] - muc_statuses[ttojid][0]
|
||||
if tmo < GT('muc_filter_status_timeout'):
|
||||
act = get_config(gr,'muc_filter_repeat_prs')
|
||||
muc_pprint('MUC-Filter status (%s): %s [%s] %s' % (act,jid,room,nick),'brown')
|
||||
if act == 'mute': msg,mute = None,True
|
||||
else: msg = muc_filter_action(act,jid,room,L('Status-flood block!',rn))
|
||||
|
||||
if msg:
|
||||
i=xmpp.Iq(to=room, typ='result')
|
||||
i.setAttr(key='id', val=id)
|
||||
i.setTag('query',namespace=xmpp.NS_MUC_FILTER).setTagData(tag='message', val='')
|
||||
try: return unicode(i).replace('<message />',msg)
|
||||
except: pass
|
||||
|
||||
return None
|
||||
|
||||
global iq_hook
|
||||
|
||||
iq_hook = [[200,'set',muc_filter_set]]
|
||||
126
plugins/net.py
Normal file
126
plugins/net.py
Normal file
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def vendor_by_mac(type, jid, nick, text):
|
||||
text = text.strip().replace('-','').replace(':','').replace(' ','')[:6].upper()
|
||||
if text and len(text) == 6:
|
||||
result = html_encode(load_page('http://standards.ieee.org/cgi-bin/ouisearch?%s' % text))
|
||||
r = re.findall('\(hex\)(.*?)\n',result,re.S|re.I)
|
||||
if 'Sorry!' in result and not r: msg = L('Not found!','%s/%s'%(jid,nick))
|
||||
else: msg = r[0].strip().upper()
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def net_ping(type, jid, nick, text):
|
||||
text = text.strip().lower().encode('idna')
|
||||
if '.' in text and len(text) > 4 and re.match(r'[-0-9a-z.]+\Z', text, re.U+re.I): msg = deidna(shell_execute('ping -c4 %s' % text,'%s/%s'%(jid,nick)))
|
||||
else: msg = L('Smoke help about command!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def get_tld(type, jid, nick, text):
|
||||
if len(text) >= 2:
|
||||
tld = readfile(tld_list).decode('utf-8')
|
||||
tld = tld.split('\n')
|
||||
msg = L('Not found!','%s/%s'%(jid,nick))
|
||||
for tl in tld:
|
||||
if tl.split('\t')[0].lower()==text.lower():
|
||||
msg = '.'+tl.replace('\t',' - ',1).replace('\t','\n')
|
||||
break
|
||||
else: msg = L('What do you want to find?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def get_dns(type, jid, nick, text):
|
||||
is_ip = None
|
||||
if text.count('.') == 3:
|
||||
is_ip = True
|
||||
for ii in text:
|
||||
if not nmbrs.count(ii):
|
||||
is_ip = None
|
||||
break
|
||||
if is_ip:
|
||||
try: msg = socket.gethostbyaddr(text)[0]
|
||||
except: msg = L('I can\'t resolve it','%s/%s'%(jid,nick))
|
||||
else:
|
||||
try:
|
||||
ans = socket.gethostbyname_ex(text.encode('idna'))[2]
|
||||
msg = text+' - '
|
||||
for an in ans: msg += an + ' | '
|
||||
msg = msg[:-2]
|
||||
except: msg = L('I can\'t resolve it','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def srv_nslookup(type, jid, nick, text):
|
||||
srv_raw_check(type, jid, nick, 'nslookup '+text)
|
||||
|
||||
def srv_dig(type, jid, nick, text):
|
||||
srv_raw_check(type, jid, nick, 'dig '+text)
|
||||
|
||||
def srv_host(type, jid, nick, text):
|
||||
srv_raw_check(type, jid, nick, 'host '+text)
|
||||
|
||||
def srv_raw_check(type, jid, nick, text):
|
||||
text = enidna_raw(text)
|
||||
text = ''.join(re.findall(u'[-a-z0-9\.\_\?\#\=\@\%\ \+]+',text,re.S|re.I)[0])
|
||||
send_msg(type, jid, nick, deidna(shell_execute(text,'%s/%s'%(jid,nick))))
|
||||
|
||||
def chkserver(type, jid, nick, text):
|
||||
for a in ':;&/|\\\n\t\r': text = text.replace(a,' ')
|
||||
t = re.findall(u'[-a-zа-я0-9._?#=@%]+',text,re.S|re.I|re.U)
|
||||
if len(t) >= 2:
|
||||
port = []
|
||||
for a in t:
|
||||
if a.isdigit(): port.append(a)
|
||||
for a in port: t.remove(a)
|
||||
if len(t)==1 and len(port)>=1:
|
||||
t = t[0]
|
||||
port.sort()
|
||||
msg = shell_execute('nmap %s -p%s -P0 -T5' % (t.encode('idna'),','.join(port)),'%s/%s'%(jid,nick))
|
||||
try: msg = '%s\n%s' % (t.encode('idna'),reduce_spaces_all(re.findall('SERVICE(.*)Nmap',msg,re.S|re.U)[0][1:-2]))
|
||||
except:
|
||||
try:
|
||||
msg = ''
|
||||
for a in port:
|
||||
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
|
||||
try:
|
||||
sock.connect((t.encode('idna'),int(a)))
|
||||
s = L('on','%s/%s'%(jid,nick))
|
||||
except: s = L('off','%s/%s'%(jid,nick))
|
||||
msg += '\n%s %s' % (a,s)
|
||||
sock.close()
|
||||
msg = '%s%s' % (t,msg)
|
||||
except: msg = '%s - %s' % (t,L('unknown','%s/%s'%(jid,nick)))
|
||||
msg = L('Port status at %s','%s/%s'%(jid,nick)) % msg
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(6, 'nslookup', srv_nslookup, 2, 'Command nslookup'),
|
||||
(6, 'host', srv_host, 2, 'Command host'),
|
||||
(6, 'dig', srv_dig, 2, 'Command dig'),
|
||||
(4, 'port', chkserver, 2, 'Check port activity\nport server port1 [port2 ...]'),
|
||||
(4, 'net_ping', net_ping, 2, 'Net Ping.\nnet_ping ip|domain'),
|
||||
(3, 'dns', get_dns, 2, 'DNS resolver.'),
|
||||
(3, 'tld', get_tld, 2, 'Search domain zones TLD.'),
|
||||
(3, 'mac', vendor_by_mac, 2, 'Show vendor of device by mac')]
|
||||
37
plugins/oboobs.py
Normal file
37
plugins/oboobs.py
Normal file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def oboobs(type, jid, nick):
|
||||
try: msg = 'http://media.oboobs.ru/%s' % json.loads(load_page('http://api.oboobs.ru/noise/1/'))[0]['preview']
|
||||
except: msg = L('Error!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def obutts(type, jid, nick):
|
||||
try: msg = 'http://media.obutts.ru/%s' % json.loads(load_page('http://api.obutts.ru/noise/1/'))[0]['preview']
|
||||
except: msg = L('Error!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'oboobs', oboobs, 1, 'Show random picture from oboobs.ru'),
|
||||
(3, 'obutts', obutts, 1, 'Show random picture from obutts.ru')]
|
||||
37
plugins/paste.py
Normal file
37
plugins/paste.py
Normal file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def private_paste(type, jid, nick, text):
|
||||
if type == 'groupchat': msg = L('This command available only in private!','%s/%s'%(jid,nick))
|
||||
else: msg = paste_text(text,jid,get_level(jid,nick)[1])
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def public_paste(type, jid, nick, text):
|
||||
if type == 'groupchat': msg = L('This command available only in private!','%s/%s'%(jid,nick))
|
||||
else: msg,type,nick = L('%s pasted by %s','%s/%s'%(jid,nick)) % (paste_text(text,jid,get_level(jid,nick)[1]),nick),'groupchat',''
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(4, 'paste', public_paste, 2, 'Paste some text to server'),
|
||||
(5, 'ppaste', private_paste, 2, 'Paste some text to server')]
|
||||
129
plugins/phone.py
Normal file
129
plugins/phone.py
Normal file
@@ -0,0 +1,129 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
phone_short_format = '%s%s%s-%s%s-%s%s'
|
||||
phone_ru_format = '+%s (%s%s%s) ' + phone_short_format
|
||||
phone_ua_format = '+%s%s (%s%s%s) ' + phone_short_format
|
||||
|
||||
def phonecode(type, jid, nick, text):
|
||||
if len(text):
|
||||
def_info,country = L('Not found!','%s/%s'%(jid,nick)),L('Unknown','%s/%s'%(jid,nick))
|
||||
if text[0] == '+': text = text[1:]
|
||||
if text.isdigit():
|
||||
if text[0] == '7':
|
||||
if len(text) > 1 and text[1] == '9':
|
||||
country = L('Russia, Mobile','%s/%s'%(jid,nick))
|
||||
if len(text) >= 5:
|
||||
dc, pn = text[1:4], text[4:]
|
||||
if len(pn) < 7: pn = pn.ljust(7, '0')
|
||||
elif len(pn) > 7: pn = pn[:7]
|
||||
result = cur_execute_fetchall('select * from def_ru_mobile where def=%s and defbegin<=%s and defend>=%s', (dc,pn,pn))
|
||||
if result:
|
||||
def pfs(t): return phone_short_format % tuple('%07d' % t)
|
||||
def_info = '\n'.join(['%s, %s (%s) %s..%s, %s ' % (res[0],res[1],res[2],pfs(res[3]),pfs(res[4]),res[5]) for res in result])
|
||||
else: def_info = L('Too many results!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
country = L('Russia','%s/%s'%(jid,nick))
|
||||
if len(text) < 11: text = text.ljust(12, '2')
|
||||
elif len(text) > 11: text = text[:11]
|
||||
text = text[:7] + 'x'*4
|
||||
pos = 7
|
||||
while pos:
|
||||
result = cur_execute_fetchall('select * from def_ru_stat where phone ilike %s', ('%s%%'%text,))
|
||||
if result:
|
||||
def_info = []
|
||||
for res in result:
|
||||
res = list(res)
|
||||
while '' in res: res.remove('')
|
||||
res[0] = phone_ru_format % tuple(res[0])
|
||||
def_info += [', '.join(res)]
|
||||
def_info = '\n'.join(def_info)
|
||||
break
|
||||
else:
|
||||
text = list(text)
|
||||
text[pos] = 'x'
|
||||
text = ''.join(text)
|
||||
pos -= 1
|
||||
elif text[:3] == '380':
|
||||
country = L('Ukraine','%s/%s'%(jid,nick))
|
||||
if len(text) < 12: text = text.ljust(12, '2')
|
||||
elif len(text) > 12: text = text[:12]
|
||||
text = text[:8]+'x'*4
|
||||
pos = 8
|
||||
while pos > 2:
|
||||
result = cur_execute_fetchall('select * from def_ua_stat where phone ilike %s', ('%s%%'%text,))
|
||||
if result:
|
||||
def_info = []
|
||||
for res in result:
|
||||
res = list(res)
|
||||
while '' in res: res.remove('')
|
||||
res[0] = phone_ua_format % tuple(res[0])
|
||||
def_info += [', '.join(res)]
|
||||
def_info = '\n'.join(def_info)
|
||||
break
|
||||
else:
|
||||
text = list(text)
|
||||
text[pos] = 'x'
|
||||
text = ''.join(text)
|
||||
pos -= 1
|
||||
if country == L('Unknown','%s/%s'%(jid,nick)): result = def_info
|
||||
elif def_info == L('Not found!','%s/%s'%(jid,nick)): result = L('Country: %s, Phone number not found','%s/%s'%(jid,nick)) % (country,)
|
||||
else: result = L('Country: %s\n%s','%s/%s'%(jid,nick)) % (country,def_info)
|
||||
else:
|
||||
text = '%s%%'%text.lower().capitalize()
|
||||
def_info = []
|
||||
result = cur_execute_fetchall('select * from def_ru_stat where city ilike %s', (text,))
|
||||
if result:
|
||||
di = []
|
||||
for res in result:
|
||||
res = list(res)
|
||||
while '' in res: res.remove('')
|
||||
res[0] = phone_ru_format % tuple(res[0])
|
||||
di += [', '.join(res)]
|
||||
di = '\n'.join(di)
|
||||
def_info += [L('Country: %s\n%s','%s/%s'%(jid,nick)) % (L('Russia','%s/%s'%(jid,nick)),di)]
|
||||
result = cur_execute_fetchall('select * from def_ua_stat where city ilike %s', (text,))
|
||||
if result:
|
||||
di = []
|
||||
for res in result:
|
||||
res = list(res)
|
||||
while '' in res: res.remove('')
|
||||
res[0] = phone_ua_format % tuple(res[0])
|
||||
di += [', '.join(res)]
|
||||
di = '\n'.join(di)
|
||||
def_info += [L('Country: %s\n%s','%s/%s'%(jid,nick)) % (L('Ukraine','%s/%s'%(jid,nick)),di)]
|
||||
#result = cur_execute_fetchall('select * from def_ru_mobile where provider ilike %s or region ilike %s', (text,text))
|
||||
#if result:
|
||||
# di = []
|
||||
# for res in result: di += ['%s, %s (%s) %s..%s, %s ' % res]
|
||||
# di = '\n'.join(di)
|
||||
# def_info += [L('Country: %s\n%s','%s/%s'%(jid,nick)) % (L('Russia, Mobile','%s/%s'%(jid,nick)),di)]
|
||||
if def_info: result = '\n\n'.join(def_info)
|
||||
else: result = L('Not found!','%s/%s'%(jid,nick))
|
||||
msg = result
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'phone', phonecode, 2, 'Information about telephone city code, DEF code or search code for city.')]
|
||||
86
plugins/psto.py
Normal file
86
plugins/psto.py
Normal file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
PSTO_JID = 'psto@psto.net/Psto'
|
||||
PSTO_ERROR = '\nYou cannot read this psto.'
|
||||
psto_msg_trunc = 64
|
||||
psto_id = {}
|
||||
|
||||
def psto(type, jid, nick, text):
|
||||
global psto_id
|
||||
if not len(text) or len(text) == text.count(' '):
|
||||
send_msg(type, jid, nick, L('What message do you want to find?','%s/%s'%(jid,nick)))
|
||||
return
|
||||
try:
|
||||
psto_idn,psto_comm = re.findall('#?([a-z]{5,})\/?([0-9]*\-*[0-9]*)?',text)[0]
|
||||
if psto_idn:
|
||||
psto_id[psto_idn] = '%s\n%s\n%s\n%s' % (type,jid,nick,psto_comm)
|
||||
send_msg('chat', PSTO_JID, '', '#%s+' % psto_idn)
|
||||
else: send_msg(type, jid, nick, L('Smoke help about command!','%s/%s'%(jid,nick)))
|
||||
except: send_msg(type, jid, nick, L('Smoke help about command!','%s/%s'%(jid,nick)))
|
||||
|
||||
def psto_catch(room,jid,nick,type,text):
|
||||
global psto_id
|
||||
if '%s/%s' % (room,nick) != PSTO_JID: return
|
||||
if text == PSTO_ERROR:
|
||||
(type,jid,nick,psto_comm) = psto_id.popitem()[1].split('\n')
|
||||
send_msg(type, jid, nick, text[1:])
|
||||
else:
|
||||
try:
|
||||
psto_idn, text = text.split(' ',1)[0][2:],text[1:]
|
||||
(type,jid,nick,psto_comm) = psto_id.pop(psto_idn).split('\n')
|
||||
splitter = re.findall('http\:\/\/[-a-z0-9]+?\.psto\.net\/%s' % psto_idn, text, re.S|re.I|re.U)[0]
|
||||
while '\n\n' in text: text = text.replace('\n\n','\n')
|
||||
while '\n ' in text: text = text.replace('\n ','\n')
|
||||
if psto_comm:
|
||||
new_text = text.split(splitter)[0][:-1]
|
||||
comment = new_text.split('\n')[-1]
|
||||
new_text = '\n'.join(new_text.split('\n')[:-1])
|
||||
if len(new_text) > psto_msg_trunc: new_text = new_text[:psto_msg_trunc] + u'…'
|
||||
new_text += '\n%s | %s' % (comment,splitter)
|
||||
if '-' in psto_comm: psto_comm = psto_comm.split('-',1)
|
||||
else: psto_comm = [psto_comm,psto_comm]
|
||||
if not psto_comm[0]: psto_comm[0] = '1'
|
||||
if not psto_comm[1]: psto_comm[1] = str(len(text.split(psto_idn)))
|
||||
if len(psto_comm[0]) > 3: psto_comm[0] = psto_comm[0][:3]
|
||||
if len(psto_comm[1]) > 3: psto_comm[1] = psto_comm[1][:3]
|
||||
msg = ''
|
||||
for tmp in range(int(psto_comm[0]),int(psto_comm[1])+1):
|
||||
try: msg += u'• #%s/%s %s' % (psto_idn,tmp,text.split(splitter)[1].split('#%s/%s' % (psto_idn,tmp))[1].split('#%s/%s' % (psto_idn,tmp+1))[0].replace('\n',' ',1))
|
||||
except: pass
|
||||
new_text += '\n' + msg
|
||||
else: new_text = text.split(splitter)[0][:-1] + ' ' + splitter
|
||||
send_msg(type, jid, nick, new_text)
|
||||
except: pass
|
||||
|
||||
def psto_post(type, jid, nick, text):
|
||||
send_msg('chat', PSTO_JID, '', text)
|
||||
time.sleep(1.2)
|
||||
send_msg(type, jid, nick, L('Message posted to Psto.','%s/%s'%(jid,nick)))
|
||||
|
||||
global execute,message_control
|
||||
|
||||
message_control = [psto_catch]
|
||||
|
||||
execute = [(3, 'psto', psto, 2, 'Miniblogs http://psto.net\npsto [#]post[/[from_comment][-][to_comment]] - show post'),
|
||||
(9, 'psto_post', psto_post, 2, 'Send message to blog at psto.net')]
|
||||
78
plugins/quotes.py
Normal file
78
plugins/quotes.py
Normal file
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) Vit@liy <vitaliy@root.ua> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
try: quotes_list = json.loads(readfile(data_folder % 'quotes.txt'),encoding='utf-8')
|
||||
except:
|
||||
quotes_list = {'bash':
|
||||
{'title': u'bash.org.ru - Цитатник Рунета',
|
||||
'random': ['http://bash.org.ru/random', '<div\ class="text">((?:.|\\s)+?)</div>'],
|
||||
'number': ['http://bash.org.ru/quote/%s', '<div\ class="text">((?:.|\\s)+?)</div>']}}
|
||||
|
||||
def quote(type, jid, nick, text):
|
||||
global quotes_list
|
||||
tmp = text.strip().split()
|
||||
if not tmp: tmp =[random.choice([q for q in quotes_list.keys() if quotes_list[q].has_key('random')])]
|
||||
if len(tmp) == 1 and tmp[0] == 'list':
|
||||
msg = (L('Quotes:\n','%s/%s'%(jid,nick)) + '\n'.join(['%s - %s (%s)' % (q, quotes_list[q]['title'],
|
||||
', '.join(k for k in quotes_list[q].keys() if k != 'title').replace('random', L('rand','%s/%s'%(jid,nick))).replace('number', L('by number','%s/%s'%(jid,nick))).replace('search', L('search','%s/%s'%(jid,nick))))
|
||||
for q in sorted(quotes_list.keys())]))
|
||||
elif len(tmp) == 1 and quotes_list.has_key(tmp[0]) and quotes_list[tmp[0]].has_key('random'):
|
||||
try:
|
||||
url = quotes_list[tmp[0]]['random'][0]
|
||||
body = html_encode(load_page(url))
|
||||
message = re.search(unescape(quotes_list[tmp[0]]['random'][1]), body).group(1)
|
||||
msg = unhtml(message)
|
||||
except:
|
||||
msg = L('Can\'t searching random quote!','%s/%s'%(jid,nick))
|
||||
elif len(tmp) > 1 and quotes_list.has_key(tmp[0]) and quotes_list[tmp[0]].has_key('number') and re.match('\d+\Z', tmp[1]):
|
||||
try:
|
||||
url = quotes_list[tmp[0]]['number'][0] % tmp[1]
|
||||
body = html_encode(load_page(url))
|
||||
message = re.search(unescape(quotes_list[tmp[0]]['number'][1]), body).group(1)
|
||||
msg = unhtml(message)
|
||||
if not msg:
|
||||
msg = L('Can\'t searching quote by number!','%s/%s'%(jid,nick))
|
||||
except:
|
||||
msg = L('Can\'t searching quote by number!','%s/%s'%(jid,nick))
|
||||
elif len(tmp) > 1 and quotes_list.has_key(tmp[0]) and quotes_list[tmp[0]].has_key('search'):
|
||||
try:
|
||||
url = quotes_list[tmp[0]]['search'][0] % urllib.quote(tmp[1].encode(quotes_list[tmp[0]]['search'][2]))
|
||||
body = html_encode(load_page(url))
|
||||
message = re.search(unescape(quotes_list[tmp[0]]['search'][1]), body).group(1)
|
||||
msg = unhtml(message)
|
||||
except:
|
||||
msg = L('Quote not found!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
|
||||
def ithap(type, jid, nick, text): quote(type, jid, nick, 'ithap %s' % text)
|
||||
|
||||
def afor(type, jid, nick): quote(type, jid, nick, 'afor')
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'quote', quote, 2, 'Quote from Internet. Exaples:\nquote list - list of resources\nquote [<key> [number|text]]'),
|
||||
(3, 'ithap', ithap, 2, 'Quote from ithappens.ru\nithap [number]'),
|
||||
(3, 'afor', afor, 1, 'Show random aphorism from skio.ru')]
|
||||
35
plugins/redirect.py
Normal file
35
plugins/redirect.py
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def to_private(type, room, nick, text): raw_redirect('chat', room, nick, text)
|
||||
|
||||
def to_public(type, room, nick, text): raw_redirect('groupchat', room, nick, text)
|
||||
|
||||
def raw_redirect(type, room, nick, text):
|
||||
access_mode,jid = get_level(room,nick)
|
||||
com_parser(access_mode, get_xnick(room), type, room, nick, text, jid)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'private', to_private, 2, 'Redirect command output in private.'),
|
||||
(3, 'public', to_public, 2, 'Redirect command output in groupchat.')]
|
||||
46
plugins/say.py
Normal file
46
plugins/say.py
Normal file
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def say(type, jid, nick, text):
|
||||
text = random.choice(re.split(r'(?<!\\)\|', text)).replace('\\|', '|')
|
||||
send_msg('groupchat', jid, '', to_censore(text,jid))
|
||||
|
||||
def psay(type, jid, nick, text):
|
||||
try:
|
||||
if '\n' in text: nnick,ntext = text.split('\n',1)
|
||||
else: nnick,ntext = text.split(' ',1)
|
||||
send_msg('chat', jid, nnick, to_censore(ntext,jid))
|
||||
except: send_msg(type, jid, nick, L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick)))
|
||||
|
||||
def gsay(type, jid, nick, text):
|
||||
for jjid in [t[0] for t in cur_execute_fetchall('select room from conference;')]: send_msg('groupchat', getRoom(jjid), '', text)
|
||||
|
||||
def set_topic(type, jid, nick, text):
|
||||
sender(xmpp.Message(jid, subject=text, typ='groupchat'))
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(6, 'say', say, 2, '"Say" command. Bot say in conference text after command. Example:\nsay text1[|text2[|text3[...]]]'),
|
||||
(6, 'psay', psay, 2, '"Say" command. Bot say in private all text after command.\npsay <nick>\ntext'),
|
||||
(9, 'gsay', gsay, 2, 'Global message in all conferences, where bot is present.'),
|
||||
(7, 'topic', set_topic, 2, 'Set conference topic.')]
|
||||
149
plugins/sayto.py
Normal file
149
plugins/sayto.py
Normal file
@@ -0,0 +1,149 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
last_cleanup_sayto_base = 0
|
||||
|
||||
def sayto(type, jid, nick, text):
|
||||
while len(text) and text[0] == '\n': text=text[1:]
|
||||
while len(text) and (text[-1] == '\n' or text[-1] == ' '): text=text[:-1]
|
||||
|
||||
if text.split(' ')[0] == 'show':
|
||||
try: text = text.split(' ',1)[1]
|
||||
except: text = ''
|
||||
ga = get_level(jid, nick)
|
||||
if ga[0] != 9: msg = L('You access level is to low!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
cm = cur_execute_fetchall('select * from sayto')
|
||||
if len(cm):
|
||||
msg = ''
|
||||
for cc in cm:
|
||||
zz = cc[0].split('\n')
|
||||
tmsg = '\n' + cc[1] +'/'+ zz[0] +' ('+un_unix(time.time()-int(zz[1]),'%s/%s'%(jid,nick))+'|'+un_unix(GT('sayto_timeout')-(time.time()-int(zz[1])),'%s/%s'%(jid,nick))+') '+L('for','%s/%s'%(jid,nick))+' '+cc[2]+' - '+cc[3]
|
||||
if len(text) and text.lower() in tmsg.lower(): msg += tmsg
|
||||
elif not len(text): msg += tmsg
|
||||
if len(msg): msg = L('Not transfered messages: %s','%s/%s'%(jid,nick)) % msg
|
||||
else: msg = L('Not found!','%s/%s'%(jid,nick))
|
||||
if type == 'groupchat':
|
||||
send_msg('chat', jid, nick, msg)
|
||||
msg = L('Sent in private message','%s/%s'%(jid,nick))
|
||||
else: msg = L('List is empty.','%s/%s'%(jid,nick))
|
||||
elif ' ' in text or '\n' in text:
|
||||
if '\n' in text: splitter = '\n'
|
||||
else: splitter = ' '
|
||||
to,what = text.split(splitter,1)[0],text.split(splitter,1)[1]
|
||||
frm = '%s\n%s' % (nick,int(time.time()))
|
||||
fnd = cur_execute_fetchall('select jid, status from age where room=%s and nick=%s group by jid, status',(jid,to))
|
||||
if len(fnd) == 1:
|
||||
if fnd[0][1]:
|
||||
msg = L('I will convey your message.','%s/%s'%(jid,nick))
|
||||
cur_execute('insert into sayto values (%s,%s,%s,%s)', (frm, jid, fnd[0][0], what))
|
||||
else: msg = L('Or am I a fool or %s is here.','%s/%s'%(jid,nick)) % to
|
||||
elif len(fnd) > 1:
|
||||
off_count = 0
|
||||
for tmp in fnd:
|
||||
if tmp[1]:
|
||||
cur_execute('insert into sayto values (%s,%s,%s,%s)', (frm, jid, tmp[0], what))
|
||||
off_count += 1
|
||||
if off_count: msg = L('I seen some people with this nick, and I can convey is incorrect. Coincidence: %s, and count convey messages: %s','%s/%s'%(jid,nick)) % (str(len(fnd)), str(off_count))
|
||||
else: msg = L('All people with this nickname are here!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
if '@' in to:
|
||||
fnd = cur_execute_fetchall('select jid, status from age where room=%s and jid=%s group by jid,status',(jid,to))
|
||||
if fnd:
|
||||
off_count = 0
|
||||
for tmp in fnd:
|
||||
if tmp[1]:
|
||||
cur_execute('insert into sayto values (%s,%s,%s,%s)', (frm, jid, tmp[0], what))
|
||||
off_count += 1
|
||||
if off_count: msg = L('I will convey your message.','%s/%s'%(jid,nick))
|
||||
else: msg = L('This jid is here!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
msg = L('I didn\'t seen user with jid %s, but if he join here I convey your message.','%s/%s'%(jid,nick)) % to
|
||||
cur_execute('insert into sayto values (%s,%s,%s,%s)', (frm, jid, to, what))
|
||||
else: msg = L('I didn\'t see user with nick %s. You can use jid.','%s/%s'%(jid,nick)) % to
|
||||
else: msg = L('What convey to?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def say_memo(type, jid, nick, text):
|
||||
while len(text) and text[0] == '\n': text=text[1:]
|
||||
while len(text) and (text[-1] == '\n' or text[-1] == ' '): text=text[:-1]
|
||||
gj = getRoom(get_level(jid, nick)[1])
|
||||
if text.split(' ')[0] == 'show':
|
||||
try: text = text.split(' ',1)[1]
|
||||
except: text = ''
|
||||
t = cur_execute_fetchall('select message,jid from sayto where room=%s and jid ilike %s', (jid,gj))
|
||||
if t: msg = '\n%s' % '\n'.join([u'• %s' % tmp[0] for tmp in t])
|
||||
else: msg = L('There is no memo for you!','%s/%s'%(jid,nick))
|
||||
elif text:
|
||||
cur_execute('insert into sayto values (%s,%s,%s,%s)', ('\n%s' % int(time.time()), jid, gj, text))
|
||||
msg = L('I\'ll remember it to you.','%s/%s'%(jid,nick))
|
||||
else: msg = L('What remember to you?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def sayto_presence(room,jid,nick,type,text):
|
||||
global conn
|
||||
if nick != '' and type != 'unavailable':
|
||||
cm = cur_execute_fetchall('select * from sayto where room=%s and (jid=%s or jid=%s)',(room, getRoom(jid), nick))
|
||||
if cm:
|
||||
cur_execute('delete from sayto where room=%s and (jid=%s or jid=%s)',(room, getRoom(jid), nick))
|
||||
for cc in cm:
|
||||
if '\n' in cc[0]:
|
||||
zz = cc[0].split('\n')
|
||||
if zz[0]: msg = L('%s (%s ago) convey for you: %s','%s/%s'%(room,nick)) % (zz[0], un_unix(time.time()-int(zz[1]),'%s/%s'%(room,nick)), cc[3])
|
||||
else: msg = L('You ask remember: %s','%s/%s'%(room,nick)) % cc[3]
|
||||
else: msg = L('%s convey for you: %s','%s/%s'%(room,nick)) % (cc[3], cc[0])
|
||||
send_msg('chat', room, nick, msg)
|
||||
|
||||
def cleanup_sayto_base():
|
||||
global last_cleanup_sayto_base
|
||||
ctime = int(time.time())
|
||||
if ctime-last_cleanup_sayto_base > GT('sayto_cleanup_time'):
|
||||
last_cleanup_sayto_base = ctime
|
||||
cm = cur_execute_fetchall('select who, room, jid from sayto')
|
||||
if len(cm):
|
||||
for cc in cm:
|
||||
if '\n' in cc[0]:
|
||||
tim = int(cc[0].split('\n')[1])
|
||||
if ctime-tim > GT('sayto_timeout'): cur_execute('delete from sayto where room=%s and jid=%s',(cc[1], cc[2]))
|
||||
else: cur_execute('delete from sayto where room=%s and jid=%s',(cc[1], cc[2]))
|
||||
|
||||
def sayjid(type, jid, nick, text):
|
||||
try:
|
||||
text = text.split(' ',1)
|
||||
if len(text) != 2: msg = L('Error!','%s/%s'%(jid,nick))
|
||||
elif '@' not in text[0] and '@' not in text[0]: msg = L('Error!','%s/%s'%(jid,nick))
|
||||
elif not len(text[1]): msg = L('Error!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
send_msg(type, jid, nick, L('Sent','%s/%s'%(jid,nick)))
|
||||
msg = L('%s from conference %s convey message for you: %s','%s/%s'%(jid,nick)) % (nick, jid, text[1])
|
||||
type, nick, jid = 'chat', '', text[0]
|
||||
except: msg = L('Error!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute, timer, presence_control
|
||||
|
||||
timer = [cleanup_sayto_base]
|
||||
presence_control = [sayto_presence]
|
||||
execute = [(3, 'sayto', sayto, 2, '"Say to" command.\nsayto jid|nick message - if jid or nick join in conference, bot send "message". Messages saves 14 days, after if message didn\'t be send this message remove.'),
|
||||
(7, 'sayjid', sayjid, 2, 'Send message to jid\n sayjid jid message.'),
|
||||
(3, 'memo', say_memo, 2, 'Send a message to yourself at next join')]
|
||||
36
plugins/setnick.py
Normal file
36
plugins/setnick.py
Normal file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def set_nickname(type, jid, nick, text):
|
||||
if get_affiliation(jid,nick) == 'owner' or get_level(jid,nick)[0] == 9:
|
||||
msg = None
|
||||
nickname = Settings['nickname']
|
||||
text = '%s/%s' % (jid, text or nickname)
|
||||
bot_join(type, jid, nick, text)
|
||||
else:
|
||||
msg = L('You can\'t do it!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(8, 'setnick', set_nickname, 2, 'Change bot nick. Available only for conference owner.')]
|
||||
37
plugins/shell.py
Normal file
37
plugins/shell.py
Normal file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def shell(type, jid, nick, text):
|
||||
sysshell(type, jid, nick, text, 1)
|
||||
|
||||
def shell_silent(type, jid, nick, text):
|
||||
sysshell(type, jid, nick, text, 0)
|
||||
|
||||
def sysshell(type, jid, nick, text, mode):
|
||||
msg = shell_execute(text,'%s/%s'%(jid,nick))
|
||||
if mode: send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
if not GT('paranoia_mode'): execute = [(9, 'sh', shell, 2, 'Execute shell command.'),
|
||||
(9, 'sh_silent', shell_silent, 2, 'Execute shell command without output result.')]
|
||||
44
plugins/shortlink.py
Normal file
44
plugins/shortlink.py
Normal file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
SHORT_TINYURL = 'http://tinyurl.com/api-create.php?url=%s'
|
||||
SHORT_CLCK = 'http://clck.ru/--?url=%s'
|
||||
SHORT_QR = 'http://chart.apis.google.com/chart?cht=qr&chs=350x350&chld=M|2&chl=%s'
|
||||
|
||||
def shorter_raw(type, jid, nick, text, url):
|
||||
text = text.strip()
|
||||
if text: msg = load_page(url % enidna(text).decode('utf-8'))
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def short_clck(type, jid, nick, text): shorter_raw(type, jid, nick, text, SHORT_CLCK)
|
||||
|
||||
def short_tinyurl(type, jid, nick, text): shorter_raw(type, jid, nick, text, SHORT_TINYURL)
|
||||
|
||||
def short_qr(type, jid, nick, text): shorter_raw(type, jid, nick, text, SHORT_TINYURL % SHORT_QR)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'clck', short_clck, 2, 'URL Shortener'),
|
||||
(3, 'tinyurl', short_tinyurl, 2, 'URL Shortener'),
|
||||
(3, 'qr', short_qr, 2, 'QR-code generator')]
|
||||
61
plugins/shutdown.py
Normal file
61
plugins/shutdown.py
Normal file
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def bot_shutdown(type, jid, nick, text, reason, xtype):
|
||||
global game_over,bot_exit_type
|
||||
StatusMessage = L('%s by command from %s','%s/%s'%(jid,nick)) % (reason, nick)
|
||||
if text != '': StatusMessage += ', ' + L('reason: %s','%s/%s'%(jid,nick)) % text
|
||||
send_presence_all(StatusMessage)
|
||||
bot_exit_type, game_over = xtype, True
|
||||
|
||||
def bot_exit(type, jid, nick, text):
|
||||
bot_shutdown(type, jid, nick, text, L('Shutdown','%s/%s'%(jid,nick)), 'exit')
|
||||
|
||||
def bot_restart(type, jid, nick, text):
|
||||
bot_shutdown(type, jid, nick, text, L('Restart','%s/%s'%(jid,nick)), 'restart')
|
||||
|
||||
def bot_update(type, jid, nick, text):
|
||||
bot_shutdown(type, jid, nick, text, L('Update','%s/%s'%(jid,nick)), 'update')
|
||||
|
||||
def bot_soft_update(type, jid, nick, text):
|
||||
global plugins_reload
|
||||
caps_and_send(xmpp.Presence(show='dnd', status=L('Soft update activated!','%s/%s'%(jid,nick)), priority=Settings['priority']))
|
||||
plugins_reload = True
|
||||
while not game_over and plugins_reload: time.sleep(1)
|
||||
if GT('soft_update_resend_hash'):
|
||||
pprint('*** Send new hash in to rooms','bright_green')
|
||||
cnf = cur_execute_fetchall('select * from conference;')
|
||||
for tocon in cnf:
|
||||
if tocon[1]: pprint('->- %s | pass: %s' % tocon,'green')
|
||||
else: pprint('->- %s' % tocon[0],'green')
|
||||
zz = join(tocon)
|
||||
if Settings['status'] == 'online': caps_and_send(xmpp.Presence(status=Settings['message'], priority=Settings['priority']))
|
||||
else: caps_and_send(xmpp.Presence(show=Settings['status'], status=Settings['message'], priority=Settings['priority']))
|
||||
send_msg(type, jid, nick, L('Soft update finished! Plugins loaded: %s. Commands: %s','%s/%s'%(jid,nick)) % (len(plugins)+1,len(comms)))
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(9, 'quit', bot_exit, 2, 'Shutting down the bot. You can set reason.'),
|
||||
(9, 'restart', bot_restart, 2, 'Restart the bot. You can set reason.'),
|
||||
(9, 'update', bot_update, 2, 'Update from VCS. You can set reason.'),
|
||||
(9, 'soft_update', bot_soft_update, 2, 'Soft update from VCS.')]
|
||||
55
plugins/sokr.py
Normal file
55
plugins/sokr.py
Normal file
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) Vit@liy <vitaliy@root.ua> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def sokr(type, jid, nick, text):
|
||||
target = ''
|
||||
text = text.strip()
|
||||
if not text: msg = L('What?','%s/%s'%(jid,nick))
|
||||
else:
|
||||
if re.search('\A\d+?(-\d+?)? ', text): target, text = text.split(' ', 1)
|
||||
if re.match('[a-zA-Z]+\Z', text):
|
||||
data = load_page('http://www.abbreviations.com/%s' % text)
|
||||
results = re.findall('<p class="desc">(.+?)</p>', data)
|
||||
results = [i for k,i in enumerate(results) if results.index(i) == k]
|
||||
else:
|
||||
data = load_page("http://www.sokr.ru/search/?", {'abbr': text.encode('utf-8'), 'abbr_exact': '1'})
|
||||
results = re.findall('em class="got_clear">.+?</em></a>.+?<p class="value">(.+?)</p>' , data, re.S)
|
||||
cr = len(results)
|
||||
if not results: msg = L('I don\'t know!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
if not target:
|
||||
if cr == 1: target = '1'
|
||||
elif cr < 6: target = '1-%s' % cr
|
||||
else: target = '1-5'
|
||||
try: n1 = n2 = int(target)
|
||||
except: n1, n2 = map(int, target.split('-'))
|
||||
if 0 < n1 <= n2 <= cr:
|
||||
msg = L('Total found %s matches. Result(s) %s:\n','%s/%s'%(jid,nick)) % (cr, target)
|
||||
msg += '\n'.join(['%s. %s' % (i[0]+n1, i[1].replace('\n',' ')) for i in enumerate(results[n1-1: n2])]).decode('utf8')
|
||||
msg = msg.replace('<br>', '').replace('\r','')
|
||||
else: msg = L('I don\'t know!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'sokr', sokr, 2, 'Abbreviations.\nExamples: sokr abbr, sokr 6 abbr, sokr 3-7 abbr')]
|
||||
42
plugins/sovm.py
Normal file
42
plugins/sovm.py
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def sovm(type, jid, nick, text):
|
||||
text = text.lower().strip().replace('.',' ').split()
|
||||
if text:
|
||||
text = '.'.join(text)
|
||||
znaki = getFile(data_folder % 'sovmestimosti.txt',{})
|
||||
znak = znaki.get(text.encode('utf-8'),None)
|
||||
if znak:
|
||||
body = html_encode(load_page('http://astro-goroskop.ru/sovmestimosti/%s.html' % znak)).replace('\n',' ')
|
||||
if '-' in znak: regexp = 'class="float_img" alt="(.*?)" />(.*?)<script'
|
||||
else: regexp = 'class="float_img" alt="(.*?)" />(.*?)<br /><br />'
|
||||
body = re.findall(regexp,body,re.S|re.I|re.U)
|
||||
if body and len(body[0]) == 2: msg ='\n'.join(t.strip().replace('<br /> <br />','') for t in body[0])
|
||||
else: msg = L('Error!','%s/%s'%(jid,nick))
|
||||
else: msg = L('Sign not found!','%s/%s'%(jid,nick))
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
global execute
|
||||
|
||||
execute = [(3, 'sovm', sovm, 2, 'Reconcilability between zodiac signs')]
|
||||
44
plugins/spellcheck.py
Normal file
44
plugins/spellcheck.py
Normal file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) Vit@liy <vitaliy@root.ua> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def spell(type, jid, nick, text):
|
||||
tmp = text.strip().split(' ', 1)
|
||||
if tmp[0]:
|
||||
langs = re.sub('-|:;', ',', tmp[0]).lower()
|
||||
if len(tmp) == 2 and re.match('((uk)|(en)|(ru))(,((uk)|(en)|(ru)))*?$', langs): text = tmp[1].encode('utf-8')
|
||||
else: text, langs = text.encode('utf-8'), ''
|
||||
url = 'http://speller.yandex.net/services/spellservice.json/checkText?text=%s&lang=%s&options=7' % (urllib.quote_plus(text), langs)
|
||||
j = json.loads(load_page(url),encoding='utf-8')
|
||||
msg = text.decode('utf-8')
|
||||
deltapos = 0
|
||||
for err in j:
|
||||
try:
|
||||
msg = msg[:err['pos']+deltapos] + err['s'][0] + msg[err['len']+err['pos']+deltapos:]
|
||||
deltapos += len(err['s'][0]) - err['len']
|
||||
except: pass
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type,jid,nick,msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(0, 'spell', spell, 2, 'Spellchecker. Example: spell [uk|ru|en] sentence')]
|
||||
115
plugins/spy.py
Normal file
115
plugins/spy.py
Normal file
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
spy_stat_time = int(time.time()) # время последнего сканирования
|
||||
|
||||
#conf hrs usrs msgs action
|
||||
def spy_add(text,rn):
|
||||
if text == '': return L('what do you want to add?',rn)
|
||||
text = text.lower()
|
||||
sconf = text.split(' ')[0]
|
||||
try: saction = text.split(' ',1)[1]
|
||||
except: return L('not given tracking',rn)
|
||||
for tmp in saction.split(' '):
|
||||
if tmp[0] != 'u' and tmp[0] != 'm':
|
||||
return L('is not specified criterion tracking',rn)
|
||||
try: int(tmp[1:])
|
||||
except: return L('incorrect digital parameter',rn)
|
||||
if sconf not in [t[0] for t in cur_execute_fetchone('select room from conference;')]: return L('I am not in the %s ',rn) % sconf
|
||||
if cur_execute_fetchone('select room from spy where room=%s;',(sconf,)):
|
||||
msg = L('Updated: %s',rn) % text
|
||||
cur_execute('delete from spy where room=%s;',(sconf,))
|
||||
else: msg = L('Append: %s',rn) % text
|
||||
cnt = len(['' for t in megabase if t[0]==tmp[0]])
|
||||
cur_execute('insert into spy values (%s,%s,%s,%s,%s)',(sconf,int(time.time()),cnt,0,saction))
|
||||
return msg
|
||||
|
||||
def spy_del(text,rn):
|
||||
if text == '': return L('what do you want remove?',rn)
|
||||
text = text.lower().split(' ')[0]
|
||||
if cur_execute_fetchone('select room from spy where room=%s;',(text,)):
|
||||
cur_execute('delete from spy where room=%s;',(text,))
|
||||
return L('Removed: %s',rn) % text
|
||||
else: return L('Not found: %s',rn) % text
|
||||
|
||||
def spy_show(rn):
|
||||
sb = cur_execute_fetchall('select * from spy;')
|
||||
if not sb: return L('List is empty.')
|
||||
msg = L('Monitoring conferences:',rn)
|
||||
msg += '\n%s' % '\n'.join(['%s %s (%s|u%s|m%s)' % (tmp[0],tmp[4],un_unix(int(time.time()-tmp[1]),rn),tmp[2],tmp[3]) for tmp in sb])
|
||||
msg += L('\nNext scanning across %s',rn) % un_unix(int(GT('scan_time')-(time.time()-spy_stat_time)),rn)
|
||||
return msg
|
||||
|
||||
def conf_spy(type, jid, nick,text):
|
||||
text = text.strip().lower()
|
||||
rn = '%s/%s'%(jid,nick)
|
||||
msg = None
|
||||
if text.startswith('add '): msg = spy_add(text[4:],rn)
|
||||
elif text.startswith('del '): msg = spy_del(text[4:],rn)
|
||||
elif text == 'show': msg = spy_show(rn)
|
||||
if not msg: msg = L('Smoke help about command!',rn)
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def spy_message(room,jid,nick,type,text):
|
||||
sb = cur_execute_fetchone('select message from spy where room=%s;',(room,))
|
||||
if sb: cur_execute('update spy set message=message+1 where room=%s',(room,))
|
||||
|
||||
def get_spy_stat():
|
||||
global spy_stat_time
|
||||
if time.time()-spy_stat_time < GT('scan_time'): return None
|
||||
spy_stat_time = time.time()
|
||||
sb = cur_execute_fetchone('select room from spy;')
|
||||
if sb:
|
||||
for tmp in sb:
|
||||
cnt = len(['' for t in megabase if t[0]==tmp[0]])
|
||||
cur_execute('update spy set participant=(participant+%s)/2 where room=%s',(cnt,tmp[0]))
|
||||
|
||||
def spy_action():
|
||||
try:
|
||||
if cur_execute_fetchone('select count(*) from conference;')[0] == 1: raise
|
||||
except: return None # Last conference
|
||||
sb = cur_execute_fetchall('select * from spy where %s-time>%s;',(int(time.time()),GT('spy_action_time')))
|
||||
for tmp in sb:
|
||||
act = tmp[4].split(' ')
|
||||
mist = None
|
||||
for tmp2 in act:
|
||||
if tmp2[0] == 'u' and int(tmp2[1:]) > tmp[2]: mist = tmp2
|
||||
elif tmp2[0] == 'm' and int(tmp2[1:]) > tmp[3]: mist = tmp2
|
||||
cur_execute('delete from spy where room=%s',(tmp[0],))
|
||||
if mist:
|
||||
if cur_execute_fetchall('select * from conference where room ilike %s;', ('%s/%%'%getRoom(tmp[0]),)):
|
||||
cur_execute('delete from conference where room ilike %s;', ('%s/%%'%getRoom(tmp[0]),))
|
||||
leave(tmp[0], L('I leave your conference because low activity'))
|
||||
pprint('*** Leave room: %s by spy activity!' % tmp[0],'red')
|
||||
own = cur_execute_fetchall('select * from bot_owner;')
|
||||
if own:
|
||||
for tmpo in own: send_msg('chat', tmpo[0], '', L('I leave conference %s by condition spy plugin: %s') % (tmp[0], mist))
|
||||
else: cur_execute('insert into spy values (%s,%s,%s,%s,%s)',(tmp[0],int(time.time()),tmp[2], 0,tmp[4]))
|
||||
|
||||
global execute, timer, message_control
|
||||
|
||||
timer = [get_spy_stat, spy_action]
|
||||
|
||||
message_control = [spy_message]
|
||||
|
||||
execute = [(9, 'spy', conf_spy, 2, 'Check conference activity\nspy add <conference>[ u<number>][ m<number>] - add conference to list. u - count users, m - count message per night. At default At least one condition - the bot will leave the conference\nspy del <conference> - remove conference from list\nspy show - show active monitoring.')]
|
||||
79
plugins/steam.py
Normal file
79
plugins/steam.py
Normal file
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
#http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=xxxx&steamids=76561198018559638
|
||||
#http://api.steampowered.com/ISteamUser/GetFriendList/v0001/?key=xxxx&steamid=76561198018559638&relationship=friend
|
||||
|
||||
steam_api_url = 'http://api.steampowered.com/ISteamUser/%s'
|
||||
steam_summary = steam_api_url % 'GetPlayerSummaries/v0002/?'
|
||||
steam_friends = steam_api_url % 'GetFriendList/v0001/?'
|
||||
|
||||
def time_str(t):
|
||||
try: return time.strftime('%Y.%m.%d %H:%M',time.localtime(t))
|
||||
except: return t
|
||||
|
||||
def steam(type, jid, nick, text):
|
||||
text = text.strip().split()
|
||||
need_id = len(text) > 1
|
||||
text = text[0]
|
||||
if text.isdigit():
|
||||
STEAM_API = GT('steam_api_key')
|
||||
if len(STEAM_API) == 32:
|
||||
try:
|
||||
data = load_page(steam_summary, {'key': STEAM_API, 'steamids': text})
|
||||
data = json.loads(data)['response']['players']
|
||||
if data:
|
||||
data = data[0]
|
||||
_PERSONANAME = data.get('personaname',L('Unknown','%s/%s'%(jid,nick)))
|
||||
_REALNAME = data.get('realname',L('Unknown','%s/%s'%(jid,nick)))
|
||||
_LOCCOUNTRYCODE = data.get('loccountrycode',L('Unknown','%s/%s'%(jid,nick)))
|
||||
_TIMECREATED = data.get('timecreated',L('Hidden','%s/%s'%(jid,nick)))
|
||||
_LASTLOGOFF = data.get('lastlogoff',L('Hidden','%s/%s'%(jid,nick)))
|
||||
_PROFILEURL = data.get('profileurl',L('Unknown','%s/%s'%(jid,nick)))
|
||||
data = load_page(steam_friends, {'key': STEAM_API, 'steamid': text, 'relationship': 'friend'})
|
||||
if data.startswith(L('Error! %s')%''):
|
||||
_FRIENDS = L('Hidden','%s/%s'%(jid,nick))
|
||||
_LEN_FRIENDS = L('Unknown','%s/%s'%(jid,nick))
|
||||
else:
|
||||
data = json.loads(data)['friendslist']['friends']
|
||||
_FRIENDS = ','.join(t['steamid'] for t in data)
|
||||
data = load_page(steam_summary, {'key': STEAM_API, 'steamids': _FRIENDS})
|
||||
data = json.loads(data)['response']['players']
|
||||
_FRIENDS = [(t.get('personaname','-'),t['steamid']) for t in data]
|
||||
_LEN_FRIENDS = len(_FRIENDS)
|
||||
if need_id: _FRIENDS = ' | '.join('%s %s' % t for t in _FRIENDS)
|
||||
else: _FRIENDS = ', '.join(t[0] for t in _FRIENDS)
|
||||
msg = L('Nick: %s\nName: %s\nCountry: %s\nCreated: %s\nLast logoff: %s\nTotal friends: %s\nFriends: %s\nProfile: %s','%s/%s'%(jid,nick)) %\
|
||||
(_PERSONANAME,_REALNAME,_LOCCOUNTRYCODE,time_str(_TIMECREATED),time_str(_LASTLOGOFF),_LEN_FRIENDS,_FRIENDS,_PROFILEURL)
|
||||
if need_id and type == 'groupchat':
|
||||
send_msg(type, jid, nick, L('Send for you in private','%s/%s'%(jid,nick)))
|
||||
type = 'chat'
|
||||
else: msg = L('Steam user not found!','%s/%s'%(jid,nick))
|
||||
except: msg = L('Steam API is broken!','%s/%s'%(jid,nick))
|
||||
else: msg = L('Steam API key is wrong!','%s/%s'%(jid,nick))
|
||||
else: msg = L('Steam ID should be digital!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'steam', steam, 2, 'Show information about Steam profile')]
|
||||
54
plugins/svn.py
Normal file
54
plugins/svn.py
Normal file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def svn_get(type, jid, nick,text):
|
||||
if len(text):
|
||||
if text[:7] !='http://' and text[:8] !='https://' and text[:6] !='svn://': text = 'http://%s' % text
|
||||
count,revn = 1,0
|
||||
if '-v' in text.split(): text,verb = reduce_spaces_all(text.replace('-v','')),True
|
||||
else: verb = False
|
||||
if ' ' in text:
|
||||
text = text.split(' ')
|
||||
url = text[0]
|
||||
try: count = int(text[1])
|
||||
except:
|
||||
try:
|
||||
if 'r' in text[1].lower(): revn = int(text[1][text[1].find('r')+1:])
|
||||
except: revn = 0
|
||||
else: url=text
|
||||
if revn != 0: sh_exe = 'sh -c \"LANG=%s svn log %s -r%s\"' % (L('en_EN.UTF8','%s/%s'%(jid,nick)),url,revn)
|
||||
else:
|
||||
if count > 10: count = 10
|
||||
sh_exe = 'sh -c \"LANG=%s svn log %s --limit %s\"' % (L('en_EN.UTF8','%s/%s'%(jid,nick)),url,count)
|
||||
if verb: sh_exe = '%s -v\"' % sh_exe[:-1]
|
||||
svn_log = shell_execute(sh_exe,'%s/%s'%(jid,nick)).replace('\n\n','\n')
|
||||
while svn_log[-1] in ['-','\n']: svn_log = svn_log[:-1]
|
||||
rpl = re.findall('-{10,}',svn_log)
|
||||
if rpl: svn_log = svn_log.replace(rpl[0],'-'*3)
|
||||
msg = 'SVN from %s\n%s' % (url,svn_log)
|
||||
else: msg = L('Read user manual for commands...','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'svn', svn_get, 2, 'Show svn log.\nsvn [http://]url [limit] - show last revision(s) limit\nsvn [http://]url rXXX - show XXX revision')]
|
||||
49
plugins/talkers.py
Normal file
49
plugins/talkers.py
Normal file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def gtalkers(type, jid, nick, text):
|
||||
if text:
|
||||
ttext = '%%%s%%' % text
|
||||
tma = cur_execute_fetchall('select * from talkers where (jid ilike %s or nick ilike %s or room ilike %s) order by -words limit %s',(ttext,ttext,ttext,10))
|
||||
else: tma = cur_execute_fetchall('select * from talkers order by -words limit %s',(10,))
|
||||
if tma:
|
||||
msg = '%s\n' % L('Talkers:\nNick\t\tWords\tPhrases\tEffect\tConf.','%s/%s'%(jid,nick))
|
||||
msg += '\n'.join(['%s. %s\t\t%s\t%s\t%s\t%s' % (cnd + 1, tt[2], tt[3], tt[4], round(tt[3]/float(tt[4]), 2),'%s@%s.%s' % (getName(tt[0]),'.'.join([tmp[0] for tmp in tt[0].split('@')[1].split('.')[:-1]]),tt[0].split('.')[-1])) for cnd, tt in enumerate(tma)])
|
||||
else: msg = '%s %s' % (text, L('Not found!','%s/%s'%(jid,nick)))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def talkers(type, jid, nick, text):
|
||||
if text:
|
||||
ttext = '%%%s%%' % text
|
||||
tma = cur_execute_fetchall('select * from talkers where room=%s and (jid ilike %s or nick ilike %s) order by -words limit %s',(jid,ttext,ttext,10))
|
||||
else: tma = cur_execute_fetchall('select * from talkers where room=%s order by -words limit %s',(jid,10))
|
||||
if tma:
|
||||
msg = '%s\n' % L('Talkers:\nNick\t\tWords\tPhrases\tEffect','%s/%s'%(jid,nick))
|
||||
msg += '\n'.join(['%s. %s\t\t%s\t%s\t%s' % (cnd + 1, tt[2], tt[3], tt[4], round(tt[3]/float(tt[4]), 2)) for cnd, tt in enumerate(tma)])
|
||||
else: msg = '%s %s' % (text, L('Not found!','%s/%s'%(jid,nick)))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'talkers', talkers, 2, 'Show local talkers'),
|
||||
(4, 'gtalkers', gtalkers, 2, 'Show global talkers')]
|
||||
28
plugins/test.py
Normal file
28
plugins/test.py
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def test(type, jid, nick): send_msg(type, jid, nick, L('Passed!','%s/%s'%(jid,nick)))
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(0, 'test', test, 1, 'Check bot activity.')]
|
||||
35
plugins/th.py
Normal file
35
plugins/th.py
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def thread_info(type, jid, nick):
|
||||
if thread_type:
|
||||
tmas = [unicode(tmp).split('(',1)[1].split(')',1)[0] for tmp in threading.enumerate()]
|
||||
tmas.sort()
|
||||
msg = L('\nActive: %s\n%s','%s/%s'%(jid,nick)) % (threading.activeCount(),'\n'.join(tmas))
|
||||
else: msg = ''
|
||||
msg = L('Executed threads: %s | Error(s): %s','%s/%s'%(jid,nick)) % (th_cnt,thread_error_count) + msg
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(7, 'th', thread_info, 1, 'Threads statistic')]
|
||||
117
plugins/todate.py
Normal file
117
plugins/todate.py
Normal file
@@ -0,0 +1,117 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def get_holiday(sdate):
|
||||
|
||||
''' Function get holiday from file plugins/date.txt and return title of
|
||||
holiday if holiday found, else return empty unicode message. Input params
|
||||
must be list of int
|
||||
|
||||
:[month, day]:'''
|
||||
|
||||
result = ''
|
||||
date_base = readfile(date_file).decode('UTF').split('\n')
|
||||
for ddate in date_base:
|
||||
if ddate != '\n' or ddate != '':
|
||||
ddate = ddate.split('-')
|
||||
hdate = ddate[0]
|
||||
if '.' in hdate:
|
||||
hdate = map(int, hdate.split('.'))
|
||||
hdate.reverse()
|
||||
if hdate == sdate:
|
||||
result += ddate[1].strip() + ', '
|
||||
if len(result) > 2: result = result[:-2]
|
||||
return result
|
||||
|
||||
def parse_date_string(string_date, spl='.'):
|
||||
|
||||
''' Parse date string and return list [year, month, day] '''
|
||||
|
||||
date_formats = ['%d'+spl+'%m', '%d'+spl+'%m'+spl+'%y',
|
||||
'%d'+spl+'%m'+spl+'%Y', '%Y'+spl+'%m'+spl+'%d']
|
||||
#output = list(time.localtime())[:3]
|
||||
for format in date_formats:
|
||||
try: output = list(time.strptime(string_date, format))[:3]
|
||||
except: pass
|
||||
return output
|
||||
|
||||
def to_date(type, jid, nick, text):
|
||||
dmass = (L('days','%s/%s'%(jid,nick)), L('day','%s/%s'%(jid,nick)), L('Days','%s/%s'%(jid,nick)).lower(), L('Days','%s/%s'%(jid,nick)).lower(),
|
||||
L('Days','%s/%s'%(jid,nick)).lower(), L('days','%s/%s'%(jid,nick)), L('days','%s/%s'%(jid,nick)), L('days','%s/%s'%(jid,nick)), L('days','%s/%s'%(jid,nick)), L('days','%s/%s'%(jid,nick)))
|
||||
splitters = ('.', '-', ':', '/', ',', '\\')
|
||||
if len(text):
|
||||
try:
|
||||
spl = [spl for spl in splitters if spl in text][0]
|
||||
sdate = parse_date_string(text, spl)
|
||||
if sdate[0] == 1900: sdate[0] = list(time.localtime())[0]
|
||||
year = sdate.pop(0)
|
||||
month, day = sdate
|
||||
hday = get_holiday(sdate)
|
||||
text = text.replace(spl, '.')
|
||||
msg = ''
|
||||
if len(hday) > 0: text = hday
|
||||
days_remain = (datetime.date(year, month, day) - datetime.date.today()).days
|
||||
if len(str(abs(days_remain))) > 1 and str(days_remain)[-2] == '1':
|
||||
dmass = (L('days','%s/%s'%(jid,nick)),L('days','%s/%s'%(jid,nick)),L('days','%s/%s'%(jid,nick)),L('days','%s/%s'%(jid,nick)),
|
||||
L('days','%s/%s'%(jid,nick)),L('days','%s/%s'%(jid,nick)),L('days','%s/%s'%(jid,nick)),L('days','%s/%s'%(jid,nick)),
|
||||
L('days','%s/%s'%(jid,nick)),L('days','%s/%s'%(jid,nick)))
|
||||
if days_remain < 0: msg += L('was %s %s ago','%s/%s'%(jid,nick)) % \
|
||||
(str(abs(days_remain)), dmass[int(str(days_remain)[-1])])
|
||||
elif days_remain == 0: msg += L('today','%s/%s'%(jid,nick))
|
||||
else: msg += L('will be in %s %s','%s/%s'%(jid,nick)) % \
|
||||
(str(abs(days_remain)), dmass[int(str(days_remain)[-1])])
|
||||
msg = text + ' ' + msg
|
||||
except: msg = L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
else: msg = L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def todate(type, jid, nick, text):
|
||||
dmass = (L('days','%s/%s'%(jid,nick)), L('day','%s/%s'%(jid,nick)), L('Days','%s/%s'%(jid,nick)).lower(), L('Days','%s/%s'%(jid,nick)).lower(),
|
||||
L('Days','%s/%s'%(jid,nick)).lower(), L('days','%s/%s'%(jid,nick)), L('days','%s/%s'%(jid,nick)), L('days','%s/%s'%(jid,nick)), L('days','%s/%s'%(jid,nick)), L('days','%s/%s'%(jid,nick)))
|
||||
splitters = ('.', '-', ':', '/', ',', '\\')
|
||||
msg = ''
|
||||
if len(text):
|
||||
try:
|
||||
if ' ' in text: ddate, msg = text.split(' ', 1)[0], text.split(' ', 1)[1]
|
||||
else: ddate = text
|
||||
spl = [spl for spl in splitters if spl in ddate][0]
|
||||
if len(msg) == 0: msg = L('before the %s remained','%s/%s'%(jid,nick)) % ddate.replace(spl, '.')
|
||||
sdate = parse_date_string(ddate, spl)
|
||||
if sdate[0] == 1900: sdate[0] = list(time.localtime())[0]
|
||||
year = sdate.pop(0)
|
||||
month, day = sdate
|
||||
days_remain = (datetime.date(year, month, day) - datetime.date.today()).days
|
||||
if len(str(abs(days_remain))) > 1 and str(days_remain)[-2] == '1':
|
||||
dmass = (L('days','%s/%s'%(jid,nick)),L('days','%s/%s'%(jid,nick)),L('days','%s/%s'%(jid,nick)),L('days','%s/%s'%(jid,nick)),
|
||||
L('days','%s/%s'%(jid,nick)),L('days','%s/%s'%(jid,nick)),L('days','%s/%s'%(jid,nick)),L('days','%s/%s'%(jid,nick)),
|
||||
L('days','%s/%s'%(jid,nick)),L('days','%s/%s'%(jid,nick)))
|
||||
if days_remain < 0: msg = L('Date has already in past!','%s/%s'%(jid,nick))
|
||||
else: msg += ' %s %s' % (days_remain,dmass[int(str(days_remain)[-1])])
|
||||
except: msg = L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
else: msg = L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'to_date', to_date, 2, 'Calculate count of days for requested date, if the date is holiday, that returned title of holiday.\nSupported date formats: dd.mm.yyyy, dd.mm, dd.mm.yy, yyyy.mm.dd\nSupported splitters: ,-.:/\\\ntodate 05.09\ntodate 5/9/2010'),
|
||||
(3, 'todate', todate, 2, 'Calculate count of days for requested date.\nSupported date formats: dd.mm.yyyy, dd.mm, dd.mm.yy, yyyy.mm.dd\nSupported splitter: ,-.:/\\\ntodate 05.09 before New year remained\ntodate 5/9/2010 before New year remained')]
|
||||
39
plugins/train.py
Normal file
39
plugins/train.py
Normal file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) Vit@liy <vitaliy@root.ua> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def train(type, jid, nick, text):
|
||||
try:
|
||||
from_to = map(lambda x: urllib.quote(x.encode('utf-8')), text.strip().split(' - '))
|
||||
url = 'http://rasp.yandex.ru/search/train/?fromName=%s&toName=%s' % (from_to[0], from_to[1])
|
||||
data = html_encode(load_page(url))
|
||||
data = data.split('<div class="b-timetable__tripname">',3)[1]
|
||||
res = re.findall(u'<a class="b-link" href="/thread/.+?><strong>(.+?)</strong> <span class="g-nowrap">(.+?)</span>.+?<span class="g-nowrap"></span>.*?<span class="g-nowrap">(.+?)</span></a>.+?<strong>(.+?)</strong>.+?<strong>(.+?)</strong>.+?<div class="b-timetable__pathtime">(.+?)</div>', data, re.S|re.I|re.U)
|
||||
if res.count(res[0]) > 1: res = res[:res.index(res[0], 1)]
|
||||
msg = '\n'.join(['%s\t%s-%s\t\t%s-%s\t(%s)' % _ for _ in res])
|
||||
if not msg.strip() or 'b-pseudo-link js-transfers-trigger' in data: msg = L('What?','%s/%s'%(jid,nick))
|
||||
except: msg = L('Command execution error.','%s/%s'%(jid,nick))
|
||||
send_msg(type,jid,nick,msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'train', train, 2, 'Train schedules by Yandex. Example: train city1 - city2')]
|
||||
89
plugins/translate.py
Normal file
89
plugins/translate.py
Normal file
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def translate_ru(type, jid, nick, text):
|
||||
text = text.strip()
|
||||
trlang = {'en':['e',L('English','%s/%s'%(jid,nick))],'ru':['r',L('Russian','%s/%s'%(jid,nick))],'fr':['f',L('French','%s/%s'%(jid,nick))],
|
||||
'es':['s',L('Spanish','%s/%s'%(jid,nick))],'it':['i',L('Italian','%s/%s'%(jid,nick))],'de':['g',L('German','%s/%s'%(jid,nick))],
|
||||
'pt':['p',L('Portuguese','%s/%s'%(jid,nick))]}
|
||||
|
||||
trlang2 = {'e':'en','r':'ru','f':'fr','s':'es','i':'it','g':'de','p':'pt'}
|
||||
|
||||
if text.lower() == 'list': msg = L('Available languages for translate:','%s/%s'%(jid,nick)) + ' ' + ', '.join(sorted(trlang.keys()))
|
||||
elif text[:5].lower() == 'info ':
|
||||
text = text.lower().split(' ')
|
||||
msg = ''
|
||||
for tmp in text:
|
||||
if tmp in trlang: msg += '%s - %s, ' % (tmp,trlang[tmp][1])
|
||||
if len(msg): msg = L('Available languages: %s','%s/%s'%(jid,nick)) % msg[:-2]
|
||||
else: msg = L('I don\'t know this language','%s/%s'%(jid,nick))
|
||||
elif text[:5].lower() == 'lang ' and text.count(' ')==1:
|
||||
text = text.lower().split(' ')[1]
|
||||
msg = ', '.join(['%s - %s' % (k,trlang[k][1]) for k in trlang.keys() if text in trlang[k][1].lower()])
|
||||
if len(msg): msg = L('Available languages: %s','%s/%s'%(jid,nick)) % msg
|
||||
else: msg = L('I don\'t know this language','%s/%s'%(jid,nick))
|
||||
else:
|
||||
if ' ' in text:
|
||||
text = text.split(' ',2)
|
||||
url = 'http://m.translate.ru/services/MobileService.asmx/TranslateText4Touch?'
|
||||
if len(text)>1 and trlang.has_key(text[0].lower()):
|
||||
if len(text)>2 and trlang.has_key(text[1].lower()): lfrom,lto,tr_text = text[0].lower(),text[1].lower(),text[2]
|
||||
else: lfrom,lto,tr_text = '',text[0].lower(),' '.join(text[1:])
|
||||
if lfrom: lft = trlang[lfrom][0]
|
||||
else: lft = 'a'
|
||||
lft += trlang[lto][0]
|
||||
search_results = load_page(url, {'intLang':lto,\
|
||||
'text':tr_text.encode("utf-8"),\
|
||||
'direction':lft,\
|
||||
'template':'General'})
|
||||
tr_xml = xmpp.simplexml.XML2Node(search_results)
|
||||
isWord = tr_xml.getTagData('isWord') == 'true'
|
||||
result = tr_xml.getTagData('result')
|
||||
tr_direct = tr_xml.getTagData('ptsDirCode')
|
||||
if isWord:
|
||||
result = result.replace(' <span class="ref_info"></span>,\n',',')
|
||||
result = result.replace('<span class="ref_dictionary">\n','<span class="ref_dictionary">')
|
||||
result = result.replace('<span class="ref_comment">\n','<span class="ref_comment">')
|
||||
result = result.replace('</span>\n<span class="ref_info">','</span><span class="ref_info">')
|
||||
result = result.replace('<li><span class="ref_result">\n','<li><span class="ref_result">, ')
|
||||
for t in re.findall('(</div>\n.*?<div class="tr_pr">)',result,re.I+re.U+re.S): result = result.replace(t,'</div><div class="tr_pr">')
|
||||
result = result.replace('<span class="ref_source">','||<span class="ref_source">')
|
||||
for t in re.findall('(<a href=.*?</a>)',result,re.I+re.U+re.S): result = result.replace(t,'')
|
||||
for t in re.findall('(<span id=.*?</span>)',result,re.I+re.U+re.S): result = result.replace(t,'')
|
||||
result = result.replace('<br><span class="w_des">','<span class="w_des">')
|
||||
result = result.replace('<b>\n','<b>')
|
||||
msg = urllib.unquote(unhtml(result).encode('utf8')).decode('utf8', 'ignore')
|
||||
msg = msg.replace('||','').replace(')\n(',') (').replace('\n, ',', ').replace(' ,',',').replace(',\n',', ')
|
||||
else: msg = result
|
||||
if not lfrom:
|
||||
if '\n' in msg: symb = '\n'
|
||||
else: symb = ' '
|
||||
msg = L('%s%s[Source: %s]','%s/%s'%(jid,nick)) % (msg,symb,trlang[trlang2[tr_direct[0]]][1].strip())
|
||||
else: msg = L('Incorrect language settings for translate. translate list - available languages.','%s/%s'%(jid,nick))
|
||||
else: msg = L('Command\'s format: translate [from] to text','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'translate', translate_ru, 2, 'Translator from translate.ru\ntranslate [from_language] to_language text - translate text\ntranslate list - list for available languages for translate\ntranslate info <reduction> - get info about language reduction\ntranslate lang <expression> - get languages by expression')]
|
||||
|
||||
101
plugins/turn.py
Normal file
101
plugins/turn.py
Normal file
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# Copyright (C) Vit@liy <vitaliy@root.ua> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
turn_base = []
|
||||
|
||||
def turner_raw(text,jid,nick):
|
||||
global turn_base
|
||||
rtab = L('qwertyuiop[]asdfghjkl;\'zxcvbnm,.`QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM<>~','%s/%s'%(jid,nick))
|
||||
ltab = L('QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM<>~qwertyuiop[]asdfghjkl;\'zxcvbnm,.`','%s/%s'%(jid,nick))
|
||||
to_turn = text
|
||||
if not text:
|
||||
for tmp in turn_base:
|
||||
if tmp[0] == jid and tmp[1] == nick:
|
||||
turn_base.remove(tmp)
|
||||
to_turn = tmp[2]
|
||||
break
|
||||
if to_turn:
|
||||
if to_turn[:3] == '/me': msg, to_turn = '*%s' % nick, to_turn[3:]
|
||||
elif ': ' in to_turn: msg, to_turn = '%s:' % to_turn.split(': ',1)[0], to_turn.split(': ',1)[1]
|
||||
else: msg = ''
|
||||
for tt in re.findall('\s+[^\s]*', ' ' + to_turn,re.I+re.U):
|
||||
if re.findall('\s+(((svn|http[s]?|ftp)(://))|(magnet:\?))',tt,re.S|re.I|re.U): msg += tt
|
||||
else: msg += ''.join([ltab[rtab.find(x)] if x in rtab else x for x in tt])
|
||||
msg = msg.strip()
|
||||
if get_config(getRoom(jid),'censor'): msg = to_censore(msg,jid)
|
||||
return msg
|
||||
else: return None
|
||||
|
||||
def turner(type, jid, nick, text):
|
||||
if not text and type != 'groupchat':
|
||||
send_msg(type, jid, nick, L('Not allowed in private!','%s/%s'%(jid,nick)))
|
||||
return
|
||||
to_turn = turner_raw(text,jid,nick)
|
||||
if to_turn: send_msg(type, jid, [nick,''][type=='groupchat'], to_turn)
|
||||
else: send_msg(type, jid, nick, L('What?','%s/%s'%(jid,nick)))
|
||||
|
||||
def append_to_turner(room,jid,nick,type,text):
|
||||
global turn_base
|
||||
for tmp in turn_base:
|
||||
if tmp[0] == room and tmp[1] == nick:
|
||||
try: turn_base.remove(tmp)
|
||||
except: pass
|
||||
break
|
||||
turn_base.append((room,nick,text))
|
||||
|
||||
def remove_from_turner(room,jid,nick,type,text):
|
||||
global turn_base
|
||||
if type == 'unavailable':
|
||||
for tmp in turn_base:
|
||||
if tmp[0] == room and tmp[1] == nick:
|
||||
try: turn_base.remove(tmp)
|
||||
except: pass
|
||||
break
|
||||
|
||||
def autoturn(room,jid,nick,type,text):
|
||||
if get_config(room,'autoturn') and type == 'groupchat':
|
||||
if cur_execute_fetchone('select * from commonoff where room=%s and cmd=%s',(room,'turn')): return
|
||||
nowname = get_xnick(room)
|
||||
if nick == nowname: return
|
||||
text = re.sub('^%s[,:]\ ' % re.escape(nowname), '', text.strip())
|
||||
tmp = text.lower()
|
||||
if ': ' in tmp: tmp = tmp.split(': ',1)[1]
|
||||
count_two = 0
|
||||
if not sum([int(ord(t)>127) for t in tmp]):
|
||||
for tt in re.findall('\s+[^\s]*', ' ' + tmp):
|
||||
if not re.findall('(svn|http[s]?|ftp)(://)',tt,re.S|re.U) and not re.findall(u'\s+[A-ZА-Я\d\']{2,}$',tt,re.U): count_two += sum([1 for k in two_en if k in tt])
|
||||
if len(tmp.split()) < count_two - 1:
|
||||
to_turn = turner_raw(text,room,nick)
|
||||
if to_turn and to_turn != text:
|
||||
pprint('Autoturn text: %s/%s [%s] %s > %s' % (room,nick,jid,text,to_turn),'dark_gray')
|
||||
send_msg(type, room, '', to_turn)
|
||||
return True
|
||||
|
||||
global execute, message_act_control
|
||||
|
||||
message_control = [append_to_turner]
|
||||
presence_control = [remove_from_turner]
|
||||
message_act_control = [autoturn]
|
||||
|
||||
execute = [(3, 'turn', turner, 2, 'Turn text from one layout to another.')]
|
||||
108
plugins/watcher.py
Normal file
108
plugins/watcher.py
Normal file
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
watch_time = time.time()
|
||||
watch_count = 0
|
||||
watch_reset = True
|
||||
watch_last_activity = {}
|
||||
watch_activity = {}
|
||||
|
||||
def connect_watch():
|
||||
global iq_request, watch_time, game_over, watch_count, bot_exit_type, watch_reset, plugins_reload
|
||||
if GT('watcher_self_ping') and (time.time() - watch_time) > GT('watch_size'):
|
||||
watch_time = time.time()
|
||||
watch_count += 1
|
||||
watch_reset = True
|
||||
iqid = get_id()
|
||||
i = xmpp.Node('iq', {'id': iqid, 'type': 'get', 'to':selfjid}, payload = [xmpp.Node('ping', {'xmlns': xmpp.NS_URN_PING},[])])
|
||||
iq_request[iqid]=(time.time(),watcher_reset,['chat',god,'',''],xmpp.NS_URN_PING)
|
||||
sender(i)
|
||||
to = GT('timeout') - 10
|
||||
if to <= 10: to = 600
|
||||
while to > 0 and not game_over and not plugins_reload:
|
||||
to -= 1
|
||||
time.sleep(1)
|
||||
if game_over or plugins_reload: return
|
||||
if watch_reset:
|
||||
pprint('Restart by watcher\'s timeout!','red')
|
||||
bot_exit_type, game_over = 'restart', True
|
||||
time.sleep(2)
|
||||
|
||||
def watch_room_activity():
|
||||
if not GT('watcher_room_activity'): return
|
||||
global watch_last_activity
|
||||
to = int(time.time())-GT('watch_activity_timeout')
|
||||
cnf = cur_execute_fetchall('select room from conference;')
|
||||
if cnf:
|
||||
for t in cnf:
|
||||
tmp = t[0]
|
||||
try: cw = watch_last_activity[getRoom(tmp)]
|
||||
except: cw = to
|
||||
if cw < to:
|
||||
watch_last_activity[getRoom(tmp)] = int(time.time())
|
||||
text = tmp
|
||||
if '\n' in text: text,passwd = text.split('\n',2)
|
||||
else: passwd = ''
|
||||
zz = join(text, passwd)
|
||||
while unicode(zz)[:3] == '409':
|
||||
time.sleep(1)
|
||||
text += '_'
|
||||
zz = join(text, passwd)
|
||||
time.sleep(1)
|
||||
pprint('Low activity! Try rejoin into %s' % text,'white')
|
||||
|
||||
def watcher_reset(a,b,c,d,e):
|
||||
global watch_reset
|
||||
watch_reset = None
|
||||
|
||||
def c_watcher(type, jid, nick): send_msg(type, jid, nick, L('Timeout for ask: %s | Timeout for answer: %s | Last ask: %s | Total checks: %s','%s/%s'%(jid,nick)) % (GT('watch_size'),GT('timeout'),un_unix(int(time.time() - watch_time),'%s/%s'%(jid,nick)),watch_count))
|
||||
|
||||
def activity_watch(type, jid, nick):
|
||||
rooms = cur_execute_fetchall("select split_part(room,'/',1) from conference;")
|
||||
cnf = [[watch_activity[t],t] for t in watch_activity.keys()]
|
||||
cnf.sort(reverse=1)
|
||||
tt = int(time.time())
|
||||
msg = '\n'.join(['%s - %s' % (t[1],un_unix(tt-t[0],'%s/%s'%(jid,nick))) for t in cnf])
|
||||
rooms = ['%s - %s' % (t[0],L('Unknown','%s/%s'%(jid,nick))) for t in rooms if t[0] not in watch_activity.keys()]
|
||||
if rooms: msg = '%s\n%s' % (msg,'\n'.join(rooms))
|
||||
msg = L('Last activity in room(s):\n%s','%s/%s'%(jid,nick)) % msg
|
||||
if type == 'groupchat':
|
||||
send_msg('chat', jid, nick, msg)
|
||||
msg = L('Send for you in private','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def connect_watch_uni(room,jid,nick,type,mass):
|
||||
global watch_last_activity
|
||||
if jid != 'None':
|
||||
gr = getRoom(room)
|
||||
watch_last_activity[gr] = int(time.time())
|
||||
if jid != Settings['jid']: watch_activity[gr] = int(time.time())
|
||||
|
||||
global execute, timer
|
||||
|
||||
if GT('iq_version_enable'): timer = [connect_watch,watch_room_activity]
|
||||
presence_control = [connect_watch_uni]
|
||||
message_control = [connect_watch_uni]
|
||||
|
||||
execute = [(6,'watcher',c_watcher,1,'Connection activity control.'),
|
||||
(9,'activity',activity_watch,1,'Show activity of conferences.')]
|
||||
38
plugins/whowas.py
Normal file
38
plugins/whowas.py
Normal file
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def whowas(type, jid, nick, text):
|
||||
period = int(time.time()-86400)
|
||||
text = '%%%s%%' % text if text else '%'
|
||||
was_here = cur_execute_fetchall('select nick from age where room=%s\
|
||||
and time>%s\
|
||||
and status=1\
|
||||
and (nick ilike %s or jid ilike %s)\
|
||||
group by jid,nick order by nick;',(jid,period,text,text))
|
||||
if was_here: msg = L('For a last day i see: %s','%s/%s'%(jid,nick)) % ', '.join([t[0] for t in was_here])
|
||||
else:msg = L('All who i see for a last day now is here.','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'whowas', whowas, 2, 'Show list of users for last day')]
|
||||
281
plugins/wot.py
Normal file
281
plugins/wot.py
Normal file
@@ -0,0 +1,281 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) 2013 Vit@liy <vitaliy@root.ua> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
# RU
|
||||
API_ADDR = 'http://api.worldoftanks.ru';
|
||||
APP_ID = '171745d21f7f98fd8878771da1000a31';
|
||||
|
||||
clantags = re.compile('(\(.*?\))|(\[.*?\])')
|
||||
|
||||
def get_tanks_data():
|
||||
data = urllib.urlopen('%s/2.0/encyclopedia/tanks/?application_id=%s&fields=level,name_i18n,name' % (API_ADDR, APP_ID))
|
||||
d = json.load(data)
|
||||
res = {}
|
||||
for i in d['data']:
|
||||
n18 = d['data'][i]['name_i18n'].rsplit(':', 1)[-1].replace('_', ' ')
|
||||
n = d['data'][i]['name'].rsplit(':', 1)[-1].replace('_', ' ')
|
||||
if n18[:2] == 'GB':
|
||||
n18 = n18[5:]
|
||||
if n[:2] == 'GB':
|
||||
n = n[5:]
|
||||
res[i] = {'name_i18n': n18, 'name': n, 'level': d['data'][i]['level']}
|
||||
return res
|
||||
|
||||
try:
|
||||
tanks_data = get_tanks_data()
|
||||
except:
|
||||
tanks_data = {}
|
||||
|
||||
def wot(type, jid, nick, text):
|
||||
text = text.strip()
|
||||
if not text:
|
||||
tmp_text = clantags.sub('', nick).strip().split(' ', 1)[0]
|
||||
if re.match('[\da-zA-Z_].*?', tmp_text):
|
||||
text = tmp_text
|
||||
if text:
|
||||
text = text.split(' ', 1)
|
||||
if len(text) == 1:
|
||||
name, tank = text[0], ''
|
||||
else:
|
||||
name, tank = text[0], text[1].lower()
|
||||
try:
|
||||
data = load_page('%s/2.0/account/list/?application_id=%s&search=%s&fields=id&limit=1' % (API_ADDR, APP_ID, name))
|
||||
v = json.loads(data)
|
||||
player_id = str(v['data'][0]['id'])
|
||||
|
||||
data = load_page('%s/2.0/account/tanks/?application_id=%s&account_id=%s&fields=statistics,tank_id,mark_of_mastery' % (API_ADDR, APP_ID, player_id))
|
||||
vdata = json.loads(data)
|
||||
|
||||
data = load_page('%s/2.0/account/info/?application_id=%s&account_id=%s&fields=clan,nickname,statistics' % (API_ADDR, APP_ID, player_id))
|
||||
pdata = json.loads(data)
|
||||
stat = pdata['data'][player_id]['statistics']
|
||||
|
||||
if pdata['data'][player_id]['clan']:
|
||||
clan_id = str(pdata['data'][player_id]['clan']['clan_id'])
|
||||
data = load_page('%s/2.0/clan/info//?application_id=%s&clan_id=%s&fields=abbreviation' % (API_ADDR, APP_ID, clan_id))
|
||||
cdata = json.loads(data)
|
||||
cname = cdata['data'][clan_id]['abbreviation']
|
||||
except:
|
||||
pdata = {'status': ''}
|
||||
|
||||
if pdata['status'] == 'ok' and pdata['data'][player_id]:
|
||||
wotname = pdata['data'][player_id]['nickname'] + ('[%s]' % cname if pdata['data'][player_id]['clan'] else '')
|
||||
|
||||
if tank:
|
||||
if len(tank) == 1:
|
||||
msg = L('Use more characters in the name of the tank','%s/%s'%(jid,nick))
|
||||
else:
|
||||
try:
|
||||
msg = '%s:' % wotname
|
||||
tids = [tid for tid in tanks_data if tank in tanks_data[tid]['name'].lower() or tank in tanks_data[tid]['name_i18n'].lower()]
|
||||
|
||||
for t in vdata['data'][player_id]:
|
||||
if str(t['tank_id']) in tids:
|
||||
tank_win = t['statistics']['wins']
|
||||
tank_battle = t['statistics']['battles']
|
||||
mom = [L('none','%s/%s'%(jid,nick)), L('3 class','%s/%s'%(jid,nick)), L('2 class','%s/%s'%(jid,nick)), L('1 class','%s/%s'%(jid,nick)), L('master','%s/%s'%(jid,nick))][t['mark_of_mastery']]
|
||||
if tank_battle:
|
||||
msg += L('\n%s (%s/%s - %s%%), mastery: %s','%s/%s'%(jid,nick)) % (tanks_data[str(t['tank_id'])]['name_i18n'], tank_win, tank_battle, round(100.0*tank_win/tank_battle, 2), mom)
|
||||
else:
|
||||
msg += '\n%s (%s/%s)' % (tanks_data[str(t['tank_id'])]['name_i18n'], tank_win, tank_battle)
|
||||
if not msg.count('\n'):
|
||||
msg += L(' not founded tank','%s/%s'%(jid,nick))
|
||||
except:
|
||||
msg = L('Impossible to get tanks\' statistics','%s/%s'%(jid,nick))
|
||||
else:
|
||||
|
||||
wins = stat['all']['wins']
|
||||
battles = stat['all']['battles']
|
||||
|
||||
if not battles:
|
||||
msg = '%s: %s/%s' % (wotname, wins, battles)
|
||||
|
||||
else:
|
||||
try:
|
||||
win_percent = round(100.0 * wins / battles, 2)
|
||||
msg = '%s: %s/%s (%s%%)' % (wotname, wins, battles, win_percent)
|
||||
|
||||
np = int(win_percent) + 1
|
||||
np_int = int((np * battles - 100 * wins) / (100 - np) + 1)
|
||||
np05 = int(win_percent + 0.5) + 0.5
|
||||
np_round = int((np05 * battles - 100 * wins) / (100 - np05) + 1)
|
||||
|
||||
msg += L('\nUp to %s%% win left: %s battles', '%s/%s'%(jid,nick)) % (np, np_int)
|
||||
msg += L('\nUp to %s%% win left: %s battles', '%s/%s'%(jid,nick)) % (np05, np_round)
|
||||
|
||||
avg_exp = stat['all']['battle_avg_xp']
|
||||
|
||||
DAMAGE = stat['all']['damage_dealt'] / float(battles)
|
||||
msg += L('\nAv. damage: %s','%s/%s'%(jid,nick)) % int(round(DAMAGE))
|
||||
FRAGS = stat['all']['frags'] / float(battles)
|
||||
msg += L('\nAv. destroyed: %s','%s/%s'%(jid,nick)) % round(FRAGS, 2)
|
||||
SPOT = stat['all']['spotted'] / float(battles)
|
||||
msg += L('\nAv. spotted: %s','%s/%s'%(jid,nick)) % round(SPOT, 2)
|
||||
CAP = stat['all']['capture_points'] / float(battles)
|
||||
msg += L('\nAv. captured points: %s','%s/%s'%(jid,nick)) % round(CAP, 2)
|
||||
DEF = stat['all']['dropped_capture_points'] / float(battles)
|
||||
msg += L('\nAv. defense points: %s','%s/%s'%(jid,nick)) % round(DEF, 2)
|
||||
|
||||
|
||||
tanks = vdata['data'][player_id]
|
||||
s = sum([t['statistics']['all']['battles'] * tanks_data[str(t['tank_id'])]['level'] for t in tanks])
|
||||
TIER = s / float(battles)
|
||||
|
||||
WINRATE = wins / float(battles)
|
||||
|
||||
msg += L('\nAv. tank lvl: %s','%s/%s'%(jid,nick)) % round(TIER, 2)
|
||||
|
||||
er = DAMAGE * (10 / (TIER + 2)) * (0.23 + 2 * TIER / 100) + FRAGS * 250 + SPOT * 150 + math.log(CAP + 1) / math.log(1.732) * 150 + DEF * 150
|
||||
|
||||
if er < 420:
|
||||
er_xvm = 0
|
||||
else:
|
||||
er_xvm = max(min(er*(er*(er*(er*(er*(4.5254e-17*er - 3.3131e-13) + 9.4164e-10) - 1.3227e-6) + 9.5664e-4) - 0.2598) + 13.23, 100), 0)
|
||||
|
||||
msg += L('\nEfficiency rating: %s (XVM: %s)','%s/%s'%(jid,nick)) % (int(round(er)), round(er_xvm, 1))
|
||||
|
||||
if er < 630:
|
||||
msg += L(' - bad player','%s/%s'%(jid,nick))
|
||||
elif er < 860:
|
||||
msg += L(' - player below average','%s/%s'%(jid,nick))
|
||||
elif er < 1140:
|
||||
msg += L(' - average player','%s/%s'%(jid,nick))
|
||||
elif er < 1460:
|
||||
msg += L(' - good player','%s/%s'%(jid,nick))
|
||||
elif er < 1735:
|
||||
msg += L(' - great player','%s/%s'%(jid,nick))
|
||||
elif er >= 1735:
|
||||
msg += L(' - unicum','%s/%s'%(jid,nick))
|
||||
|
||||
wn6 = (1240 - 1040 / math.pow((min(TIER, 6)), 0.164)) * FRAGS + DAMAGE * 530 / (184 * math.exp(0.24 * TIER) + 130) + SPOT * 125 + min(DEF, 2.2) * 100 + ((185 / (0.17 + math.exp((WINRATE * 100 - 35) * -0.134))) - 500) * 0.45 + (6 - min(TIER, 6)) * (-60)
|
||||
|
||||
if wn6 > 2160:
|
||||
wn6_xvm = 100
|
||||
else:
|
||||
wn6_xvm = max(min(wn6*(wn6*(wn6*(-1.268e-11*wn6 + 5.147e-8) - 6.418e-5) + 7.576e-2) - 7.25, 100), 0)
|
||||
|
||||
msg += L('\nWN6 rating: %s (XVM: %s)','%s/%s'%(jid,nick)) % (int(round(wn6)), round(wn6_xvm, 1))
|
||||
|
||||
if wn6 < 425:
|
||||
msg += L(' - bad player','%s/%s'%(jid,nick))
|
||||
elif wn6 < 795:
|
||||
msg += L(' - player below average','%s/%s'%(jid,nick))
|
||||
elif wn6 < 1175:
|
||||
msg += L(' - average player','%s/%s'%(jid,nick))
|
||||
elif wn6 < 1570:
|
||||
msg += L(' - good player','%s/%s'%(jid,nick))
|
||||
elif wn6 < 1885:
|
||||
msg += L(' - great player','%s/%s'%(jid,nick))
|
||||
elif wn6 >= 1885:
|
||||
msg += L(' - unicum','%s/%s'%(jid,nick))
|
||||
|
||||
stat_rnd = lambda x: stat['all'][x] - stat['clan'][x] - stat['company'][x]
|
||||
|
||||
armor = math.log(stat_rnd('battles')) / 10 * (stat_rnd('xp')/float(stat_rnd('battles')) + stat_rnd('damage_dealt')/float(stat_rnd('battles')) * (stat_rnd('wins') * 2 + stat_rnd('frags') * 0.9 + (stat_rnd('spotted') + stat_rnd('capture_points') + stat_rnd('dropped_capture_points')) * 0.5)/float(stat_rnd('battles')))
|
||||
|
||||
msg += L('\nArmor-rating: %s','%s/%s'%(jid,nick)) % int(round(armor))
|
||||
|
||||
try:
|
||||
data = load_page('http://armor.kiev.ua/wot/api.php?version=iSida3')
|
||||
armor_limits = json.loads(data)
|
||||
|
||||
if armor > armor_limits['classRatings']['cv']:
|
||||
msg += L(' - virtuoso','%s/%s'%(jid,nick))
|
||||
elif armor > armor_limits['classRatings']['cm']:
|
||||
msg += L(' - master tanker','%s/%s'%(jid,nick))
|
||||
elif armor > armor_limits['classRatings']['c1']:
|
||||
msg += L(' - tanker 1st class','%s/%s'%(jid,nick))
|
||||
elif armor > armor_limits['classRatings']['c2']:
|
||||
msg += L(' - tanker 2nd class','%s/%s'%(jid,nick))
|
||||
elif armor > armor_limits['classRatings']['c3']:
|
||||
msg += L(' - tanker 3rd class','%s/%s'%(jid,nick))
|
||||
elif armor > armor_limits['classRatings']['d3']:
|
||||
msg += L(' - deerhead 3rd class','%s/%s'%(jid,nick))
|
||||
elif armor > armor_limits['classRatings']['d2']:
|
||||
msg += L(' - deerhead 2nd class','%s/%s'%(jid,nick))
|
||||
elif armor > armor_limits['classRatings']['d1']:
|
||||
msg += L(' - deerhead 1st class','%s/%s'%(jid,nick))
|
||||
else: #['dm']
|
||||
msg += L(' - master deerhead','%s/%s'%(jid,nick))
|
||||
except:
|
||||
pass
|
||||
|
||||
except:
|
||||
msg = L('Impossible to get statistics','%s/%s'%(jid,nick))
|
||||
elif not pdata['status']:
|
||||
msg = L('Query error','%s/%s'%(jid,nick))
|
||||
else:
|
||||
msg = L('Player not found','%s/%s'%(jid,nick))
|
||||
else:
|
||||
msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type,jid,nick,msg)
|
||||
|
||||
def wotclan(type, jid, nick, text):
|
||||
text = text.strip().upper()
|
||||
try:
|
||||
data = load_page('%s/2.0/clan/list/?application_id=%s&search=%s' % (API_ADDR, APP_ID, text))
|
||||
data = json.loads(data)
|
||||
claninfo = [i for i in data['data'] if i['abbreviation'] == text]
|
||||
if claninfo:
|
||||
claninfo = claninfo[0]
|
||||
clid = claninfo['clan_id']
|
||||
owner = claninfo['owner_name']
|
||||
created_at = claninfo['created_at']
|
||||
abbrev = claninfo['abbreviation']
|
||||
data = load_page('%s/2.0/clan/info/?application_id=%s&clan_id=%s' % (API_ADDR, APP_ID, clid))
|
||||
data = json.loads(data)
|
||||
claninfo2 = data['data'][str(clid)]
|
||||
msg = L('Name: %s [%s]','%s/%s'%(jid,nick)) % (claninfo2['name'], abbrev)
|
||||
msg += L('\nOwner: %s','%s/%s'%(jid,nick)) % owner
|
||||
msg += L('\nCreated at: %s','%s/%s'%(jid,nick)) % time.ctime(created_at)
|
||||
msg += L('\nCount of members: %s','%s/%s'%(jid,nick)) % claninfo2['members_count']
|
||||
msg += L('\nMotto: %s','%s/%s'%(jid,nick)) % claninfo2['motto']
|
||||
msg += '\n%s' % claninfo2['description']
|
||||
else:
|
||||
msg = L('Clan not found','%s/%s'%(jid,nick))
|
||||
except:
|
||||
msg = L('Impossible to get info','%s/%s'%(jid,nick))
|
||||
send_msg(type,jid,nick,msg)
|
||||
|
||||
def wotoffers(type, jid, nick, text):
|
||||
text = text.strip().split(' ', 1)
|
||||
try:
|
||||
url = 'http://jexp2.wotapi.ru/wotnews/get-news.php'
|
||||
d = '?'
|
||||
for opt in text:
|
||||
if opt in ['active', 'all']:
|
||||
url += '%sactivity=%s' % (d, opt)
|
||||
d = '&'
|
||||
if opt in ['real', 'prem', 'info']:
|
||||
url += '%sdetailed=%s' % (d, opt)
|
||||
d = '&'
|
||||
msg = load_page(url).decode('utf-8')
|
||||
except:
|
||||
msg = L('Impossible to get info','%s/%s'%(jid,nick))
|
||||
send_msg(type,jid,nick,msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'wot', wot, 2, 'World of Tanks - info about user. Usage: wot [nick [tank]]'),
|
||||
(3, 'wotclan', wotclan, 2, 'World of Tanks - info about clan. Usage: wotclan clan'),
|
||||
(3, 'wotoffers', wotoffers, 2, 'World of Tanks - info about offers. Usage: wotoffers [active|all] [real|prem|info]')]
|
||||
166
plugins/wtf.py
Normal file
166
plugins/wtf.py
Normal file
@@ -0,0 +1,166 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def wtfall(type, jid, nick, text):
|
||||
if text:
|
||||
ww = cur_execute_fetchall('select * from wtf where (room=%s or room=%s or room=%s) and wtfword=%s order by -time',(jid,'global','import',text))
|
||||
if ww: msg = L('I know that %s is %s','%s/%s'%(jid,nick)) % (text,'\n%s' % '\n\n'.join([L('from %s: %s','%s/%s'%(jid,nick)) % (t[3],t[5]) for t in ww]))
|
||||
else: msg = L('I don\'t know!','%s/%s'%(jid,nick))
|
||||
else: msg = L('What search?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def wtfsearch(type, jid, nick, text):
|
||||
if text:
|
||||
text = '%%%s%%' % text
|
||||
ww = cur_execute_fetchall('select wtfword from wtf where (room=%s or room=%s or room=%s) and (room ilike %s or jid ilike %s or nick ilike %s or wtfword ilike %s or wtftext ilike %s)',(jid,'global','import',text,text,text,text,text))
|
||||
if ww: msg = L('Some matches in definitions: %s','%s/%s'%(jid,nick)) % ', '.join(zip(*ww)[0])
|
||||
else: msg = L('No matches.','%s/%s'%(jid,nick))
|
||||
else: msg = L('What need to find?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def wtfrand(type, jid, nick):
|
||||
ww = cur_execute_fetchall('select * from wtf where room=%s or room=%s or room=%s',(jid,'global','import'))
|
||||
tlen = len(ww)
|
||||
ww = ww[random.randint(0,tlen-1)]
|
||||
msg = L('I know that %s is %s','%s/%s'%(jid,nick)) % (ww[4],ww[5])
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def wtfnames(type, jid, nick, text):
|
||||
text = text.strip().lower()
|
||||
if text == 'all': tmp = cur_execute_fetchall('select distinct wtfword from wtf where room=%s or room=%s or room=%s',(jid,'global','import'))
|
||||
elif text in ['global','import']: tmp = cur_execute_fetchall('select distinct wtfword from wtf where room=%s',(text,))
|
||||
else: tmp = cur_execute_fetchall('select distinct wtfword from wtf where room=%s',(jid,))
|
||||
if tmp: msg = L('All I know is: %s','%s/%s'%(jid,nick)) % ', '.join(zip(*tmp)[0])
|
||||
else: msg = L('No matches.','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def wtfcount(type, jid, nick):
|
||||
tlen = cur_execute_fetchall('select count(*) from wtf')[0][0]
|
||||
cnt = cur_execute_fetchall('select count(*) from wtf where room=%s',(jid,))[0][0]
|
||||
glb = cur_execute_fetchall('select count(*) from wtf where room=%s',('global',))[0][0]
|
||||
imp = cur_execute_fetchall('select count(*) from wtf where room=%s',('import',))[0][0]
|
||||
msg = L('Locale definition: %s\nGlobal: %s\nImported: %s\nTotal: %s','%s/%s'%(jid,nick)) % (cnt,glb,imp,tlen)
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def wtf(type, jid, nick, text): wtf_get(0,type, jid, nick, text)
|
||||
|
||||
def wtff(type, jid, nick, text): wtf_get(1,type, jid, nick, text)
|
||||
|
||||
def wwtf(type, jid, nick, text): wtf_get(2,type, jid, nick, text)
|
||||
|
||||
def wtfp(type, jid, nick, text):
|
||||
if '\n' in text:
|
||||
text = text.split('\n')
|
||||
tnick = text[1]
|
||||
ttext = text[0]
|
||||
is_found = 0
|
||||
for mmb in megabase:
|
||||
if mmb[0]==jid and mmb[1]==tnick:
|
||||
is_found = 1
|
||||
break
|
||||
if is_found:
|
||||
wtf_get(0,'chat', jid, tnick, ttext)
|
||||
send_msg(type, jid, nick, L('Send to private %s','%s/%s'%(jid,nick)) % tnick)
|
||||
else: send_msg(type, jid, nick, L('Nick %s not found!','%s/%s'%(jid,nick)) % tnick)
|
||||
else: wtf_get(0,'chat', jid, nick, text)
|
||||
|
||||
def wtf_get(ff,type, jid, nick, text):
|
||||
if text:
|
||||
ww = cur_execute_fetchone('select * from wtf where (room=%s or room=%s or room=%s) and wtfword=%s order by -time',(jid,'global','import',text))
|
||||
if ww:
|
||||
msg = L('I know that %s is %s','%s/%s'%(jid,nick)) % (text,ww[5])
|
||||
if ff == 1: msg += L('\nfrom: %s %s','%s/%s'%(jid,nick)) % (ww[3],'[%s]' % disp_time(ww[6],'%s/%s'%(jid,nick)))
|
||||
elif ff == 2: msg = L('I know that %s was defined by %s %s %s','%s/%s'%(jid,nick)) % (text,ww[3],'(%s)' % ww[2],'[%s]' % disp_time(ww[6],'%s/%s'%(jid,nick)))
|
||||
else: msg = L('I don\'t know!','%s/%s'%(jid,nick))
|
||||
else: msg = L('What search?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def dfn(type, jid, nick, text):
|
||||
text = text.strip()
|
||||
if '=' in text and text[0] != '=':
|
||||
al, realjid = get_level(jid,nick)
|
||||
what, text = map(lambda x: x.strip(), text.split('=', 1))
|
||||
matches = cur_execute_fetchall('select * from wtf where (room=%s or room=%s or room=%s) and wtfword=%s order by -time',(jid,'global','import',what))
|
||||
if matches:
|
||||
match_jid = None
|
||||
grr = getRoom(realjid)
|
||||
for t in matches:
|
||||
if getRoom(t[2]) == grr:
|
||||
match_jid = t[2]
|
||||
break
|
||||
if matches[0][1] == 'global': msg, text = L('This is global definition and not allowed to change!','%s/%s'%(jid,nick)), ''
|
||||
elif text == '':
|
||||
if match_jid:
|
||||
msg = L('Definition removed!','%s/%s'%(jid,nick))
|
||||
cur_execute('delete from wtf where wtfword=%s and room=%s and jid=%s',(what,jid,match_jid))
|
||||
else: msg = L('This definition is not Your!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
msg = L('Definition updated!','%s/%s'%(jid,nick))
|
||||
if match_jid: cur_execute('delete from wtf where wtfword=%s and room=%s and jid=%s',(what,jid,match_jid))
|
||||
elif text == '': msg = L('Nothing to remove!','%s/%s'%(jid,nick))
|
||||
else: msg = L('Definition saved!','%s/%s'%(jid,nick))
|
||||
idx = cur_execute_fetchall('select count(*) from wtf')[0][0]
|
||||
if text != '': cur_execute('insert into wtf values (%s,%s,%s,%s,%s,%s,%s,%s)', (idx, jid, realjid, nick, what, text, int(time.time()),al))
|
||||
else: msg = L('What need to remember?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def gdfn(type, jid, nick, text):
|
||||
text = text.strip()
|
||||
if '=' in text and text[0] != '=':
|
||||
al, realjid = get_level(jid,nick)
|
||||
what, text = map(lambda x: x.strip(), text.split('=', 1))
|
||||
matches = cur_execute_fetchall('select * from wtf where (room=%s or room=%s or room=%s) and wtfword=%s order by lim,-time',(jid,'global','import',what))
|
||||
if matches:
|
||||
max = -1
|
||||
for t in matches:
|
||||
if t[7] >= max: max,match=t[7],t
|
||||
if match[7] > al:
|
||||
msg,text = L('Not enough rights!','%s/%s'%(jid,nick)),''
|
||||
try: msg += ' ' + L(unlevltxt[unlevlnum[match[7]]],'%s/%s'%(jid,nick)) % L(unlevl[match[7]],'%s/%s'%(jid,nick))
|
||||
except: pass
|
||||
elif text == '':
|
||||
msg = L('Definition removed!','%s/%s'%(jid,nick))
|
||||
cur_execute('delete from wtf where wtfword=%s',(what,))
|
||||
else:
|
||||
msg = L('Definition updated!','%s/%s'%(jid,nick))
|
||||
if getRoom(realjid) == getRoom(match[2]): cur_execute('delete from wtf where wtfword=%s and jid=%s',(what,match[2]))
|
||||
elif text == '': msg = L('Nothing to remove!','%s/%s'%(jid,nick))
|
||||
else: msg = L('Definition saved!','%s/%s'%(jid,nick))
|
||||
idx = cur_execute_fetchall('select count(*) from wtf')[0][0]
|
||||
if text != '': cur_execute('insert into wtf values (%s,%s,%s,%s,%s,%s,%s,%s)', (idx, 'global', realjid, nick, what, text, int(time.time()),al))
|
||||
else: msg = L('What need to remember?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'wtfrand', wtfrand, 1, 'Random definition from base.'),
|
||||
(3, 'wtfnames', wtfnames, 2, 'List of definitions in conference.\nwtfnames [all|global|import]'),
|
||||
(3, 'wtfcount', wtfcount, 1, 'Definitions count.'),
|
||||
(3, 'wtfsearch', wtfsearch, 2, 'Search in definitions base.'),
|
||||
(3, 'wtfall', wtfall, 2, 'All definitions of word.'),
|
||||
(9, 'wwtf', wwtf, 2, 'Information about definition commiter.'),
|
||||
(3, 'wtff', wtff, 2, 'Show definition with nick and date.'),
|
||||
(3, 'wtfp', wtfp, 2, 'Show definition in private.\nwtfp word\n[nick]'),
|
||||
(0, 'wtf', wtf, 2, 'Show definition.'),
|
||||
(3, 'dfn', dfn, 2, 'Set definition.\ndfn word=definition - remember definition as word\ndfn word= - remove definition word'),
|
||||
(3, 'gdfn', gdfn, 2, 'Set global definition.\ngdfn word=definition - remember definition as word\ngdfn word= - remove definition word')]
|
||||
223
plugins/www.py
Normal file
223
plugins/www.py
Normal file
@@ -0,0 +1,223 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# Copyright (C) Vit@liy <vitaliy@root.ua> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
filename_chars_limit = 48
|
||||
last_url_watch = ''
|
||||
url_watch_ignore = ['pdf','sig','spl','class','ps','torrent','dvi','gz','pac','swf','tar','tgz','tar','zip','mp3','m3u','wma',\
|
||||
'wax','ogg','wav','gif','jar','jpg','jpeg','png','xbm','xpm','xwd','css','asc','c','cpp','log','conf','text',\
|
||||
'txt','dtd','xml','mpeg','mpg','mov','qt','avi','asf','asx','wmv','bz2','tbz','tar','so','dll','exe','bin',\
|
||||
'img','usbimg','rar','deb','rpm','iso','ico','apk','patch','svg','7z','tcl']
|
||||
|
||||
def rss_search(type, jid, nick, text):
|
||||
if text:
|
||||
if not re.findall('^http(s?)://',text[:10]): text = 'http://%s' % text
|
||||
text = enidna(text)
|
||||
msg, result = get_opener(text)
|
||||
if result:
|
||||
msg = L('Bad url or rss/atom not found!','%s/%s'%(jid,nick))
|
||||
page = remove_sub_space(html_encode(load_page(text)))
|
||||
page = get_tag(page,'head')
|
||||
l = []
|
||||
while '<link' in page:
|
||||
lnk = get_tag_full(page,'link')
|
||||
page = page.replace(lnk,'')
|
||||
l.append(lnk)
|
||||
if l:
|
||||
m = []
|
||||
for t in l:
|
||||
rss_type = get_subtag(t,'type')
|
||||
if rss_type in ['application/rss+xml','application/atom+xml']:
|
||||
if rss_type == 'application/rss+xml': rss_type = 'RSS'
|
||||
else: rss_type = 'ATOM'
|
||||
rss_title = get_subtag(t,'title')
|
||||
rss_href = get_subtag(t,'href')
|
||||
if rss_href == '/': rss_href = '/'.join(text.split('/',3)[:3]) + rss_href
|
||||
m.append('[%s] %s - %s' % (rss_type,rss_href,rss_title))
|
||||
if m:
|
||||
m = '\n'.join(m)
|
||||
msg = L('Found feed(s):%s%s','%s/%s'%(jid,nick)) % ([' ','\n']['\n' in m],unescape(m))
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def www_isdown(type, jid, nick, text):
|
||||
text = text.strip().lower()
|
||||
if text:
|
||||
if not re.findall('^http(s?)://',text[:10]): text = 'http://%s' % text
|
||||
_,result = get_opener(enidna(text))
|
||||
if result: msg = L('It\'s just you. %s is up.','%s/%s'%(jid,nick)) % text
|
||||
else: msg = L('It\'s not just you! %s looks down from here.','%s/%s'%(jid,nick)) % text
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def netheader(type, jid, nick, text):
|
||||
if text:
|
||||
try:
|
||||
regex = text.split('\n')[0].replace('*','*?')
|
||||
text = text.split('\n')[1]
|
||||
except: regex = None
|
||||
if not re.findall('^http(s?)://',text[:10]): text = 'http://%s' % text
|
||||
body, result = get_opener(enidna(text))
|
||||
if result:
|
||||
k = body.headers.keys()
|
||||
res = []
|
||||
for t in k:
|
||||
for tt in body.headers.getheaders(t): res.append('%s: %s' % (t,''.join([[r,'?'][r>'~'] for r in str(tt)])))
|
||||
body = '%s\n%s' % (text,'\n'.join(res))
|
||||
if regex:
|
||||
try:
|
||||
mt = re.findall(regex, body, re.S|re.I|re.U)
|
||||
if mt != []: body = ''.join(mt[0])
|
||||
else: body = L('RegExp not found!','%s/%s'%(jid,nick))
|
||||
except: body = L('Error in RegExp!','%s/%s'%(jid,nick))
|
||||
body = deidna(body)
|
||||
else: body = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, body)
|
||||
|
||||
def netwww(type, jid, nick, text):
|
||||
if text:
|
||||
try:
|
||||
regex = text.split('\n')[0].replace('*','*?')
|
||||
tmp = regex.split(' ', 1)
|
||||
if tmp[0].strip().isdigit():
|
||||
n = int(tmp[0])
|
||||
regex = tmp[1]
|
||||
else:
|
||||
n = 1
|
||||
text = text.split('\n')[1]
|
||||
except: regex = None
|
||||
if not re.findall('^http(s?)://',text[:10]): text = 'http://%s' % text
|
||||
text = enidna(text)
|
||||
msg, result = get_opener(text)
|
||||
if result:
|
||||
page = remove_sub_space(html_encode(load_page(text)))
|
||||
if regex:
|
||||
try:
|
||||
mt = re.findall(regex, page, re.S|re.I|re.U)
|
||||
if mt != []:
|
||||
if n:
|
||||
msg = unhtml_hard('\n'.join([''.join(t) for t in mt[:n]]))
|
||||
else:
|
||||
msg = unhtml_hard('\n'.join([''.join(t) for t in mt]))
|
||||
else: msg = L('RegExp not found!','%s/%s'%(jid,nick))
|
||||
except: msg = L('Error in RegExp!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
msg = urllib.unquote(unhtml_hard(page).encode('utf8')).decode('utf8', 'ignore')
|
||||
if '<title' in page: msg = '%s\n%s' % (rss_replace(get_tag(page,'title')), msg)
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg[:msg_limit])
|
||||
|
||||
def get_content_title(link):
|
||||
try:
|
||||
ll = link.lower()
|
||||
for t in url_watch_ignore:
|
||||
if ll.endswith('.%s' % t): raise
|
||||
link = enidna(link)
|
||||
original_page = load_page_size(urllib2.Request(link),8192)
|
||||
page = html_encode(original_page)
|
||||
if '<title' in page: tag = 'title'
|
||||
elif '<TITLE' in page: tag = 'TITLE'
|
||||
else: raise
|
||||
text = remove_sub_space(get_tag(page,tag).replace('\n',' ').replace('\r',' ').replace('\t',' '))
|
||||
while ' ' in text: text = text.replace(' ',' ')
|
||||
if text:
|
||||
cnt = 0
|
||||
for tmp in text: cnt += int(ord(tmp) in [1056,1057])
|
||||
if cnt >= len(text)/3: text = remove_sub_space(html_encode(get_tag(original_page,tag)).replace('\n',' ').replace('\r',' ').replace('\t',' '))
|
||||
except: text = ''
|
||||
return text.strip()
|
||||
|
||||
def parse_url_in_message(room,jid,nick,type,text):
|
||||
global last_url_watch
|
||||
if type != 'groupchat' or text == 'None' or nick == '' or getRoom(jid) == getRoom(selfjid): return
|
||||
if get_level(room,nick)[0] < 4: return
|
||||
content_title = None
|
||||
if get_config(getRoom(room),'store_users_url'):
|
||||
rjid = getRoom(jid)
|
||||
for t in text.split():
|
||||
link = re.findall(r'(http[s]?://.*)',t)
|
||||
if link:
|
||||
link = link[0].split(' ')[0].split('"')[0].split('\'')[0]
|
||||
if not cur_execute_fetchone('select * from url where room=%s and jid=%s and url=%s',(room,rjid,link)):
|
||||
ttext = get_content_title(link)
|
||||
if ttext:
|
||||
ttext = to_censore(rss_del_html(rss_replace(ttext)),room)
|
||||
content_title = [link,ttext]
|
||||
else:
|
||||
is_file,ttext = False,''
|
||||
ll = link.lower()
|
||||
for t in url_watch_ignore:
|
||||
if ll.endswith('.%s' % t):
|
||||
is_file = True
|
||||
break
|
||||
if is_file:
|
||||
body, result = get_opener(enidna(link))
|
||||
if result:
|
||||
mt = float(body.headers.get('Content-Length',0))
|
||||
if mt: ttext = L('Content length %s','%s/%s'%(jid,nick)) % get_size_human(mt)
|
||||
else: ttext = ''
|
||||
pprint('Store url: %s in %s/%s' % (link,room,nick),'white')
|
||||
cur_execute('insert into url values (%s,%s,%s,%s,%s,%s);',(room,rjid,nick,int(time.time()),link,ttext))
|
||||
was_shown = False
|
||||
if get_config(getRoom(room),'url_title'):
|
||||
try:
|
||||
link = re.findall(r'(http[s]?://.*)',text)[0].split(' ')[0].split('"')[0].split('\'')[0]
|
||||
if link and last_url_watch != link and pasteurl not in link:
|
||||
if content_title and content_title[0] == link: ttext = content_title[1]
|
||||
else: ttext = get_content_title(link)
|
||||
if ttext:
|
||||
pprint('Show url-title: %s in %s' % (link,room),'white')
|
||||
was_shown = True
|
||||
send_msg(type, room, '', L('Title: %s','%s/%s'%(jid,nick)) % to_censore(rss_del_html(rss_replace(ttext)),room))
|
||||
last_url_watch = link
|
||||
except: pass
|
||||
if not was_shown and get_config(getRoom(room),'content_length'):
|
||||
try:
|
||||
link = re.findall(u'(http[s]?://[-0-9a-zа-я.]+\/[-a-zа-я0-9._?#=@%/]+\.[a-z0-9]{2,7})',text,re.I+re.U+re.S)[0]
|
||||
if link and last_url_watch != link and pasteurl not in link:
|
||||
is_file = False
|
||||
ll = link.lower()
|
||||
for t in url_watch_ignore:
|
||||
if ll.endswith('.%s' % t):
|
||||
is_file = True
|
||||
break
|
||||
if is_file:
|
||||
last_url_watch = enidna(link)
|
||||
body, result = get_opener(last_url_watch)
|
||||
pprint('Show content length: %s in %s' % (link,room),'white')
|
||||
if result:
|
||||
mt = float(body.headers.get('Content-Length',0))
|
||||
if mt:
|
||||
link_end = urllib2.unquote(last_url_watch.rsplit('/',1)[-1]).decode('utf-8')
|
||||
link_end = u'…%s%s' % (['/',''][len(link_end)>filename_chars_limit], link_end[-filename_chars_limit:])
|
||||
send_msg(type, room, '', L('Length of %s is %s','%s/%s'%(jid,nick)) % (to_censore(link_end,room),get_size_human(mt)))
|
||||
except: pass
|
||||
|
||||
global execute
|
||||
|
||||
message_act_control = [parse_url_in_message]
|
||||
|
||||
execute = [(3, 'www', netwww, 2, 'Show web page.\nwww [count (0 for all)] regexp\n[http://]url - page after regexp\nwww [http://]url - without html tags'),
|
||||
(3, 'header', netheader, 2, 'Show net header'),
|
||||
(3, 'isdown', www_isdown, 2, 'Check works site'),
|
||||
(4, 'rss_search', rss_search, 2, 'Search RSS/ATOM feeds')]
|
||||
130
plugins/wz.py
Normal file
130
plugins/wz.py
Normal file
@@ -0,0 +1,130 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def check_wz(text):
|
||||
if not len(text): return True
|
||||
for tm in text:
|
||||
if ord(tm)<33 or ord(tm)>127: return True
|
||||
return None
|
||||
|
||||
def get_weather(text):
|
||||
wzc = cur_execute_fetchall('select code from wz where code ilike %s or city ilike %s or counry ilike %s',(text,text,text))
|
||||
if not wzc: return 'Not Found'
|
||||
if len(wzc) != 1: return 'Not Found'
|
||||
return load_page('http://weather.noaa.gov/pub/data/observations/metar/decoded/%s.TXT' % wzc[0][0].upper())
|
||||
|
||||
def weather(type, jid, nick, text):
|
||||
if check_wz(text): msg = L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
else:
|
||||
wzz = get_weather(text)
|
||||
if 'Not Found' in wzz: msg = L('City not found!','%s/%s'%(jid,nick))
|
||||
elif len(wzz.split('\n')) < 9: msg = L('Unexpected error','%s/%s'%(jid,nick))
|
||||
else:
|
||||
wzz = wzz.split('\n')
|
||||
wzr = []
|
||||
wzr.append(wzz[0]) # 0
|
||||
wzr.append(wzz[1]) # 1
|
||||
wzr.append(sfind(wzz,'Temperature')) # 2
|
||||
wzr.append(sfind(wzz,'Wind')) # 3
|
||||
wzr.append(sfind(wzz,'Relative')) # 4
|
||||
wzr.append(sfind(wzz,'Sky')) # 5
|
||||
wzr.append(sfind(wzz,'Weather')) # 6
|
||||
wzr.append(sfind(wzz,'Visibility')) # 7
|
||||
wzr.append(sfind(wzz,'Pressure')) # 8
|
||||
if ')' in wzr[0]: msg = wzr[0][:wzr[0].find(')')+1]
|
||||
else: msg = wzr[0]
|
||||
msg += '\n'+ wzr[1]
|
||||
wzz1 = wzr[2].find(':')+1 # Temperature
|
||||
wzz2 = wzr[2].find('(',wzz1)
|
||||
wzz3 = wzr[2].find(')',wzz2)
|
||||
msg += '\n'+ wzr[2][:wzz1] + ' ' + wzr[2][wzz2+1:wzz3]
|
||||
wzz1 = wzr[3].find('(')
|
||||
wzz2 = wzr[3].find(')',wzz1)
|
||||
wzz3 = wzr[3].find(':',wzz2)
|
||||
msg += '\n'+ wzr[3][:wzz1-1] + wzr[3][wzz2+1:wzz3]
|
||||
msg += '\n'+ wzr[4]
|
||||
if len(wzr[5]): msg += ','+ wzr[5][wzr[5].find(':')+1:]
|
||||
if len(wzr[6]): msg += ','+ wzr[6][wzr[6].find(':')+1:]
|
||||
if not (len(wzr[5])+len(wzr[6])): msg += ', clear'
|
||||
msg += '\n'+ wzr[7][:-2]
|
||||
wzz1 = wzr[8].find('(')
|
||||
wzz2 = wzr[8].find(':',wzz1)
|
||||
wzz3 = wzr[8].find('(',wzz2)
|
||||
msg += ', '+ wzr[8][:wzz1-1]+': '+wzr[8][wzz3+1:-1]
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def weather_short(type, jid, nick, text):
|
||||
if check_wz(text): msg = L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
else:
|
||||
wzz = get_weather(text)
|
||||
if 'Not Found' in wzz: msg = L('City not found!','%s/%s'%(jid,nick))
|
||||
elif len(wzz.split('\n')) < 9: msg = L('Unexpected error','%s/%s'%(jid,nick))
|
||||
else:
|
||||
wzz = wzz.split('\n')
|
||||
wzr = []
|
||||
wzr.append(wzz[0]) # 0
|
||||
wzr.append(sfind(wzz,'Temperature')) # 2
|
||||
wzr.append(sfind(wzz,'Wind')) # 3
|
||||
wzr.append(sfind(wzz,'Relative')) # 4
|
||||
wzr.append(sfind(wzz,'Sky')) # 5
|
||||
wzr.append(sfind(wzz,'Weather')) # 6
|
||||
if ')' in wzr[0]: msg = wzr[0][:wzr[0].find(')')+1]
|
||||
else: msg = wzr[0]
|
||||
wzz1 = wzr[1].find(':')+1 # Temperature
|
||||
wzz2 = wzr[1].find('(',wzz1)
|
||||
wzz3 = wzr[1].find(')',wzz2)
|
||||
msg += ' | '+ wzr[1][:wzz1] + ' ' + wzr[1][wzz2+1:wzz3]
|
||||
wzz1 = wzr[2].find('(')
|
||||
wzz2 = wzr[2].find(')',wzz1)
|
||||
wzz3 = wzr[2].find(':',wzz2)
|
||||
msg += ' | '+ wzr[2][:wzz1-1] + wzr[2][wzz2+1:wzz3]
|
||||
msg += ' | '+ wzr[3]
|
||||
if len(wzr[4]): msg += ','+ wzr[4][wzr[4].find(':')+1:]
|
||||
if len(wzr[5]): msg += ','+ wzr[5][wzr[5].find(':')+1:]
|
||||
if not (len(wzr[4])+len(wzr[5])): msg += ', clear'
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def weather_raw(type, jid, nick, text):
|
||||
if check_wz(text): msg = L('Error in parameters. Read the help about command.','%s/%s'%(jid,nick))
|
||||
else:
|
||||
msg = get_weather(text)[:-1]
|
||||
if 'Not Found' in msg: msg = L('City not found!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
def weather_search(type, jid, nick, text):
|
||||
if len(text):
|
||||
wzc = cur_execute_fetchall('select code,city,counry from wz where code ilike %s or city ilike %s or counry ilike %s',(text,text,text))
|
||||
if not wzc: msg = msg = L('City not found!','%s/%s'%(jid,nick))
|
||||
else:
|
||||
msg = ''
|
||||
for tmp in wzc: msg += '\n%s - %s (%s)' % tmp
|
||||
msg = L('Found: %s','%s/%s'%(jid,nick)) % msg
|
||||
else: msg = L('What?','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'wzz', weather_raw, 2, 'Weather by airport code. Full version.'),
|
||||
(3, 'wzs', weather_short, 2, 'Weather by airport code. Short version.'),
|
||||
(3, 'wz', weather, 2, 'Weather by airport code. Optimized version.'),
|
||||
(3, 'wzsearch', weather_search, 2, 'Search weather by code, city, country.')]
|
||||
49
plugins/youtube.py
Normal file
49
plugins/youtube.py
Normal file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# #
|
||||
# Plugin for iSida Jabber Bot #
|
||||
# Copyright (C) diSabler <dsy@dsy.name> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def youtube(type, jid, nick, text):
|
||||
if '\n' in text:
|
||||
try: lim = int(text.split('\n',1)[1])
|
||||
except: lim = GT('youtube_default_videos')
|
||||
if lim > GT('youtube_max_videos'): lim = GT('youtube_max_videos')
|
||||
if lim < 1: lim = 1
|
||||
text = text.split('\n',1)[0]
|
||||
else: lim = GT('youtube_default_videos')
|
||||
req = text.lower().encode("utf-8").replace(' ','+')
|
||||
url = 'http://gdata.youtube.com/feeds/api/videos?q=%s&alt=json-in-script&callback=yt&max-results=%s&format=5'
|
||||
res = json.loads(load_page(url % (req,lim)).split('yt(',1)[1][:-2])['feed']
|
||||
if res.has_key('entry'):
|
||||
msg = L('Found:','%s/%s'%(jid,nick))
|
||||
for t in res['entry']:
|
||||
y_title = t['title']['$t']
|
||||
try: y_views = t['yt$statistics']['viewCount']
|
||||
except: y_views = ''
|
||||
y_link = t['media$group'][u'media$player'][0]['url'].split('?v=',1)[1].split('&')[0]
|
||||
y_time = t['media$group'][u'media$thumbnail'][0]['time'].split('.',1)[0]
|
||||
msg += unescape('\nhttp://youtu.be/%s - %s [%s] %s' % (y_link,y_title,y_time,y_views))
|
||||
else: msg = L('Not found!','%s/%s'%(jid,nick))
|
||||
send_msg(type, jid, nick, msg)
|
||||
|
||||
global execute
|
||||
|
||||
execute = [(3, 'youtube', youtube, 2, 'Search at YouTube')]
|
||||
Reference in New Issue
Block a user