Коммит ночгого красноглазанья.
[nia.git] / jaconn.py
blob3246844fc857d3b812980dce4c810a0841c82d74
1 # -*- coding: utf-8 -*-
2 import xmpp, inspect, re
3 import ConfigParser
5 class bot:
6 def DEBUG(self, text=None):
7 '''Режим отладки и тестирования'''
8 if self.debug:
9 self.config_file = 'nia_test.cfg'
10 print unicode(text)
12 comm_pref = 'nia_'
13 admin_comm_pref = 'admin_'
14 def __init__(self):
15 self.debug = 0
17 self.config_file = 'nia.cfg'
18 self.resource= 'Nia Teppelin .NET'
19 self.version = '0.666'
20 self.os = 'Windows Vista'
22 self.DEBUG()
24 user, confs, ignore, alias = self.config(False)
25 self.JID = user['jid']
26 self.PASSWD = user['passwd']
27 self.NICK= unicode(user['nick'],'utf-8')
28 self.admin = xmpp.protocol.JID(user['admin'])
29 self.CONFS = confs
30 self.ignore = ignore
31 self.alias = alias
33 self.commands = {}
34 self.admin_commands = {}
35 self.help = {'com':[],'admin':[]}
36 for (name, value) in inspect.getmembers(self):
37 if inspect.ismethod(value) and name.startswith(self.comm_pref):
38 self.commands[name[len(self.comm_pref):]] = value
39 self.help['com'].append(name[len(self.comm_pref):])
40 if inspect.ismethod(value) and name.startswith(self.admin_comm_pref):
41 self.admin_commands[name[len(self.admin_comm_pref):]] = value
42 self.help['admin'].append(name[len(self.admin_comm_pref):])
43 self.help = {'com':', '.join(self.help['com']),'admin':', '.join(self.help['admin'])}
47 def config(self,flag,confs=None,ignore=None):
48 config = ConfigParser.ConfigParser()
49 def config_write():
50 config.add_section('alias')
51 for key in self.alias:
52 config.set('alias', key, self.alias[key])
53 config.add_section('general')
54 config.set('general', 'jid', self.JID)
55 config.set('general', 'passwd', self.PASSWD)
56 config.set('general', 'nick', self.NICK)
57 config.set('general', 'admin', self.admin)
58 config.set('general', 'ignore', ','.join(ignore))
59 config.set('general', 'confs', ','.join(confs) )
60 config.write(open(self.config_file,'w'))
61 def config_read():
62 alias = {}
63 config.read(self.config_file)
64 user = {'jid':config.get('general','jid'),
65 'passwd':config.get('general','passwd'),
66 'nick':config.get('general','nick'),
67 'admin':config.get('general','admin')}
68 confs = config.get('general','confs').decode('utf-8').split(',')
69 ignore = config.get('general','ignore').decode('utf-8').split(',')
70 for key in config.options('alias'):
71 alias[key] = config.get('alias',key)
72 return user, confs, ignore, alias
73 if flag:
74 config_write()
75 else:
76 return config_read()
79 def connect(self):
80 '''Подключение к серверу'''
81 self.jid = xmpp.protocol.JID(self.JID)
82 self.conn=xmpp.Client(self.jid.getDomain(),debug=[])
83 self.conn.connect()
84 self.conn.auth(self.jid.getNode(),self.PASSWD,'nyaa~')
85 self.conn.sendInitPresence()
86 self.conn.RegisterDisconnectHandler(self.conn.reconnectAndReauth)
87 self.conn.RegisterHandler('message',self.get_mes)
88 self.conn.RegisterHandler('iq', self.iq_version, typ='get', ns=xmpp.NS_VERSION)
89 self.conn.RegisterHandler('iq', self.get_iq, typ='result', ns=xmpp.NS_VERSION)
91 def iq_version(self, conn, iq):
92 """Returns reply to iq:version"""
93 iq=iq.buildReply('result')
94 qp=iq.getTag('query')
95 qp.setTagData('name', self.resource)
96 qp.setTagData('version', self.version)
97 qp.setTagData('os', self.os)
98 conn.send(iq)
99 raise xmpp.NodeProcessed
101 def join_room(self, confs):
102 for conf in confs:
103 self.p=xmpp.Presence(to='%s/%s'%(conf,self.NICK))
104 self.p.setTag('Nia',namespace=xmpp.NS_MUC).setTagData('password','')
105 self.p.getTag('Nia').addChild('history',{'maxchars':'0','maxstanzas':'0'})
106 self.conn.send(self.p)
107 def leave_room(self, confs):
108 for conf in confs:
109 to = '%s/%s'%(conf,self.NICK)
110 self.send_system(to,'offline','unavailable')
111 def reconnect(self):
112 self.connect()
113 self.join_room(self.CONFS)
114 def online(self):
115 self.connect()
116 self.join_room(self.CONFS)
117 while True:
118 try:
119 self.conn.Process(1)
120 except xmpp.protocol.XMLNotWellFormed:
121 self.reconnect()
124 def send(self, text, extra=None, flag=True):
126 True - chat
127 False - xml
129 if flag:
130 self.conn.send(xmpp.protocol.Message(self.to,text,self.type))
131 else:
132 '''Отправка сообщения в форме xhtml'''
134 xhtml = '''
135 <html xmlns='http://jabber.org/protocol/xhtml-im'>
136 <body xml:lang='en-US' xmlns='http://www.w3.org/1999/xhtml'>
138 </body></html>
139 '''%extra
141 self.conn.send("<message to='%s' type='%s'><body>%s</body>%s</message>"%(self.to,self.type,text,xhtml))
143 def send_system(self,to,msg,type):
144 '''Отправка системного сообщения. Статусы'''
145 print to, msg, type
146 self.conn.send(xmpp.protocol.Presence(to=to,status=msg,typ=type))
148 def XMLescape(self, text):
149 return xmpp.simplexml.XMLescape(text)
151 def get_mes(self, conn, mess):
152 def parse():
153 if self.type_f:
154 text = re.findall('^%s[\W]{0,2}[\s]{1,3}(.*?)$'%self.NICK,self.text)
155 else:
156 text = re.findall('^(.*?)$',self.text)
157 self.DEBUG(text)
158 if text:
159 tmp = text[0].split(' ',1)
160 if len(tmp) >= 2: cmd, args = tmp[0], tmp[1]
161 elif len(tmp) == 1: cmd, args = tmp[0], ''
162 return cmd, args
164 else: return False, False
165 def alias(cmd, args):
166 text = ' '.join( (self.alias[cmd], args))
167 tmp = text.split(' ',1)
168 if len(tmp) >= 2: cmd, args = tmp[0], tmp[1]
169 elif len(tmp) == 1: cmd, args = tmp[0], ''
170 return cmd, args
172 self.type=mess.getType()
173 self.nick=mess.getFrom()
174 self.text=mess.getBody()
176 if self.type == 'groupchat':
177 self.to = self.nick.getStripped()
178 nick = self.nick.getResource()
179 self.type_f = True
180 elif self.type == 'chat' and self.nick.getDomain().startswith('conference.'):
181 self.to = self.nick
182 nick = self.nick.getResource()
183 self.type_f = False
184 elif self.type == 'chat':
185 self.to = self.nick.getStripped()
186 nick = self.nick.getNode()
187 self.type_f = False
189 ''' if (user in CONFERENCES) or (user in [i+u'/'+jid.getResource() for i in CONFERENCES]) or (user in IGNORE) or (user.getStripped() in IGNORE) or (type(text)!=type(u'')):
191 self.DEBUG([self.nick,self.text,self.type])
192 self.DEBUG(mess)
193 if self.ignore.count(self.nick) or re.match('%s/%s'%(self.to,self.NICK),'%s/%s'%(self.to,nick) ):
194 pass
195 elif self.text.startswith(self.NICK) or not self.type_f:
196 cmd, args = parse()
197 if self.alias.has_key(cmd):
198 cmd,args = alias(cmd, args)
199 if cmd:
200 if self.commands.has_key(cmd):
201 self.commands[cmd](args)
202 elif self.admin_commands.has_key(cmd):
203 if nick == self.admin.getNode() or self.to == str(self.admin).lower() :
204 self.admin_commands[cmd](self.nick,args)
205 else: self.send('%s~ nyaaa? Access denied...'%nick)
206 else: self.send('%s~ nyaaa? Type "help"...'%nick)
207 else: self.send('%s~ nyaaa? Type "help"...'%nick)
210 def send_iq(self,_type, to):
211 self.conn.send(xmpp.protocol.Iq(to=to,typ=_type ,queryNS=xmpp.NS_VERSION))
212 def get_iq(self,conn,mess):
213 query = mess.getTag('query')
214 client = '%s %s'%(query.getTagData('name'),query.getTagData('version') )
215 os = query.getTagData('os')
216 target = mess.getFrom().getResource()
217 toversion = '%s has client %s at %s'%(target, client, os)
218 self.send(toversion)
226 http://code.google.com/p/robocat/source/browse/trunk/start.py
227 http://www.linux.org.ru/view-message.jsp?msgid=2591531#2591657