XEP-0353: Jingle Message Initiation

This commit is contained in:
Emmanuel Gil Peyrot 2020-12-04 03:01:19 +01:00
parent 922ad8d9ea
commit 203628d707
5 changed files with 179 additions and 0 deletions

View file

@ -512,6 +512,14 @@
<xmpp:status>unknown</xmpp:status>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0353.html"/>
<xmpp:status>complete</xmpp:status>
<xmpp:version>0.3</xmpp:version>
<xmpp:since>NEXT</xmpp:since>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0369.html"/>

View file

@ -85,6 +85,7 @@ __all__ = [
'xep_0323', # IoT Systems Sensor Data
'xep_0325', # IoT Systems Control
'xep_0332', # HTTP Over XMPP Transport
'xep_0353', # Jingle Message Initiation
'xep_0369', # MIX-CORE
'xep_0377', # Spam reporting
'xep_0403', # MIX-Presence

View file

@ -0,0 +1,14 @@
"""
slixmpp: The Slick XMPP Library
Copyright (C) 2020 Emmanuel Gil Peyrot
This file is part of slixmpp.
See the file LICENSE for copying permission.
"""
from slixmpp.plugins.base import register_plugin
from slixmpp.plugins.xep_0353.stanza import Propose, Retract, Accept, Proceed, Reject
from slixmpp.plugins.xep_0353.jingle_message import XEP_0353
register_plugin(XEP_0353)

View file

@ -0,0 +1,101 @@
"""
slixmpp: The Slick XMPP Library
Copyright (C) 2020 Emmanuel Gil Peyrot
This file is part of slixmpp.
See the file LICENSE for copying permission.
"""
import logging
from typing import Iterable, Tuple, Optional
from slixmpp import JID, Message
from slixmpp.plugins import BasePlugin
from slixmpp.xmlstream import register_stanza_plugin
from slixmpp.xmlstream.handler import Callback
from slixmpp.xmlstream.matcher import StanzaPath
from slixmpp.plugins.xep_0353 import stanza, Propose, Retract, Accept, Proceed, Reject
log = logging.getLogger(__name__)
class XEP_0353(BasePlugin):
name = 'xep_0353'
description = 'XEP-0353: Jingle Message Initiation'
stanza = stanza
def plugin_init(self):
register_stanza_plugin(Message, Propose)
register_stanza_plugin(Message, Retract)
register_stanza_plugin(Message, Accept)
register_stanza_plugin(Message, Proceed)
register_stanza_plugin(Message, Reject)
self.xmpp.register_handler(
Callback('Indicating Intent to Start a Session',
StanzaPath('message/jingle_propose'),
self._handle_propose))
self.xmpp.register_handler(
Callback('Disavowing Intent to Start a Session',
StanzaPath('message/jingle_retract'),
self._handle_retract))
self.xmpp.register_handler(
Callback('Accepting Intent to Start a Session',
StanzaPath('message/jingle_accept'),
self._handle_accept))
self.xmpp.register_handler(
Callback('Proceed',
StanzaPath('message/jingle_proceed'),
self._handle_accept))
self.xmpp.register_handler(
Callback('Rejecting Intent to Start a Session',
StanzaPath('message/jingle_reject'),
self._handle_reject))
def session_bind(self, jid):
self.xmpp.plugin['xep_0030'].add_feature(stanza.JingleMessage.namespace)
def plugin_end(self):
self.xmpp.plugin['xep_0030'].del_feature(feature=stanza.JingleMessage.namespace)
def _handle_propose(self, message):
self.xmpp.event('jingle_message_propose', message)
def _handle_retract(self, message):
self.xmpp.event('jingle_message_retract', message)
def _handle_accept(self, message):
self.xmpp.event('jingle_message_accept', message)
def _handle_proceed(self, message):
self.xmpp.event('jingle_message_proceed', message)
def _handle_reject(self, message):
self.xmpp.event('jingle_message_reject', message)
def propose(self, mto: JID, sid: str, descriptions: Iterable[Tuple[str, str]], *, mfrom: Optional[JID] = None):
msg = self.xmpp.make_message(mto, mfrom=mfrom)
msg['jingle_propose']['id'] = sid
msg['jingle_propose']['descriptions'] = descriptions
msg.send()
def retract(self, mto: JID, sid: str, *, mfrom: Optional[JID] = None):
msg = self.xmpp.make_message(mto, mfrom=mfrom)
msg['jingle_retract']['id'] = sid
msg.send()
def accept(self, mto: JID, sid: str, *, mfrom: Optional[JID] = None):
msg = self.xmpp.make_message(mto, mfrom=mfrom)
msg['jingle_accept']['id'] = sid
msg.send()
def proceed(self, mto: JID, sid: str, *, mfrom: Optional[JID] = None):
msg = self.xmpp.make_message(mto, mfrom=mfrom)
msg['jingle_proceed']['id'] = sid
msg.send()
def reject(self, mto: JID, sid: str, *, mfrom: Optional[JID] = None):
msg = self.xmpp.make_message(mto, mfrom=mfrom)
msg['jingle_reject']['id'] = sid
msg.send()

View file

@ -0,0 +1,55 @@
"""
slixmpp: The Slick XMPP Library
Copyright (C) 2020 Emmanuel Gil Peyrot
This file is part of slixmpp.
See the file LICENSE for copying permission.
"""
from typing import Iterable, List, Tuple
from slixmpp.xmlstream import ElementBase, ET
class JingleMessage(ElementBase):
namespace = 'urn:xmpp:jingle-message:0'
interfaces = {'id'}
class Propose(JingleMessage):
name = 'propose'
plugin_attrib = 'jingle_propose'
interfaces = {'id', 'descriptions'}
def get_descriptions(self) -> List[Tuple[str, str]]:
result = []
for desc in self.xml:
namespace = desc.tag.split('}')[0][1:]
media = desc.attrib['media']
result.append((namespace, media))
return result
def set_descriptions(self, descriptions: Iterable[Tuple[str, str]]):
self.del_descriptions()
for namespace, media in descriptions:
desc = ET.Element('{%s}description' % namespace)
desc.attrib['media'] = media
self.xml.append(desc)
def del_descriptions(self):
for desc in self.xml.findall('{*}description'):
self.xml.remove(desc)
class Retract(JingleMessage):
name = 'retract'
plugin_attrib = 'jingle_retract'
class Accept(JingleMessage):
name = 'accept'
plugin_attrib = 'jingle_accept'
class Proceed(JingleMessage):
name = 'proceed'
plugin_attrib = 'jingle_proceed'
class Reject(JingleMessage):
name = 'reject'
plugin_attrib = 'jingle_reject'