Merge branch 'xep-0353' into 'master'
XEP-0353: Jingle Message Initiation See merge request poezio/slixmpp!72
This commit is contained in:
commit
5c5780503a
5 changed files with 179 additions and 0 deletions
8
doap.xml
8
doap.xml
|
@ -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"/>
|
||||
|
|
|
@ -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
|
||||
|
|
14
slixmpp/plugins/xep_0353/__init__.py
Normal file
14
slixmpp/plugins/xep_0353/__init__.py
Normal 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)
|
101
slixmpp/plugins/xep_0353/jingle_message.py
Normal file
101
slixmpp/plugins/xep_0353/jingle_message.py
Normal 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()
|
55
slixmpp/plugins/xep_0353/stanza.py
Normal file
55
slixmpp/plugins/xep_0353/stanza.py
Normal 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'
|
Loading…
Reference in a new issue