Modified event handling to use the event queue.
[slixmpp.git] / sleekxmpp / componentxmpp.py
blob5534a457af6e64fac2b75f1f36f13495e98f9f4f
1 #!/usr/bin/env python
3 """
4 SleekXMPP: The Sleek XMPP Library
5 Copyright (C) 2010 Nathanael C. Fritz
6 This file is part of SleekXMPP.
8 See the file LICENSE for copying permission.
9 """
10 from __future__ import absolute_import
11 from . basexmpp import basexmpp
12 from xml.etree import cElementTree as ET
14 from . xmlstream.xmlstream import XMLStream
15 from . xmlstream.xmlstream import RestartStream
16 from . xmlstream.matcher.xmlmask import MatchXMLMask
17 from . xmlstream.matcher.xpath import MatchXPath
18 from . xmlstream.matcher.many import MatchMany
19 from . xmlstream.handler.callback import Callback
20 from . xmlstream.stanzabase import StanzaBase
21 from . xmlstream import xmlstream as xmlstreammod
22 import time
23 import logging
24 import base64
25 import sys
26 import random
27 import copy
28 from . import plugins
29 from . import stanza
30 import hashlib
31 srvsupport = True
32 try:
33 import dns.resolver
34 except ImportError:
35 srvsupport = False
38 class ComponentXMPP(basexmpp, XMLStream):
39 """SleekXMPP's client class. Use only for good, not evil."""
41 def __init__(self, jid, secret, host, port, plugin_config = {}, plugin_whitelist=[], use_jc_ns=False):
42 XMLStream.__init__(self)
43 if use_jc_ns:
44 self.default_ns = 'jabber:client'
45 else:
46 self.default_ns = 'jabber:component:accept'
47 basexmpp.__init__(self)
48 self.auto_authorize = None
49 self.stream_header = "<stream:stream xmlns='jabber:component:accept' xmlns:stream='http://etherx.jabber.org/streams' to='%s'>" % jid
50 self.stream_footer = "</stream:stream>"
51 self.server_host = host
52 self.server_port = port
53 self.set_jid(jid)
54 self.secret = secret
55 self.is_component = True
56 self.registerHandler(Callback('Handshake', MatchXPath('{jabber:component:accept}handshake'), self._handleHandshake))
58 def __getitem__(self, key):
59 if key in self.plugin:
60 return self.plugin[key]
61 else:
62 logging.warning("""Plugin "%s" is not loaded.""" % key)
63 return False
65 def get(self, key, default):
66 return self.plugin.get(key, default)
68 def incoming_filter(self, xmlobj):
69 if xmlobj.tag.startswith('{jabber:client}'):
70 xmlobj.tag = xmlobj.tag.replace('jabber:client', self.default_ns)
71 for sub in xmlobj:
72 self.incoming_filter(sub)
73 return xmlobj
75 def start_stream_handler(self, xml):
76 sid = xml.get('id', '')
77 handshake = ET.Element('{jabber:component:accept}handshake')
78 if sys.version_info < (3,0):
79 handshake.text = hashlib.sha1("%s%s" % (sid, self.secret)).hexdigest().lower()
80 else:
81 handshake.text = hashlib.sha1(bytes("%s%s" % (sid, self.secret), 'utf-8')).hexdigest().lower()
82 self.sendXML(handshake)
84 def _handleHandshake(self, xml):
85 self.event("session_start")
87 def connect(self):
88 logging.debug("Connecting to %s:%s" % (self.server_host, self.server_port))
89 return xmlstreammod.XMLStream.connect(self, self.server_host, self.server_port)