Фикс багов с iq:version
[nia.git] / jaconn.py
blobdcd82c25e8369a2650f0c8f1581fea4d630d10d2
1 # -*- coding: utf-8 -*-
2 import xmpp, inspect, re
3 import ConfigParser
5 class bot:
6 comm_pref = 'nia_'
7 admin_comm_pref = 'admin_'
8 def __init__(self):
9 user, confs, ignore = self.config(False)
10 self.JID = user['jid']
11 self.PASSWD = user['passwd']
12 self.NICK= user['nick']
13 self.admin = xmpp.protocol.JID(user['admin'])
14 self.CONFS = confs
15 self.commands = {}
16 self.admin_commands = {}
17 self.ignore = ignore
19 self.resource= 'Nia Teppelin'
20 self.version = '0.666'
21 self.os = '.NET Windows Vista'
22 self.help = {'com':[],'admin':[]}
23 for (name, value) in inspect.getmembers(self):
24 # print name, value
25 if inspect.ismethod(value) and name.startswith(self.comm_pref):
26 self.commands[name[len(self.comm_pref):]] = value
27 self.help['com'].append(name[len(self.comm_pref):])
28 if inspect.ismethod(value) and name.startswith(self.admin_comm_pref):
29 self.admin_commands[name[len(self.admin_comm_pref):]] = value
30 self.help['admin'].append(name[len(self.admin_comm_pref):])
31 #print self.commands, self.admin_commands
32 self.help = {'com':', '.join(self.help['com']),'admin':', '.join(self.help['admin'])}
35 def config(self,flag,confs=None,ignore=None):
36 config = ConfigParser.ConfigParser()
37 def config_write():
38 config.add_section('general')
39 config.set('general', 'jid', self.JID)
40 config.set('general', 'passwd', self.PASSWD)
41 config.set('general', 'nick', self.NICK)
42 config.set('general', 'admin', self.admin)
43 config.set('general', 'ignore', ','.join(ignore))
44 config.set('general', 'confs', ','.join(confs) )
45 config.write(open('nia.cfg','w'))
46 def config_read():
47 config.read('nia.cfg')
48 user = {'jid':config.get('general','jid'),
49 'passwd':config.get('general','passwd'),
50 'nick':config.get('general','nick'),
51 'admin':config.get('general','admin')}
52 confs = config.get('general','confs').decode('utf-8').split(',')
53 ignore = config.get('general','ignore').decode('utf-8').split(',')
54 return user, confs, ignore
55 if flag:
56 config_write()
57 else:
58 return config_read()
61 def connect(self):
62 '''Подключение к серверу'''
63 self.jid = xmpp.protocol.JID(self.JID)
64 self.conn=xmpp.Client(self.jid.getDomain(),debug=[])
65 self.conn.connect()
66 self.conn.auth(self.jid.getNode(),self.PASSWD,'nyaa~')
67 self.conn.sendInitPresence()
68 self.conn.RegisterDisconnectHandler(self.conn.reconnectAndReauth)
69 self.conn.RegisterHandler('message',self.get_mes)
70 self.conn.RegisterHandler('iq', self.iq_version, typ='get', ns=xmpp.NS_VERSION)
72 def iq_version(self, conn, iq):
73 """Returns reply to iq:version"""
74 iq=iq.buildReply('result')
75 qp=iq.getTag('query')
76 qp.setTagData('name', self.resource)
77 qp.setTagData('version', self.version)
78 qp.setTagData('os', self.os)
79 conn.send(iq)
80 raise xmpp.NodeProcessed
82 def join_room(self, confs):
83 for conf in confs:
84 self.p=xmpp.Presence(to='%s/%s'%(conf,self.NICK))
85 self.p.setTag('Nia',namespace=xmpp.NS_MUC).setTagData('password','')
86 self.p.getTag('Nia').addChild('history',{'maxchars':'0','maxstanzas':'0'})
87 self.conn.send(self.p)
88 def leave_room(self, confs):
89 for conf in confs:
90 to = '%s/%s'%(conf,self.NICK)
91 self.send_system(to,'offline','unavailable')
92 def reconnect(self):
93 self.connect()
94 self.join_room(self.CONFS)
95 def online(self):
96 self.connect()
97 self.join_room(self.CONFS)
98 while True:
99 try:
100 self.conn.Process(1)
101 except xmpp.protocol.XMLNotWellFormed:
102 self.reconnect()
105 def send_chat(self,type,to,text):
106 ''' Отправка в чат обычного сообщения.
107 type - тип сообщения, groupchat или chat
108 to - кому отправляем
109 text - отправляемый текст'''
110 self.conn.send(xmpp.protocol.Message(to,text,type))
112 def send_system(self,to,msg,type):
113 '''Отправка системного сообщения. Статусы'''
114 print to, msg, type
115 self.conn.send(xmpp.protocol.Presence(to=to,status=msg,typ=type))
116 def XMLescape(self, text):
117 return xmpp.simplexml.XMLescape(text)
119 def send_xml(self,type,to,text,extra):
120 '''Отправка сообщения в форме xhtml'''
121 xhtml = '''
122 <html xmlns='http://jabber.org/protocol/xhtml-im'>
123 <body xml:lang='en-US' xmlns='http://www.w3.org/1999/xhtml'>
125 </body></html>
126 '''%extra
128 self.conn.send("<message to='%s' type='%s'><body>%s</body>%s</message>"%(to,type,text,xhtml))
130 def get_mes(self,conn,mess):
131 ''' Получение сообщений и обработка'''
132 self.type=mess.getType()
133 self.nick=mess.getFrom()
134 self.text=mess.getBody()
135 #print self.type.encode('utf-8'), self.nick.encode('utf-8'), self.text.encode('utf-8')
136 if self.ignore.count(self.nick.getResource()):
137 pass
138 elif self.type == 'groupchat':
139 if re.match('^%s[\W]'%self.NICK, self.text):
140 self.to = '%s@%s'%(self.nick.getNode(),self.nick.getDomain())
141 nick = self.nick.getResource()
142 text = re.findall('^%s[\W]{0,2}[\s]{1,3}(.*?)$'%self.NICK,self.text)[0]
144 tmp = text.split(' ',1)
145 if len(tmp) >= 2:
146 cmd = tmp[0]
147 args = tmp[1]
148 elif len(tmp) == 1:
149 cmd = tmp[0]
150 args = ''
152 if self.commands.has_key(cmd):
154 True - chat
155 False - xml
157 result = self.commands[cmd](args)
159 if result[0]:
160 text = result[1]
161 self.send_chat(self.type,to,text)
162 else:
163 text,extra = result[1],result[2]
164 self.send_xml(self.type, to, text, extra)
166 elif self.admin_commands.has_key(cmd):
167 if nick == self.admin.getNode():
168 result = self.admin_commands[cmd](self.nick,args)
169 if result:
170 text = result
171 self.send_chat(self.type,self.to,text)
172 else: pass
173 else: self.send_chat(self.type, self.to, '%s~ nyaaa? Access denied...'%nick)
174 else: self.send_chat(self.type, self.to, '%s~ nyaaa? Type "help"...'%nick)
175 else: return
177 elif self.type == 'chat':
178 if '%s@%s'%(self.nick.getNode(),self.nick.getDomain()) == self.admin:
179 tmp = self.text.split(' ',1)
180 print tmp
181 if len(tmp) >= 2:
182 cmd = tmp[0]
183 args = tmp[1]
184 elif len(tmp) == 1:
185 cmd = tmp[0]
186 args = ''
187 print cmd, args
188 if self.admin_commands.has_key(cmd):
189 self.admin_commands[cmd](args)
192 def send_iq(self,_type, to):
193 self.conn.send(xmpp.protocol.Iq(to=to,typ=_type ,queryNS=xmpp.NS_VERSION))
194 def get_iq(self,conn,mess):
195 print mess
196 self.query = mess
197 '''
198 query = mess.getTag('query')
199 client = '%s %s'%(query.getTagData('name'),query.getTagData('version') )
200 os = query.getTagData('os')
201 self._version=(client, os)
202 print self._version
211 http://code.google.com/p/robocat/source/browse/trunk/start.py
214 <iq from='apkawa@jabber.ru/LoR' to='apkawa@jabber.ru/LoR' xml:lang='ru' id='1856' type='result'>
215 <query xmlns='jabber:iq:version'>
216 <name>Gajim</name>
217 <version>0.11.4.4-svn</version>
218 <os>Arch Linux</os>
219 </query>
220 </iq>
223 http://www.linux.org.ru/view-message.jsp?msgid=2591531#2591657
225 <presence to="жабы@conference.jabber.ru/Apkawa" xml:lang="ru" type="unavailable" id="1345">
226 <status>offline</status>
227 </presence>
229 <presence from='жабы@conference.jabber.ru/Apkawa' to='apkawa@jabber.ru/LoR' xml:lang='ru' type='unavailable' id='1345'>
230 <status>offline</status>
231 <x xmlns='http://jabber.org/protocol/muc#user'>
232 <item affiliation='owner' role='none'/>
233 </x>
234 </presence>