]>
code.delx.au - pymsnt/blob - src/misciq.py
1 # Copyright 2004-2005 James Bunton <james@delx.cjb.net>
2 # Licensed for distribution under the GPL version 2, check COPYING for details
5 if(utils
.checkTwisted()):
6 from twisted
.xish
.domish
import Element
7 from twisted
.words
.protocols
.jabber
import jid
9 from tlib
.domish
import Element
10 from tlib
.jabber
import jid
11 from twisted
.internet
import reactor
, task
12 from debug
import LogEvent
, INFO
, WARN
, ERROR
23 def __init__(self
, pytrans
):
24 self
.pytrans
= pytrans
25 self
.pytrans
.adHocCommands
.addCommand("connectusers", self
.incomingIq
, "command_ConnectUsers")
28 for jid
in self
.pytrans
.xdb
.files():
29 jabw
.sendPresence(self
.pytrans
, jid
, config
.jid
, ptype
="probe")
31 def incomingIq(self
, el
):
32 to
= el
.getAttribute("from")
33 ID
= el
.getAttribute("id")
34 ulang
= utils
.getLang(el
)
36 if config
.admins
.count(jid
.JID(to
).userhost()) == 0:
37 self
.pytrans
.discovery
.sendIqError(to
=to
, fro
=config
.jid
, ID
=ID
, xmlns
=disco
.COMMANDS
, etype
="cancel", condition
="not-authorized")
43 iq
= Element((None, "iq"))
44 iq
.attributes
["to"] = to
45 iq
.attributes
["from"] = config
.jid
47 iq
.attributes
["id"] = ID
48 iq
.attributes
["type"] = "result"
50 command
= iq
.addElement("command")
51 command
.attributes
["sessionid"] = self
.pytrans
.makeMessageID()
52 command
.attributes
["xmlns"] = disco
.COMMANDS
53 command
.attributes
["status"] = "completed"
55 x
= command
.addElement("x")
56 x
.attributes
["xmlns"] = "jabber:x:data"
57 x
.attributes
["type"] = "result"
59 title
= x
.addElement("title")
60 title
.addContent(lang
.get(ulang
).command_ConnectUsers
)
62 field
= x
.addElement("field")
63 field
.attributes
["type"] = "fixed"
64 field
.addElement("value").addContent(lang
.get(ulang
).command_Done
)
70 def __init__(self
, pytrans
):
71 self
.pytrans
= pytrans
72 self
.pytrans
.adHocCommands
.addCommand("stats", self
.incomingIq
, "command_Statistics")
74 # self.stats is indexed by a unique ID, with value being the value for that statistic
76 self
.stats
["Uptime"] = 0
77 self
.stats
["OnlineUsers"] = 0
78 self
.stats
["TotalUsers"] = 0
80 legacy
.startStats(self
)
82 def incomingIq(self
, el
):
83 to
= el
.getAttribute("from")
84 ID
= el
.getAttribute("id")
85 ulang
= utils
.getLang(el
)
87 iq
= Element((None, "iq"))
88 iq
.attributes
["to"] = to
89 iq
.attributes
["from"] = config
.jid
91 iq
.attributes
["id"] = ID
92 iq
.attributes
["type"] = "result"
94 command
= iq
.addElement("command")
95 command
.attributes
["sessionid"] = self
.pytrans
.makeMessageID()
96 command
.attributes
["xmlns"] = disco
.COMMANDS
97 command
.attributes
["status"] = "completed"
99 x
= command
.addElement("x")
100 x
.attributes
["xmlns"] = "jabber:x:data"
101 x
.attributes
["type"] = "result"
103 title
= x
.addElement("title")
104 title
.addContent(lang
.get(ulang
).command_Statistics
)
106 for key
in self
.stats
:
107 label
= getattr(lang
.get(ulang
), "command_%s" % key
)
108 description
= getattr(lang
.get(ulang
), "command_%s_Desc" % key
)
109 field
= x
.addElement("field")
110 field
.attributes
["var"] = key
111 field
.attributes
["label"] = label
112 field
.attributes
["type"] = "text-single"
113 field
.addElement("value").addContent(str(self
.stats
[key
]))
114 field
.addElement("desc").addContent(description
)
116 self
.pytrans
.send(iq
)
121 def __init__(self
, pytrans
):
122 self
.pytrans
= pytrans
123 self
.pytrans
.discovery
.addFeature(disco
.COMMANDS
, self
.incomingIq
, config
.jid
)
124 self
.pytrans
.discovery
.addNode(disco
.COMMANDS
, self
.sendCommandList
, "command_CommandList", config
.jid
, True)
126 self
.commands
= {} # Dict of handlers indexed by node
127 self
.commandNames
= {} # Dict of names indexed by node
129 def addCommand(self
, command
, handler
, name
):
130 self
.commands
[command
] = handler
131 self
.commandNames
[command
] = name
132 self
.pytrans
.discovery
.addNode(command
, self
.incomingIq
, name
, config
.jid
, False)
134 def incomingIq(self
, el
):
135 itype
= el
.getAttribute("type")
136 fro
= el
.getAttribute("from")
138 to
= el
.getAttribute("to")
139 ID
= el
.getAttribute("id")
141 LogEvent(INFO
, "", "Looking for handler")
144 for child
in el
.elements():
145 xmlns
= child
.defaultUri
146 node
= child
.getAttribute("node")
149 if(child
.name
== "query" and xmlns
== disco
.DISCO_INFO
):
150 if(node
and self
.commands
.has_key(node
) and (itype
== "get")):
151 self
.sendCommandInfoResponse(to
=fro
, ID
=ID
)
153 elif(child
.name
== "query" and xmlns
== disco
.DISCO_ITEMS
):
154 if(node
and self
.commands
.has_key(node
) and (itype
== "get")):
155 self
.sendCommandItemsResponse(to
=fro
, ID
=ID
)
157 elif(child
.name
== "command" and xmlns
== disco
.COMMANDS
):
158 if((node
and self
.commands
.has_key(node
)) and (itype
== "set" or itype
== "error")):
159 self
.commands
[node
](el
)
162 LogEvent(WARN
, "", "Unknown Ad-Hoc command received.")
163 self
.pytrans
.discovery
.sendIqError(to
=fro
, fro
=config
.jid
, ID
=ID
, xmlns
=xmlns
, etype
="cancel", condition
="feature-not-implemented")
166 def sendCommandList(self
, el
):
167 to
= el
.getAttribute("from")
168 ID
= el
.getAttribute("id")
169 ulang
= utils
.getLang(el
)
171 iq
= Element((None, "iq"))
172 iq
.attributes
["to"] = to
173 iq
.attributes
["from"] = config
.jid
175 iq
.attributes
["id"] = ID
176 iq
.attributes
["type"] = "result"
178 query
= iq
.addElement("query")
179 query
.attributes
["xmlns"] = disco
.DISCO_ITEMS
180 query
.attributes
["node"] = disco
.COMMANDS
182 for command
in self
.commands
:
183 item
= query
.addElement("item")
184 item
.attributes
["jid"] = config
.jid
185 item
.attributes
["node"] = command
186 item
.attributes
["name"] = getattr(lang
.get(ulang
), self
.commandNames
[command
])
188 self
.pytrans
.send(iq
)
190 def sendCommandInfoResponse(self
, to
, ID
):
191 LogEvent(INFO
, "", "Replying to disco#info")
192 iq
= Element((None, "iq"))
193 iq
.attributes
["type"] = "result"
194 iq
.attributes
["from"] = config
.jid
195 iq
.attributes
["to"] = to
196 if(ID
): iq
.attributes
["id"] = ID
197 query
= iq
.addElement("query")
198 query
.attributes
["xmlns"] = disco
.DISCO_INFO
200 feature
= query
.addElement("feature")
201 feature
.attributes
["var"] = disco
.COMMANDS
202 self
.pytrans
.send(iq
)
204 def sendCommandItemsResponse(self
, to
, ID
):
205 LogEvent(INFO
, "", "Replying to disco#items")
206 iq
= Element((None, "iq"))
207 iq
.attributes
["type"] = "result"
208 iq
.attributes
["from"] = config
.jid
209 iq
.attributes
["to"] = to
210 if(ID
): iq
.attributes
["id"] = ID
211 query
= iq
.addElement("query")
212 query
.attributes
["xmlns"] = disco
.DISCO_ITEMS
213 self
.pytrans
.send(iq
)
217 def __init__(self
, pytrans
):
218 self
.pytrans
= pytrans
219 self
.pytrans
.discovery
.addFeature("vcard-temp", self
.incomingIq
, "USER")
220 self
.pytrans
.discovery
.addFeature("vcard-temp", self
.incomingIq
, config
.jid
)
222 def incomingIq(self
, el
):
223 itype
= el
.getAttribute("type")
224 fro
= el
.getAttribute("from")
226 to
= el
.getAttribute("to")
227 ID
= el
.getAttribute("id")
228 if(itype
!= "get" and itype
!= "error"):
229 self
.pytrans
.discovery
.sendIqError(to
=fro
, fro
=config
.jid
, ID
=ID
, xmlns
="vcard-temp", etype
="cancel", condition
="feature-not-implemented")
232 LogEvent(INFO
, "", "Sending vCard")
234 toGateway
= not (to
.find('@') > 0)
237 if(not self
.pytrans
.sessions
.has_key(froj
.userhost())):
238 self
.pytrans
.discovery
.sendIqError(to
=fro
, fro
=config
.jid
, ID
=ID
, xmlns
="vcard-temp", etype
="auth", condition
="not-authorized")
240 s
= self
.pytrans
.sessions
[froj
.userhost()]
242 self
.pytrans
.discovery
.sendIqError(to
=fro
, fro
=config
.jid
, ID
=ID
, xmlns
="vcard-temp", etype
="auth", condition
="not-authorized")
245 c
= s
.contactList
.findContact(to
)
247 self
.pytrans
.discovery
.sendIqError(to
=fro
, fro
=config
.jid
, ID
=ID
, xmlns
="vcard-temp", etype
="cancel", condition
="recipient-unavailable")
251 iq
= Element((None, "iq"))
252 iq
.attributes
["to"] = fro
253 iq
.attributes
["from"] = to
255 iq
.attributes
["id"] = ID
256 iq
.attributes
["type"] = "result"
257 vCard
= iq
.addElement("vCard")
258 vCard
.attributes
["xmlns"] = "vcard-temp"
260 FN
= vCard
.addElement("FN")
261 FN
.addContent(legacy
.name
)
262 DESC
= vCard
.addElement("DESC")
263 DESC
.addContent(legacy
.name
)
264 URL
= vCard
.addElement("URL")
265 URL
.addContent(legacy
.url
)
268 NICKNAME
= vCard
.addElement("NICKNAME")
269 NICKNAME
.addContent(c
.nickname
)
271 PHOTO
= c
.avatar
.makePhotoElement()
272 vCard
.addChild(PHOTO
)
274 self
.pytrans
.send(iq
)
276 class IqAvatarFactory
:
277 def __init__(self
, pytrans
):
278 self
.pytrans
= pytrans
279 self
.pytrans
.discovery
.addFeature(disco
.IQAVATAR
, self
.incomingIq
, "USER")
280 self
.pytrans
.discovery
.addFeature(disco
.STORAGEAVATAR
, self
.incomingIq
, "USER")
282 def incomingIq(self
, el
):
283 itype
= el
.getAttribute("type")
284 fro
= el
.getAttribute("from")
286 to
= el
.getAttribute("to")
287 ID
= el
.getAttribute("id")
289 if(itype
!= "get" and itype
!= "error"):
290 self
.pytrans
.discovery
.sendIqError(to
=fro
, fro
=config
.jid
, ID
=ID
, xmlns
=disco
.IQAVATAR
, etype
="cancel", condition
="feature-not-implemented")
293 LogEvent(INFO
, "", "Retrieving avatar")
295 if(not self
.pytrans
.sessions
.has_key(froj
.userhost())):
296 self
.pytrans
.discovery
.sendIqError(to
=fro
, fro
=config
.jid
, ID
=ID
, xmlns
=disco
.IQAVATAR
, etype
="auth", condition
="not-authorized")
298 s
= self
.pytrans
.sessions
[froj
.userhost()]
300 self
.pytrans
.discovery
.sendIqError(to
=fro
, fro
=config
.jid
, ID
=ID
, xmlns
=disco
.IQAVATAR
, etype
="auth", condition
="not-authorized")
303 c
= s
.contactList
.findContact(to
)
305 self
.pytrans
.discovery
.sendIqError(to
=fro
, fro
=config
.jid
, ID
=ID
, xmlns
=disco
.IQAVATAR
, etype
="cancel", condition
="recipient-unavailable")
308 iq
= Element((None, "iq"))
309 iq
.attributes
["to"] = fro
310 iq
.attributes
["from"] = to
312 iq
.attributes
["id"] = ID
313 iq
.attributes
["type"] = "result"
314 query
= iq
.addElement("query")
315 query
.attributes
["xmlns"] = disco
.IQAVATAR
317 DATA
= c
.avatar
.makeDataElement()
320 self
.pytrans
.send(iq
)
325 def __init__(self
, pytrans
):
326 self
.pytrans
= pytrans
327 # self.pingCounter = 0
328 # self.pingTask = task.LoopingCall(self.pingCheck)
329 self
.pingTask
= task
.LoopingCall(self
.whitespace
)
330 # reactor.callLater(10.0, self.start)
333 # self.pingTask.start(120.0)
335 def whitespace(self
):
336 self
.pytrans
.send(" ")
338 # def pingCheck(self):
339 # if(self.pingCounter >= 2 and self.pytrans.xmlstream): # Two minutes of no response from the main server
340 # LogEvent(WARN, "", "Disconnecting because the main server has ignored our pings for too long.")
341 # self.pytrans.xmlstream.transport.loseConnection()
342 # elif(config.mainServerJID):
343 # d = self.pytrans.discovery.sendIq(self.makePingPacket())
344 # d.addCallback(self.pongReceived)
345 # d.addErrback(self.pongFailed)
346 # self.pingCounter += 1
348 # def pongReceived(self, el):
349 # self.pingCounter = 0
351 # def pongFailed(self, el):
354 # def makePingPacket(self):
355 # iq = Element((None, "iq"))
356 # iq.attributes["from"] = config.jid
357 # iq.attributes["to"] = config.mainServerJID
358 # iq.attributes["type"] = "get"
359 # query = iq.addElement("query")
360 # query.attributes["xmlns"] = disco.IQVERSION
363 class GatewayTranslator
:
364 def __init__(self
, pytrans
):
365 self
.pytrans
= pytrans
366 self
.pytrans
.discovery
.addFeature(disco
.IQGATEWAY
, self
.incomingIq
, config
.jid
)
368 def incomingIq(self
, el
):
369 fro
= el
.getAttribute("from")
370 ID
= el
.getAttribute("id")
371 itype
= el
.getAttribute("type")
373 self
.sendPrompt(fro
, ID
, utils
.getLang(el
))
374 elif(itype
== "set"):
375 self
.sendTranslation(fro
, ID
, el
)
378 def sendPrompt(self
, to
, ID
, ulang
):
381 iq
= Element((None, "iq"))
383 iq
.attributes
["type"] = "result"
384 iq
.attributes
["from"] = config
.jid
385 iq
.attributes
["to"] = to
387 iq
.attributes
["id"] = ID
388 query
= iq
.addElement("query")
389 query
.attributes
["xmlns"] = disco
.IQGATEWAY
390 desc
= query
.addElement("desc")
391 desc
.addContent(lang
.get(ulang
).gatewayTranslator
)
392 prompt
= query
.addElement("prompt")
394 self
.pytrans
.send(iq
)
396 def sendTranslation(self
, to
, ID
, el
):
399 # Find the user's legacy account
401 for query
in el
.elements():
402 if(query
.name
== "query"):
403 for child
in query
.elements():
404 if(child
.name
== "prompt"):
405 legacyaccount
= str(child
)
410 if(legacyaccount
and len(legacyaccount
) > 0):
411 LogEvent(INFO
, "", "Sending translated account.")
412 iq
= Element((None, "iq"))
413 iq
.attributes
["type"] = "result"
414 iq
.attributes
["from"] = config
.jid
415 iq
.attributes
["to"] = to
417 iq
.attributes
["id"] = ID
418 query
= iq
.addElement("query")
419 query
.attributes
["xmlns"] = disco
.IQGATEWAY
420 prompt
= query
.addElement("prompt")
421 prompt
.addContent(legacy
.translateAccount(legacyaccount
))
423 self
.pytrans
.send(iq
)
426 self
.pytrans
.discovery
.sendIqError(to
, ID
, disco
.IQGATEWAY
)
427 self
.pytrans
.discovery
.sendIqError(to
=to
, fro
=config
.jid
, ID
=ID
, xmlns
=disco
.IQGATEWAY
, etype
="retry", condition
="bad-request")
432 def __init__(self
, pytrans
):
433 self
.pytrans
= pytrans
434 self
.pytrans
.discovery
.addFeature(disco
.IQVERSION
, self
.incomingIq
, config
.jid
)
435 self
.pytrans
.discovery
.addFeature(disco
.IQVERSION
, self
.incomingIq
, "USER")
437 def incomingIq(self
, el
):
438 eltype
= el
.getAttribute("type")
439 if(eltype
!= "get"): return # Only answer "get" stanzas
443 def sendVersion(self
, el
):
445 iq
= Element((None, "iq"))
446 iq
.attributes
["type"] = "result"
447 iq
.attributes
["from"] = el
.getAttribute("to")
448 iq
.attributes
["to"] = el
.getAttribute("from")
449 if(el
.getAttribute("id")):
450 iq
.attributes
["id"] = el
.getAttribute("id")
451 query
= iq
.addElement("query")
452 query
.attributes
["xmlns"] = disco
.IQVERSION
453 name
= query
.addElement("name")
454 name
.addContent(legacy
.name
)
455 version
= query
.addElement("version")
456 version
.addContent(legacy
.version
)
457 os
= query
.addElement("os")
458 os
.addContent("Python" + ".".join([str(x
) for x
in sys
.version_info
[0:3]]) + " - " + sys
.platform
)
460 self
.pytrans
.send(iq
)