| 1 |
|
|---|
| 2 |
""" |
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 25 |
|
|---|
| 26 |
|
|---|
| 27 |
|
|---|
| 28 |
|
|---|
| 29 |
from Axon.Component import component |
|---|
| 30 |
from Kamaelia.Chassis.Graphline import Graphline |
|---|
| 31 |
from Kamaelia.Chassis.Pipeline import Pipeline |
|---|
| 32 |
from Kamaelia.Util.Backplane import Backplane |
|---|
| 33 |
from Kamaelia.Util.Backplane import PublishTo, SubscribeTo |
|---|
| 34 |
from Kamaelia.Internet.TCPClient import TCPClient |
|---|
| 35 |
from Kamaelia.Util.Console import ConsoleReader |
|---|
| 36 |
from Axon.Ipc import shutdownMicroprocess, producerFinished |
|---|
| 37 |
|
|---|
| 38 |
from headstock.protocol.core.stream import ClientStream, StreamError, SaslError |
|---|
| 39 |
from headstock.protocol.core.presence import PresenceDispatcher |
|---|
| 40 |
from headstock.protocol.core.roster import RosterDispatcher, RosterNull |
|---|
| 41 |
from headstock.protocol.core.message import MessageDispatcher, MessageEchoer |
|---|
| 42 |
from headstock.protocol.extension.register import RegisterDispatcher |
|---|
| 43 |
from headstock.protocol.extension.activity import ActivityDispatcher |
|---|
| 44 |
from headstock.protocol.extension.discovery import DiscoveryDispatcher |
|---|
| 45 |
from headstock.protocol.extension.discovery import FeaturesDiscovery |
|---|
| 46 |
from headstock.api.jid import JID |
|---|
| 47 |
from headstock.api.im import Message, Body, Event |
|---|
| 48 |
from headstock.api.contact import Presence, Roster, Item |
|---|
| 49 |
from headstock.api import Entity |
|---|
| 50 |
from headstock.api.activity import Activity |
|---|
| 51 |
from headstock.api.registration import Registration |
|---|
| 52 |
from headstock.lib.parser import XMLIncrParser |
|---|
| 53 |
from headstock.lib.logger import Logger |
|---|
| 54 |
from headstock.lib.utils import generate_unique |
|---|
| 55 |
|
|---|
| 56 |
from bridge import Element as E |
|---|
| 57 |
from bridge.common import XMPP_CLIENT_NS, XMPP_ROSTER_NS, \ |
|---|
| 58 |
XMPP_LAST_NS, XMPP_DISCO_INFO_NS, XMPP_IBR_NS |
|---|
| 59 |
|
|---|
| 60 |
__all__ = ['Client'] |
|---|
| 61 |
|
|---|
| 62 |
class RosterHandler(component): |
|---|
| 63 |
Inboxes = {"inbox" : "headstock.api.contact.Roster instance", |
|---|
| 64 |
"control" : "stops the component", |
|---|
| 65 |
"pushed" : "roster stanzas pushed by the server", |
|---|
| 66 |
"jid" : "headstock.api.jid.JID instance received from the server", |
|---|
| 67 |
"ask-activity" : "request activity status to the server for each roster contact"} |
|---|
| 68 |
|
|---|
| 69 |
Outboxes = {"outbox" : "UNUSED", |
|---|
| 70 |
"signal" : "Shutdown signal", |
|---|
| 71 |
"message" : "Message to send", |
|---|
| 72 |
"result" : "", |
|---|
| 73 |
"activity" : "headstock.api.activity.Activity instance to send to the server"} |
|---|
| 74 |
|
|---|
| 75 |
def __init__(self, from_jid): |
|---|
| 76 |
super(RosterHandler, self).__init__() |
|---|
| 77 |
self.from_jid = from_jid |
|---|
| 78 |
self.roster = None |
|---|
| 79 |
|
|---|
| 80 |
def initComponents(self): |
|---|
| 81 |
|
|---|
| 82 |
|
|---|
| 83 |
|
|---|
| 84 |
sub = SubscribeTo("JID") |
|---|
| 85 |
self.link((sub, 'outbox'), (self, 'jid')) |
|---|
| 86 |
self.addChildren(sub) |
|---|
| 87 |
sub.activate() |
|---|
| 88 |
|
|---|
| 89 |
return 1 |
|---|
| 90 |
|
|---|
| 91 |
def main(self): |
|---|
| 92 |
yield self.initComponents() |
|---|
| 93 |
|
|---|
| 94 |
while 1: |
|---|
| 95 |
if self.dataReady("control"): |
|---|
| 96 |
mes = self.recv("control") |
|---|
| 97 |
|
|---|
| 98 |
if isinstance(mes, shutdownMicroprocess) or isinstance(mes, producerFinished): |
|---|
| 99 |
self.send(producerFinished(), "signal") |
|---|
| 100 |
break |
|---|
| 101 |
|
|---|
| 102 |
if self.dataReady("jid"): |
|---|
| 103 |
self.from_jid = self.recv('jid') |
|---|
| 104 |
|
|---|
| 105 |
if self.dataReady("pushed"): |
|---|
| 106 |
roster = self.recv('pushed') |
|---|
| 107 |
for nodeid in roster.items: |
|---|
| 108 |
self.send(Roster(from_jid=self.from_jid, to_jid=nodeid, |
|---|
| 109 |
type=u'result', stanza_id=generate_unique()), 'result') |
|---|
| 110 |
|
|---|
| 111 |
if self.dataReady("inbox"): |
|---|
| 112 |
roster = self.recv("inbox") |
|---|
| 113 |
self.roster = roster |
|---|
| 114 |
print "Your contacts:" |
|---|
| 115 |
for nodeid in roster.items: |
|---|
| 116 |
contact = roster.items[nodeid] |
|---|
| 117 |
print " ", contact.jid |
|---|
| 118 |
|
|---|
| 119 |
if self.dataReady('ask-activity'): |
|---|
| 120 |
self.recv('ask-activity') |
|---|
| 121 |
if self.roster: |
|---|
| 122 |
for nodeid in self.roster.items: |
|---|
| 123 |
contact = roster.items[nodeid] |
|---|
| 124 |
a = Activity(unicode(self.from_jid), unicode(contact.jid)) |
|---|
| 125 |
self.send(a, 'activity') |
|---|
| 126 |
|
|---|
| 127 |
if not self.anyReady(): |
|---|
| 128 |
self.pause() |
|---|
| 129 |
|
|---|
| 130 |
yield 1 |
|---|
| 131 |
|
|---|
| 132 |
class DummyMessageHandler(component): |
|---|
| 133 |
Inboxes = {"inbox" : "headstock.api.contact.Message instance received from a peer"\ |
|---|
| 134 |
"or the string input in the console", |
|---|
| 135 |
"jid" : "headstock.api.jid.JID instance received from the server", |
|---|
| 136 |
"control" : "stops the component"} |
|---|
| 137 |
|
|---|
| 138 |
Outboxes = {"outbox" : "headstock.api.im.Message to send to the client", |
|---|
| 139 |
"signal" : "Shutdown signal"} |
|---|
| 140 |
|
|---|
| 141 |
def __init__(self): |
|---|
| 142 |
super(DummyMessageHandler, self).__init__() |
|---|
| 143 |
self.from_jid = None |
|---|
| 144 |
|
|---|
| 145 |
def initComponents(self): |
|---|
| 146 |
sub = SubscribeTo("JID") |
|---|
| 147 |
self.link((sub, 'outbox'), (self, 'jid')) |
|---|
| 148 |
self.addChildren(sub) |
|---|
| 149 |
sub.activate() |
|---|
| 150 |
|
|---|
| 151 |
sub = SubscribeTo("CONSOLE") |
|---|
| 152 |
self.link((sub, 'outbox'), (self, 'inbox')) |
|---|
| 153 |
self.addChildren(sub) |
|---|
| 154 |
sub.activate() |
|---|
| 155 |
|
|---|
| 156 |
return 1 |
|---|
| 157 |
|
|---|
| 158 |
def main(self): |
|---|
| 159 |
yield self.initComponents() |
|---|
| 160 |
|
|---|
| 161 |
while 1: |
|---|
| 162 |
if self.dataReady("control"): |
|---|
| 163 |
mes = self.recv("control") |
|---|
| 164 |
if isinstance(mes, shutdownMicroprocess) or isinstance(mes, producerFinished): |
|---|
| 165 |
self.send(producerFinished(), "signal") |
|---|
| 166 |
break |
|---|
| 167 |
|
|---|
| 168 |
if self.dataReady("jid"): |
|---|
| 169 |
self.from_jid = self.recv('jid') |
|---|
| 170 |
|
|---|
| 171 |
if self.dataReady("inbox"): |
|---|
| 172 |
m = self.recv("inbox") |
|---|
| 173 |
|
|---|
| 174 |
|
|---|
| 175 |
|
|---|
| 176 |
|
|---|
| 177 |
if isinstance(m, str) and m != '': |
|---|
| 178 |
try: |
|---|
| 179 |
contact_jid, message = m.split(' ', 1) |
|---|
| 180 |
except ValueError: |
|---|
| 181 |
print "Messages format: contact_jid message" |
|---|
| 182 |
continue |
|---|
| 183 |
m = Message(unicode(self.from_jid), unicode(contact_jid), |
|---|
| 184 |
type=u'chat', stanza_id=generate_unique()) |
|---|
| 185 |
m.event = Event.composing |
|---|
| 186 |
m.bodies.append(Body(unicode(message))) |
|---|
| 187 |
self.send(m, "outbox") |
|---|
| 188 |
|
|---|
| 189 |
|
|---|
| 190 |
|
|---|
| 191 |
m = Message(unicode(self.from_jid), unicode(contact_jid), |
|---|
| 192 |
type=u'chat', stanza_id=generate_unique()) |
|---|
| 193 |
self.send(m, "outbox") |
|---|
| 194 |
|
|---|
| 195 |
|
|---|
| 196 |
elif isinstance(m, Message): |
|---|
| 197 |
for body in m.bodies: |
|---|
| 198 |
print m.from_jid, ": ", str(body) |
|---|
| 199 |
|
|---|
| 200 |
if not self.anyReady(): |
|---|
| 201 |
self.pause() |
|---|
| 202 |
|
|---|
| 203 |
yield 1 |
|---|
| 204 |
|
|---|
| 205 |
class DiscoHandler(component): |
|---|
| 206 |
Inboxes = {"inbox" : "UNUSED", |
|---|
| 207 |
"control" : "stops the component", |
|---|
| 208 |
"initiate" : "event informing the component the client session is active", |
|---|
| 209 |
"jid" : "headstock.api.jid.JID instance received from the server", |
|---|
| 210 |
"features.result": "headstock.api.discovery.FeaturesDiscovery instance from the server",} |
|---|
| 211 |
|
|---|
| 212 |
Outboxes = {"outbox" : "UNUSED", |
|---|
| 213 |
"signal" : "Shutdown signal", |
|---|
| 214 |
"features-disco" : "headstock.api.discovery.FeaturesDiscovery query to the server", |
|---|
| 215 |
"features-announce": "headstock.api.discovery.FeaturesDiscovery informs"\ |
|---|
| 216 |
"the other components about the features instance received from the server"} |
|---|
| 217 |
|
|---|
| 218 |
def __init__(self, from_jid, to_jid): |
|---|
| 219 |
super(DiscoHandler, self).__init__() |
|---|
| 220 |
self.from_jid = from_jid |
|---|
| 221 |
self.to_jid = to_jid |
|---|
| 222 |
|
|---|
| 223 |
def initComponents(self): |
|---|
| 224 |
sub = SubscribeTo("JID") |
|---|
| 225 |
self.link((sub, 'outbox'), (self, 'jid')) |
|---|
| 226 |
self.addChildren(sub) |
|---|
| 227 |
sub.activate() |
|---|
| 228 |
|
|---|
| 229 |
pub = PublishTo("DISCO_FEAT") |
|---|
| 230 |
self.link((self, 'features-announce'), (pub, 'inbox')) |
|---|
| 231 |
self.addChildren(pub) |
|---|
| 232 |
pub.activate() |
|---|
| 233 |
|
|---|
| 234 |
sub = SubscribeTo("BOUND") |
|---|
| 235 |
self.link((sub, 'outbox'), (self, 'initiate')) |
|---|
| 236 |
self.addChildren(sub) |
|---|
| 237 |
sub.activate() |
|---|
| 238 |
|
|---|
| 239 |
return 1 |
|---|
| 240 |
|
|---|
| 241 |
def main(self): |
|---|
| 242 |
yield self.initComponents() |
|---|
| 243 |
|
|---|
| 244 |
while 1: |
|---|
| 245 |
if self.dataReady("control"): |
|---|
| 246 |
mes = self.recv("control") |
|---|
| 247 |
|
|---|
| 248 |
if isinstance(mes, shutdownMicroprocess) or isinstance(mes, producerFinished): |
|---|
| 249 |
self.send(producerFinished(), "signal") |
|---|
| 250 |
break |
|---|
| 251 |
|
|---|
| 252 |
if self.dataReady("jid"): |
|---|
| 253 |
self.from_jid = self.recv('jid') |
|---|
| 254 |
|
|---|
| 255 |
|
|---|
| 256 |
|
|---|
| 257 |
|
|---|
| 258 |
if self.dataReady("initiate"): |
|---|
| 259 |
self.recv("initiate") |
|---|
| 260 |
d = FeaturesDiscovery(unicode(self.from_jid), self.to_jid) |
|---|
| 261 |
self.send(d, "features-disco") |
|---|
| 262 |
|
|---|
| 263 |
|
|---|
| 264 |
|
|---|
| 265 |
|
|---|
| 266 |
|
|---|
| 267 |
if self.dataReady('features.result'): |
|---|
| 268 |
disco = self.recv('features.result') |
|---|
| 269 |
print "Supported features:" |
|---|
| 270 |
for feature in disco.features: |
|---|
| 271 |
print " ", feature.var |
|---|
| 272 |
self.send(disco, 'features-announce') |
|---|
| 273 |
|
|---|
| 274 |
if not self.anyReady(): |
|---|
| 275 |
self.pause() |
|---|
| 276 |
|
|---|
| 277 |
yield 1 |
|---|
| 278 |
|
|---|
| 279 |
class ActivityHandler(component): |
|---|
| 280 |
Inboxes = {"inbox" : "headstock.api.discovery.FeaturesDiscovery instance", |
|---|
| 281 |
"control" : "stops the component", |
|---|
| 282 |
} |
|---|
| 283 |
|
|---|
| 284 |
Outboxes = {"outbox" : "UNUSED", |
|---|
| 285 |
"signal" : "Shutdown signal", |
|---|
| 286 |
"activity-supported": "when used this tells the RosterHandler it needs"\ |
|---|
| 287 |
"to request the server for each contact's activity."\ |
|---|
| 288 |
"This is only used when the server supports the feature", |
|---|
| 289 |
} |
|---|
| 290 |
|
|---|
| 291 |
def __init__(self): |
|---|
| 292 |
super(ActivityHandler, self).__init__() |
|---|
| 293 |
|
|---|
| 294 |
def initComponents(self): |
|---|
| 295 |
sub = SubscribeTo("DISCO_FEAT") |
|---|
| 296 |
self.link((sub, 'outbox'), (self, 'inbox')) |
|---|
| 297 |
self.addChildren(sub) |
|---|
| 298 |
sub.activate() |
|---|
| 299 |
|
|---|
| 300 |
return 1 |
|---|
| 301 |
|
|---|
| 302 |
def main(self): |
|---|
| 303 |
yield self.initComponents() |
|---|
| 304 |
|
|---|
| 305 |
while 1: |
|---|
| 306 |
if self.dataReady("control"): |
|---|
| 307 |
mes = self.recv("control") |
|---|
| 308 |
if isinstance(mes, shutdownMicroprocess) or isinstance(mes, producerFinished): |
|---|
| 309 |
self.send(producerFinished(), "signal") |
|---|
| 310 |
break |
|---|
| 311 |
|
|---|
| 312 |
if self.dataReady("inbox"): |
|---|
| 313 |
disco = self.recv("inbox") |
|---|
| 314 |
support = disco.has_feature(XMPP_LAST_NS) |
|---|
| 315 |
print "Activity support: ", support |
|---|
| 316 |
if support: |
|---|
| 317 |
self.send('', "activity-supported") |
|---|
| 318 |
|
|---|
| 319 |
if not self.anyReady(): |
|---|
| 320 |
self.pause() |
|---|
| 321 |
|
|---|
| 322 |
yield 1 |
|---|
| 323 |
|
|---|
| 324 |
class PresenceHandler(component): |
|---|
| 325 |
Inboxes = {"inbox" : "headstock.api.contact.Presence instance", |
|---|
| 326 |
"control" : "Shutdown the client stream", |
|---|
| 327 |
"subscribe" : "", |
|---|
| 328 |
"unsubscribe" : "",} |
|---|
| 329 |
|
|---|
| 330 |
Outboxes = {"outbox" : "headstock.api.contact.Presence instance to return to the server", |
|---|
| 331 |
"signal" : "Shutdown signal", |
|---|
| 332 |
"roster" : "", |
|---|
| 333 |
"log" : "log",} |
|---|
| 334 |
|
|---|
| 335 |
def __init__(self): |
|---|
| 336 |
super(PresenceHandler, self).__init__() |
|---|
| 337 |
|
|---|
| 338 |
def main(self): |
|---|
| 339 |
while 1: |
|---|
| 340 |
if self.dataReady("control"): |
|---|
| 341 |
mes = self.recv("control") |
|---|
| 342 |
|
|---|
| 343 |
if isinstance(mes, shutdownMicroprocess) or isinstance(mes, producerFinished): |
|---|
| 344 |
self.send(producerFinished(), "signal") |
|---|
| 345 |
break |
|---|
| 346 |
|
|---|
| 347 |
if self.dataReady("subscribe"): |
|---|
| 348 |
p = self.recv("subscribe") |
|---|
| 349 |
p.swap_jids() |
|---|
| 350 |
|
|---|
| 351 |
|
|---|
| 352 |
p = Presence(from_jid=p.from_jid, to_jid=unicode(p.to_jid), |
|---|
| 353 |
type=u'subscribed') |
|---|
| 354 |
self.send(p, "outbox") |
|---|
| 355 |
|
|---|
| 356 |
|
|---|
| 357 |
p = Presence(from_jid=p.from_jid, to_jid=unicode(p.to_jid), |
|---|
| 358 |
type=u'subscribe') |
|---|
| 359 |
self.send(p, "outbox") |
|---|
| 360 |
|
|---|
| 361 |
if self.dataReady("unsubscribe"): |
|---|
| 362 |
p = self.recv("unsubscribe") |
|---|
| 363 |
p.swap_jids() |
|---|
| 364 |
|
|---|
| 365 |
|
|---|
| 366 |
p = Presence(from_jid=p.from_jid, to_jid=unicode(p.to_jid), |
|---|
| 367 |
type=u'unsubscribed') |
|---|
| 368 |
self.send(p, "outbox") |
|---|
| 369 |
|
|---|
| 370 |
|
|---|
| 371 |
p = Presence(from_jid=p.from_jid, to_jid=unicode(p.to_jid), |
|---|
| 372 |
type=u'unsubscribe') |
|---|
| 373 |
self.send(p, "outbox") |
|---|
| 374 |
|
|---|
| 375 |
|
|---|
| 376 |
r = Roster(from_jid=p.from_jid, type=u'set') |
|---|
| 377 |
i = Item(p.to_jid) |
|---|
| 378 |
i.subscription = u'remove' |
|---|
| 379 |
r.items[unicode(p.to_jid)] = i |
|---|
| 380 |
self.send(r, 'roster') |
|---|
| 381 |
|
|---|
| 382 |
|
|---|
| 383 |
p = Presence(from_jid=p.from_jid, to_jid=unicode(p.to_jid), |
|---|
| 384 |
type=u'unavailable') |
|---|
| 385 |
self.send(p, "outbox") |
|---|
| 386 |
|
|---|
| 387 |
if not self.anyReady(): |
|---|
| 388 |
self.pause() |
|---|
| 389 |
|
|---|
| 390 |
yield 1 |
|---|
| 391 |
|
|---|
| 392 |
|
|---|
| 393 |
class RegistrationHandler(component): |
|---|
| 394 |
Inboxes = {"inbox" : "headstock.api.registration.Registration", |
|---|
| 395 |
"error" : "headstock.api.registration.Registration", |
|---|
| 396 |
"control" : "Shutdown the client stream",} |
|---|
| 397 |
|
|---|
| 398 |
Outboxes = {"outbox" : "headstock.api.registration.Registration", |
|---|
| 399 |
"signal" : "Shutdown signal", |
|---|
| 400 |
"log" : "log",} |
|---|
| 401 |
|
|---|
| 402 |
def __init__(self, username, password): |
|---|
| 403 |
super(RegistrationHandler, self).__init__() |
|---|
| 404 |
self.username = username |
|---|
| 405 |
self.password = password |
|---|
| 406 |
self.registration_id = None |
|---|
| 407 |
|
|---|
| 408 |
def main(self): |
|---|
| 409 |
while 1: |
|---|
| 410 |
if self.dataReady("control"): |
|---|
| 411 |
mes = self.recv("control") |
|---|
| 412 |
|
|---|
| 413 |
if isinstance(mes, shutdownMicroprocess) or isinstance(mes, producerFinished): |
|---|
| 414 |
self.send(producerFinished(), "signal") |
|---|
| 415 |
break |
|---|
| 416 |
|
|---|
| 417 |
if self.dataReady("inbox"): |
|---|
| 418 |
r = self.recv('inbox') |
|---|
| 419 |
if r.registered: |
|---|
| 420 |
print "'%s' is already a registered username." % self.username |
|---|
| 421 |
elif self.registration_id == r.stanza_id: |
|---|
| 422 |
print "'%s' is now a registered user."\ |
|---|
| 423 |
"Please restart the client without the register flag." % self.username |
|---|
| 424 |
else: |
|---|
| 425 |
if 'username' in r.infos and 'password' in r.infos: |
|---|
| 426 |
self.registration_id = generate_unique() |
|---|
| 427 |
r = Registration(type=u'set', stanza_id=self.registration_id) |
|---|
| 428 |
r.infos[u'username'] = self.username |
|---|
| 429 |
r.infos[u'password'] = self.password |
|---|
| 430 |
self.send(r, 'outbox') |
|---|
| 431 |
|
|---|
| 432 |
if self.dataReady("error"): |
|---|
| 433 |
r = self.recv('error') |
|---|
| 434 |
print r.error |
|---|
| 435 |
|
|---|
| 436 |
if not self.anyReady(): |
|---|
| 437 |
self.pause() |
|---|
| 438 |
|
|---|
| 439 |
yield 1 |
|---|
| 440 |
|
|---|
| 441 |
class Client(component): |
|---|
| 442 |
Inboxes = {"inbox" : "", |
|---|
| 443 |
"jid" : "", |
|---|
| 444 |
"streamfeat" : "", |
|---|
| 445 |
"control" : "Shutdown the client stream"} |
|---|
| 446 |
|
|---|
| 447 |
Outboxes = {"outbox" : "", |
|---|
| 448 |
"forward" : "", |
|---|
| 449 |
"log" : "", |
|---|
| 450 |
"doauth" : "", |
|---|
| 451 |
"signal" : "Shutdown signal", |
|---|
| 452 |
"doregistration" : ""} |
|---|
| 453 |
|
|---|
| 454 |
def __init__(self, username, password, domain, resource=u"headstock-client1", |
|---|
| 455 |
server=u'localhost', port=5222, usetls=False, register=False): |
|---|
| 456 |
super(Client, self).__init__() |
|---|
| 457 |
self.jid = JID(username, domain, resource) |
|---|
| 458 |
self.username = username |
|---|
| 459 |
self.password = password |
|---|
| 460 |
self.server = server |
|---|
| 461 |
self.port = port |
|---|
| 462 |
self.client = None |
|---|
| 463 |
self.graph = None |
|---|
| 464 |
self.domain = domain |
|---|
| 465 |
self.usetls = usetls |
|---|
| 466 |
self.register = register |
|---|
| 467 |
|
|---|
| 468 |
def passwordLookup(self, jid): |
|---|
| 469 |
return self.password |
|---|
| 470 |
|
|---|
| 471 |
def shutdown(self): |
|---|
| 472 |
self.send(Presence.to_element(Presence(self.jid, type=u'unavailable')), 'forward') |
|---|
| 473 |
self.send('OUTGOING : </stream:stream>', 'log') |
|---|
| 474 |
self.send('</stream:stream>', 'outbox') |
|---|
| 475 |
|
|---|
| 476 |
def abort(self): |
|---|
| 477 |
self.send('OUTGOING : </stream:stream>', 'log') |
|---|
| 478 |
self.send('</stream:stream>', 'outbox') |
|---|
| 479 |
|
|---|
| 480 |
def setup(self): |
|---|
| 481 |
|
|---|
| 482 |
|
|---|
| 483 |
|
|---|
| 484 |
|
|---|
| 485 |
|
|---|
| 486 |
|
|---|
| 487 |
|
|---|
| 488 |
|
|---|
| 489 |
|
|---|
| 490 |
|
|---|
| 491 |
|
|---|
| 492 |
|
|---|
| 493 |
|
|---|
| 494 |
|
|---|
| 495 |
|
|---|
| 496 |
Backplane("CONSOLE").activate() |
|---|
| 497 |
Backplane("JID").activate() |
|---|
| 498 |
|
|---|
| 499 |
Backplane("BOUND").activate() |
|---|
| 500 |
|
|---|
| 501 |
Backplane("DISCO_FEAT").activate() |
|---|
| 502 |
|
|---|
| 503 |
sub = SubscribeTo("JID") |
|---|
| 504 |
self.link((sub, 'outbox'), (self, 'jid')) |
|---|
| 505 |
self.addChildren(sub) |
|---|
| 506 |
sub.activate() |
|---|
| 507 |
|
|---|
| 508 |
|
|---|
| 509 |
|
|---|
| 510 |
|
|---|
| 511 |
|
|---|
| 512 |
|
|---|
| 513 |
Pipeline(ConsoleReader(), PublishTo('CONSOLE')).activate() |
|---|
| 514 |
|
|---|
| 515 |
|
|---|
| 516 |
ClientStream.Outboxes["%s.query" % XMPP_IBR_NS] = "Registration" |
|---|
| 517 |
ClientStream.Outboxes["%s.query" % XMPP_LAST_NS] = "Activity" |
|---|
| 518 |
ClientStream.Outboxes["%s.query" % XMPP_DISCO_INFO_NS] = "Discovery" |
|---|
| 519 |
|
|---|
| 520 |
self.client = ClientStream(self.jid, self.passwordLookup, use_tls=self.usetls) |
|---|
| 521 |
|
|---|
| 522 |
self.graph = Graphline(client = self, |
|---|
| 523 |
console = SubscribeTo('CONSOLE'), |
|---|
| 524 |
logger = Logger(path=None, stdout=True), |
|---|
| 525 |
tcp = TCPClient(self.server, self.port), |
|---|
| 526 |
xmlparser = XMLIncrParser(), |
|---|
| 527 |
xmpp = self.client, |
|---|
| 528 |
streamerr = StreamError(), |
|---|
| 529 |
saslerr = SaslError(), |
|---|
| 530 |
discohandler = DiscoHandler(self.jid, self.domain), |
|---|
| 531 |
activityhandler = ActivityHandler(), |
|---|
| 532 |
rosterhandler = RosterHandler(self.jid), |
|---|
| 533 |
registerhandler = RegistrationHandler(self.username, self.password), |
|---|
| 534 |
msgdummyhandler = DummyMessageHandler(), |
|---|
| 535 |
presencehandler = PresenceHandler(), |
|---|
| 536 |
presencedisp = PresenceDispatcher(), |
|---|
| 537 |
rosterdisp = RosterDispatcher(), |
|---|
| 538 |
msgdisp = MessageDispatcher(), |
|---|
| 539 |
discodisp = DiscoveryDispatcher(), |
|---|
| 540 |
activitydisp = ActivityDispatcher(), |
|---|
| 541 |
registerdisp = RegisterDispatcher(), |
|---|
| 542 |
pjid = PublishTo("JID"), |
|---|
| 543 |
pbound = PublishTo("BOUND"), |
|---|
| 544 |
|
|---|
| 545 |
linkages = {('xmpp', 'terminated'): ('client', 'inbox'), |
|---|
| 546 |
('console', 'outbox'): ('client', 'control'), |
|---|
| 547 |
('client', 'forward'): ('xmpp', 'forward'), |
|---|
| 548 |
('client', 'outbox'): ('tcp', 'inbox'), |
|---|
| 549 |
('client', 'signal'): ('tcp', 'control'), |
|---|
| 550 |
("tcp", "outbox") : ("xmlparser", "inbox"), |
|---|
| 551 |
("xmpp", "starttls") : ("tcp", "makessl"), |
|---|
| 552 |
("tcp", "sslready") : ("xmpp", "tlssuccess"), |
|---|
| 553 |
("xmlparser", "outbox") : ("xmpp" , "inbox"), |
|---|
| 554 |
("xmpp", "outbox") : ("tcp" , "inbox"), |
|---|
| 555 |
("xmpp", "reset"): ("xmlparser", "reset"), |
|---|
| 556 |
("client", "log"): ("logger", "inbox"), |
|---|
| 557 |
("xmpp", "log"): ("logger", "inbox"), |
|---|
| 558 |
("xmpp", "jid"): ("pjid", "inbox"), |
|---|
| 559 |
("xmpp", "bound"): ("pbound", "inbox"), |
|---|
| 560 |
("xmpp", "features"): ("client", "streamfeat"), |
|---|
| 561 |
("client", "doauth"): ("xmpp", "auth"), |
|---|
| 562 |
|
|---|
| 563 |
|
|---|
| 564 |
("xmpp", "%s.query" % XMPP_IBR_NS): ("registerdisp", "inbox"), |
|---|
| 565 |
("registerdisp", "log"): ('logger', "inbox"), |
|---|
| 566 |
("registerdisp", "xmpp.error"): ("registerhandler", "error"), |
|---|
| 567 |
("registerdisp", "xmpp.result"): ("registerhandler", "inbox"), |
|---|
| 568 |
("registerhandler", "outbox"): ("registerdisp", "forward"), |
|---|
| 569 |
("client", "doregistration"): ("registerdisp", "forward"), |
|---|
| 570 |
("registerdisp", "outbox"): ("xmpp", "forward"), |
|---|
| 571 |
|
|---|
| 572 |
|
|---|
| 573 |
("xmpp", "%s.presence" % XMPP_CLIENT_NS): ("presencedisp", "inbox"), |
|---|
| 574 |
("presencedisp", "log"): ('logger', "inbox"), |
|---|
| 575 |
("presencedisp", "xmpp.subscribe"): ("presencehandler", "subscribe"), |
|---|
| 576 |
("presencedisp", "xmpp.unsubscribe"): ("presencehandler", "unsubscribe"), |
|---|
| 577 |
("presencehandler", "outbox"): ("presencedisp", "forward"), |
|---|
| 578 |
("presencehandler", "roster"): ("rosterdisp", "forward"), |
|---|
| 579 |
("presencedisp", "outbox"): ("xmpp", "forward"), |
|---|
| 580 |
|
|---|
| 581 |
|
|---|
| 582 |
("xmpp", "%s.query" % XMPP_ROSTER_NS): ("rosterdisp", "inbox"), |
|---|
| 583 |
("rosterdisp", "log"): ('logger', "inbox"), |
|---|
| 584 |
('rosterdisp', 'xmpp.set'): ('rosterhandler', 'pushed'), |
|---|
| 585 |
('rosterdisp', 'xmpp.result'): ('rosterhandler', 'inbox'), |
|---|
| 586 |
('rosterhandler', 'result'): ('rosterdisp', 'forward'), |
|---|
| 587 |
("rosterdisp", "outbox"): ("xmpp", "forward"), |
|---|
| 588 |
|
|---|
| 589 |
|
|---|
| 590 |
("xmpp", "%s.query" % XMPP_DISCO_INFO_NS): ("discodisp", "features.inbox"), |
|---|
| 591 |
("discodisp", "log"): ('logger', "inbox"), |
|---|
| 592 |
("discohandler", "features-disco"): ('discodisp', "features.forward"), |
|---|
| 593 |
("discodisp", "out.features.result"): ('discohandler', "features.result"), |
|---|
| 594 |
("discodisp", "outbox"): ("xmpp", "forward"), |
|---|
| 595 |
|
|---|
| 596 |
|
|---|
| 597 |
("xmpp", "%s.message" % XMPP_CLIENT_NS): ("msgdisp", "inbox"), |
|---|
| 598 |
("msgdisp", "log"): ('logger', "inbox"), |
|---|
| 599 |
("msgdisp", "xmpp.chat"): ('msgdummyhandler', 'inbox'), |
|---|
| 600 |
("msgdummyhandler", "outbox"): ('msgdisp', 'forward'), |
|---|
| 601 |
("msgdisp", "outbox"): ("xmpp", "forward"), |
|---|
| 602 |
|
|---|
| 603 |
|
|---|
| 604 |
("xmpp", "%s.query" % XMPP_LAST_NS): ("activitydisp", "inbox"), |
|---|
| 605 |
("activitydisp", "log"): ('logger', "inbox"), |
|---|
| 606 |
("activitydisp", "outbox"): ("xmpp", "forward"), |
|---|
| 607 |
("activityhandler", 'activity-supported'): ('rosterhandler', 'ask-activity'), |
|---|
| 608 |
("rosterhandler", 'activity'): ('activitydisp', 'forward'), |
|---|
| 609 |
} |
|---|
| 610 |
) |
|---|
| 611 |
self.addChildren(self.graph) |
|---|
| 612 |
self.graph.activate() |
|---|
| 613 |
|
|---|
| 614 |
return 1 |
|---|
| 615 |
|
|---|
| 616 |
def main(self): |
|---|
| 617 |
yield self.setup() |
|---|
| 618 |
|
|---|
| 619 |
while 1: |
|---|
| 620 |
if self.dataReady("control"): |
|---|
| 621 |
mes = self.recv("control") |
|---|
| 622 |
|
|---|
| 623 |
if isinstance(mes, str): |
|---|
| 624 |
if mes.strip() == 'quit': |
|---|
| 625 |
self.shutdown() |
|---|
| 626 |
elif isinstance(mes, shutdownMicroprocess) or isinstance(mes, producerFinished): |
|---|
| 627 |
self.send(mes, "signal") |
|---|
| 628 |
break |
|---|
| 629 |
|
|---|
| 630 |
if self.dataReady("inbox"): |
|---|
| 631 |
msg = self.recv('inbox') |
|---|
| 632 |
if msg == "quit": |
|---|
| 633 |
self.send(shutdownMicroprocess(), "signal") |
|---|
| 634 |
yield 1 |
|---|
| 635 |
break |
|---|
| 636 |
|
|---|
| 637 |
if self.dataReady("streamfeat"): |
|---|
| 638 |
feat = self.recv('streamfeat') |
|---|
| 639 |
if feat.register and self.register: |
|---|
| 640 |
self.send(Registration(), 'doregistration') |
|---|
| 641 |
elif self.register and not feat.register: |
|---|
| 642 |
print "The server does not support in-band registration. Closing connection." |
|---|
| 64 |
|---|