From 5ae6c8f8faefef3bd0c7d8e4caf0a2071d76382d Mon Sep 17 00:00:00 2001
From: Lance Stout <lancestout@gmail.com>
Date: Sat, 28 Jul 2012 01:06:21 -0700
Subject: Add support for XEP-0131: Standard Headers and Internet Metadata

---
 sleekxmpp/plugins/__init__.py          |  1 +
 sleekxmpp/plugins/xep_0060/pubsub.py   |  4 ++-
 sleekxmpp/plugins/xep_0131/__init__.py | 16 +++++++++++
 sleekxmpp/plugins/xep_0131/headers.py  | 41 +++++++++++++++++++++++++++
 sleekxmpp/plugins/xep_0131/stanza.py   | 51 ++++++++++++++++++++++++++++++++++
 5 files changed, 112 insertions(+), 1 deletion(-)
 create mode 100644 sleekxmpp/plugins/xep_0131/__init__.py
 create mode 100644 sleekxmpp/plugins/xep_0131/headers.py
 create mode 100644 sleekxmpp/plugins/xep_0131/stanza.py

(limited to 'sleekxmpp/plugins')

diff --git a/sleekxmpp/plugins/__init__.py b/sleekxmpp/plugins/__init__.py
index 615ef7eb..ce64e152 100644
--- a/sleekxmpp/plugins/__init__.py
+++ b/sleekxmpp/plugins/__init__.py
@@ -42,6 +42,7 @@ __all__ = [
     'xep_0115',  # Entity Capabilities
     'xep_0118',  # User Tune
     'xep_0128',  # Extended Service Discovery
+    'xep_0131',  # Standard Headers and Internet Metadata
     'xep_0133',  # Service Administration
     'xep_0153',  # vCard-Based Avatars
     'xep_0163',  # Personal Eventing Protocol
diff --git a/sleekxmpp/plugins/xep_0060/pubsub.py b/sleekxmpp/plugins/xep_0060/pubsub.py
index 387c5a0f..952cad85 100644
--- a/sleekxmpp/plugins/xep_0060/pubsub.py
+++ b/sleekxmpp/plugins/xep_0060/pubsub.py
@@ -26,7 +26,7 @@ class XEP_0060(BasePlugin):
 
     name = 'xep_0060'
     description = 'XEP-0060: Publish-Subscribe'
-    dependencies = set(['xep_0030', 'xep_0004'])
+    dependencies = set(['xep_0030', 'xep_0004', 'xep_0082', 'xep_0131'])
     stanza = stanza
 
     def plugin_init(self):
@@ -53,6 +53,8 @@ class XEP_0060(BasePlugin):
                     StanzaPath('message/pubsub_event/subscription'),
                     self._handle_event_subscription))
 
+        self.xmpp['xep_0131'].supported_headers.add('SubID')
+
     def plugin_end(self):
         self.xmpp.remove_handler('Pubsub Event: Items')
         self.xmpp.remove_handler('Pubsub Event: Purge')
diff --git a/sleekxmpp/plugins/xep_0131/__init__.py b/sleekxmpp/plugins/xep_0131/__init__.py
new file mode 100644
index 00000000..ec71c98d
--- /dev/null
+++ b/sleekxmpp/plugins/xep_0131/__init__.py
@@ -0,0 +1,16 @@
+"""
+    SleekXMPP: The Sleek XMPP Library
+    Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+    This file is part of SleekXMPP.
+
+    See the file LICENSE for copying permission.
+"""
+
+from sleekxmpp.plugins.base import register_plugin
+
+from sleekxmpp.plugins.xep_0131 import stanza
+from sleekxmpp.plugins.xep_0131.stanza import Headers
+from sleekxmpp.plugins.xep_0131.headers import XEP_0131
+
+
+register_plugin(XEP_0131)
diff --git a/sleekxmpp/plugins/xep_0131/headers.py b/sleekxmpp/plugins/xep_0131/headers.py
new file mode 100644
index 00000000..3e47541a
--- /dev/null
+++ b/sleekxmpp/plugins/xep_0131/headers.py
@@ -0,0 +1,41 @@
+"""
+    SleekXMPP: The Sleek XMPP Library
+    Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
+    This file is part of SleekXMPP.
+
+    See the file LICENSE for copying permission.
+"""
+
+from sleekxmpp import Message, Presence
+from sleekxmpp.xmlstream import register_stanza_plugin
+from sleekxmpp.plugins import BasePlugin
+from sleekxmpp.plugins.xep_0131 import stanza
+from sleekxmpp.plugins.xep_0131.stanza import Headers
+
+
+class XEP_0131(BasePlugin):
+
+    name = 'xep_0131'
+    description = 'XEP-0131: Stanza Headers and Internet Metadata'
+    dependencies = set(['xep_0030'])
+    stanza = stanza
+    default_config = {
+        'supported_headers': set()
+    }
+
+    def plugin_init(self):
+        register_stanza_plugin(Message, Headers)
+        register_stanza_plugin(Presence, Headers)
+
+    def plugin_end(self):
+        self.xmpp['xep_0030'].del_feature(feature=Headers.namespace)
+        for header in self.supported_headers:
+            self.xmpp['xep_0030'].del_feature(
+                    feature='%s#%s' % (Headers.namespace, header))
+
+    def session_bind(self, jid):
+        self.xmpp['xep_0030'].add_feature(Headers.namespace)
+        for header in self.supported_headers:
+            self.xmpp['xep_0030'].add_feature('%s#%s' % (
+                Headers.namespace,
+                header))
diff --git a/sleekxmpp/plugins/xep_0131/stanza.py b/sleekxmpp/plugins/xep_0131/stanza.py
new file mode 100644
index 00000000..347adf96
--- /dev/null
+++ b/sleekxmpp/plugins/xep_0131/stanza.py
@@ -0,0 +1,51 @@
+"""
+    SleekXMPP: The Sleek XMPP Library
+    Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
+    This file is part of SleekXMPP.
+
+    See the file LICENSE for copying permission.
+"""
+
+from sleekxmpp.thirdparty import OrderedDict
+from sleekxmpp.xmlstream import ET, ElementBase
+
+
+class Headers(ElementBase):
+    name = 'headers'
+    namespace = 'http://jabber.org/protocol/shim'
+    plugin_attrib = 'headers'
+    interfaces = set(['headers'])
+    is_extension = True
+
+    def get_headers(self):
+        result = OrderedDict()
+        headers = self.xml.findall('{%s}header' % self.namespace)
+        for header in headers:
+            name = header.attrib.get('name', '')
+            value = header.text
+            if name in result:
+                if not isinstance(result[name], set):
+                    result[name] = [result[name]]
+                else:
+                    result[name] = []
+                result[name].add(value)
+            else:
+                result[name] = value
+        return result
+
+    def set_headers(self, values):
+        self.del_headers()
+        for name in values:
+            vals = values[name]
+            if not isinstance(vals, (list, set)):
+                vals = [values[name]]
+            for value in vals:
+                header = ET.Element('{%s}header' % self.namespace)
+                header.attrib['name'] = name
+                header.text = value
+                self.xml.append(header)
+
+    def del_headers(self):
+        headers = self.xml.findall('{%s}header' % self.namespace)
+        for header in headers:
+            self.xml.remove(header)
-- 
cgit v1.2.3