summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--cacert.pem76
-rw-r--r--connection/__init__.py0
-rw-r--r--connection/xmpp.py132
-rwxr-xr-xcurunir8
-rw-r--r--curunir.py21
6 files changed, 239 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b261d8d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*~
+*.pyo
diff --git a/cacert.pem b/cacert.pem
new file mode 100644
index 0000000..da2e8e6
--- /dev/null
+++ b/cacert.pem
@@ -0,0 +1,76 @@
+-----BEGIN CERTIFICATE-----
+MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290
+IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB
+IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA
+Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO
+BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi
+MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ
+ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
+CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ
+8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6
+zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y
+fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7
+w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc
+G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k
+epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q
+laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ
+QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU
+fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826
+YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w
+ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY
+gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe
+MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0
+IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy
+dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw
+czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0
+dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl
+aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC
+AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg
+b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB
+ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc
+nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg
+18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c
+gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl
+Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY
+sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T
+SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF
+CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum
+GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk
+zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW
+omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGCDCCA/CgAwIBAgIBATANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290
+IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB
+IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA
+Y2FjZXJ0Lm9yZzAeFw0wNTEwMTQwNzM2NTVaFw0zMzAzMjgwNzM2NTVaMFQxFDAS
+BgNVBAoTC0NBY2VydCBJbmMuMR4wHAYDVQQLExVodHRwOi8vd3d3LkNBY2VydC5v
+cmcxHDAaBgNVBAMTE0NBY2VydCBDbGFzcyAzIFJvb3QwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQCrSTURSHzSJn5TlM9Dqd0o10Iqi/OHeBlYfA+e2ol9
+4fvrcpANdKGWZKufoCSZc9riVXbHF3v1BKxGuMO+f2SNEGwk82GcwPKQ+lHm9WkB
+Y8MPVuJKQs/iRIwlKKjFeQl9RrmK8+nzNCkIReQcn8uUBByBqBSzmGXEQ+xOgo0J
+0b2qW42S0OzekMV/CsLj6+YxWl50PpczWejDAz1gM7/30W9HxM3uYoNSbi4ImqTZ
+FRiRpoWSR7CuSOtttyHshRpocjWr//AQXcD0lKdq1TuSfkyQBX6TwSyLpI5idBVx
+bgtxA+qvFTia1NIFcm+M+SvrWnIl+TlG43IbPgTDZCciECqKT1inA62+tC4T7V2q
+SNfVfdQqe1z6RgRQ5MwOQluM7dvyz/yWk+DbETZUYjQ4jwxgmzuXVjit89Jbi6Bb
+6k6WuHzX1aCGcEDTkSm3ojyt9Yy7zxqSiuQ0e8DYbF/pCsLDpyCaWt8sXVJcukfV
+m+8kKHA4IC/VfynAskEDaJLM4JzMl0tF7zoQCqtwOpiVcK01seqFK6QcgCExqa5g
+eoAmSAC4AcCTY1UikTxW56/bOiXzjzFU6iaLgVn5odFTEcV7nQP2dBHgbbEsPyyG
+kZlxmqZ3izRg0RS0LKydr4wQ05/EavhvE/xzWfdmQnQeiuP43NJvmJzLR5iVQAX7
+6QIDAQABo4G/MIG8MA8GA1UdEwEB/wQFMAMBAf8wXQYIKwYBBQUHAQEEUTBPMCMG
+CCsGAQUFBzABhhdodHRwOi8vb2NzcC5DQWNlcnQub3JnLzAoBggrBgEFBQcwAoYc
+aHR0cDovL3d3dy5DQWNlcnQub3JnL2NhLmNydDBKBgNVHSAEQzBBMD8GCCsGAQQB
+gZBKMDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuQ0FjZXJ0Lm9yZy9pbmRleC5w
+aHA/aWQ9MTAwDQYJKoZIhvcNAQEEBQADggIBAH8IiKHaGlBJ2on7oQhy84r3HsQ6
+tHlbIDCxRd7CXdNlafHCXVRUPIVfuXtCkcKZ/RtRm6tGpaEQU55tiKxzbiwzpvD0
+nuB1wT6IRanhZkP+VlrRekF490DaSjrxC1uluxYG5sLnk7mFTZdPsR44Q4Dvmw2M
+77inYACHV30eRBzLI++bPJmdr7UpHEV5FpZNJ23xHGzDwlVks7wU4vOkHx4y/CcV
+Bc/dLq4+gmF78CEQGPZE6lM5+dzQmiDgxrvgu1pPxJnIB721vaLbLmINQjRBvP+L
+ivVRIqqIMADisNS8vmW61QNXeZvo3MhN+FDtkaVSKKKs+zZYPumUK5FQhxvWXtaM
+zPcPEAxSTtAWYeXlCmy/F8dyRlecmPVsYGN6b165Ti/Iubm7aoW8mA3t+T6XhDSU
+rgCvoeXnkm5OvfPi2RSLXNLrAWygF6UtEOucekq9ve7O/e0iQKtwOIj1CodqwqsF
+YMlIBdpTwd5Ed2qz8zw87YC8pjhKKSRf/lk7myV6VmMAZLldpGJ9VzZPrYPvH5JT
+oI53V93lYRE9IwCQTDz6o2CTBKOvNfYOao9PSmCnhQVsRqGP9Md246FZV/dxssRu
+FFxtbUFm3xuTsdQAw+7Lzzw9IYCpX2Nl/N3gX6T0K/CFcUHUZyX7GrGXrtaZghNB
+0m6lG5kngOcLqagA
+-----END CERTIFICATE-----
diff --git a/connection/__init__.py b/connection/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/connection/__init__.py
diff --git a/connection/xmpp.py b/connection/xmpp.py
new file mode 100644
index 0000000..1b2dcf1
--- /dev/null
+++ b/connection/xmpp.py
@@ -0,0 +1,132 @@
+from pyxmpp.all import JID, Message
+from pyxmpp.streamtls import TLSSettings
+from pyxmpp.client import Client
+from pyxmpp.jabber.muc import *
+from pyxmpp.interface import implements
+from pyxmpp.interfaces import *
+
+class MessageHandler:
+ implements(IMessageHandlersProvider)
+
+ def __init__(self, client):
+ self.client = client
+
+ def get_message_handlers(self):
+ return [
+ ("normal", self.message),
+ ]
+
+ def message(self, stanza):
+ return Message(
+ to_jid=stanza.get_from(),
+ from_jid=stanza.get_to(),
+ stanza_type=stanza.get_type(),
+ subject=stanza.get_subject(),
+ body=stanza.get_body())
+
+class MucHandler(MucRoomHandler):
+ def message_received(self, user, stanza):
+ if(user.same_as(self.room_state.me)):
+ return
+
+ self.room_state.send_message(stanza.get_body()[::-1])
+
+ def user_joined(self, user, stanza):
+ if(not self.room_state.joined or user.same_as(self.room_state.me)):
+ return
+
+ self.room_state.send_message('Willkommen, ' + user.nick)
+
+class PresenceHandler(object):
+ implements(IPresenceHandlersProvider)
+
+ def __init__(self, client):
+ self.client = client
+
+ def get_presence_handlers(self):
+ return [
+ (None, self.presence),
+ ("unavailable", self.presence),
+ ("subscribe", self.presence_control),
+ ("subscribed", self.presence_control),
+ ("unsubscribe", self.presence_control),
+ ("unsubscribed", self.presence_control),
+ ]
+
+ def presence(self,stanza):
+ msg=u"%s has become " % (stanza.get_from())
+ t=stanza.get_type()
+ if t=="unavailable":
+ msg+=u"unavailable"
+ else:
+ msg+=u"available"
+
+ show=stanza.get_show()
+ if show:
+ msg+=u"(%s)" % (show,)
+
+ status=stanza.get_status()
+ if status:
+ msg+=u": "+status
+ print msg
+
+ def presence_control(self,stanza):
+ msg=unicode(stanza.get_from())
+ t=stanza.get_type()
+ if t=="subscribe":
+ msg+=u" has requested presence subscription."
+ elif t=="subscribed":
+ msg+=u" has accepted our presence subscription request."
+ elif t=="unsubscribe":
+ msg+=u" has canceled his subscription of our."
+ elif t=="unsubscribed":
+ msg+=u" has canceled our subscription of his presence."
+
+ print msg
+
+ return stanza.make_accept_response()
+
+class VersionHandler(object):
+ implements(IIqHandlersProvider, IFeaturesProvider)
+
+ def __init__(self, client):
+ self.client = client
+
+ def get_features(self):
+ return ["jabber:iq:version"]
+
+ def get_iq_get_handlers(self):
+ return [
+ ("query", "jabber:iq:version", self.get_version),
+ ]
+
+ def get_iq_set_handlers(self):
+ return []
+
+ def get_version(self,iq):
+ iq=iq.make_result_response()
+ q=iq.new_query("jabber:iq:version")
+ q.newTextChild(q.ns(),"name","Curunir XMPP-Bot")
+ q.newTextChild(q.ns(),"version","0.1")
+ return iq
+
+
+class XMPPConnection(Client):
+ _jid = JID('curunir@jabber.ccc.de/Orthanc')
+ _password = ''
+ _cert_file = 'cacert.pem'
+
+ def __init__(self):
+ Client.__init__(self, self._jid, self._password, tls_settings = TLSSettings(require = True, cacert_file = self._cert_file))
+
+ self.interface_providers = [
+ MessageHandler(self),
+ PresenceHandler(self),
+ VersionHandler(self)
+ ]
+
+ def authorized(self):
+ Client.authorized(self)
+ self.room_manager = MucRoomManager(self.stream)
+ self.room_manager.set_handlers()
+ self.room_manager.join(JID('c3hl@conference.jabber.ccc.de'), 'curunir', MucHandler(), history_maxstanzas=0)
diff --git a/curunir b/curunir
new file mode 100755
index 0000000..bf357b1
--- /dev/null
+++ b/curunir
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+APP=`basename $0`
+DIR=`dirname $0`
+
+cd "$DIR"
+export PYTHONPATH="$PYTHONPATH:."
+exec /usr/bin/env python -OO "$APP.py" "$@"
diff --git a/curunir.py b/curunir.py
new file mode 100644
index 0000000..3c6c442
--- /dev/null
+++ b/curunir.py
@@ -0,0 +1,21 @@
+from connection.xmpp import XMPPConnection
+
+import signal, sys
+
+run = True
+
+def exithandler(signum, frame):
+ global run
+ run = False
+
+signal.signal(signal.SIGINT, exithandler)
+signal.signal(signal.SIGTERM, exithandler)
+signal.signal(signal.SIGQUIT, exithandler)
+
+connection = XMPPConnection()
+connection.connect()
+
+while run:
+ connection.stream.loop_iter(1)
+
+connection.disconnect()