Commit 0f6205d2 authored by Maxime Buquet's avatar Maxime Buquet

Add /invite for ConversationTab to generate new room with all invitees

Signed-off-by: Maxime Buquet's avatarMaxime “pep” Buquet <pep@bouah.net>
parent cf50ef2c
...@@ -6,6 +6,7 @@ import logging ...@@ -6,6 +6,7 @@ import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
import asyncio
from xml.etree import cElementTree as ET from xml.etree import cElementTree as ET
from slixmpp.exceptions import XMPPError from slixmpp.exceptions import XMPPError
...@@ -764,17 +765,21 @@ class CommandCore: ...@@ -764,17 +765,21 @@ class CommandCore:
self.core.information('Invited %s to %s' % (to.bare, room), 'Info') self.core.information('Invited %s to %s' % (to.bare, room), 'Info')
@command_args_parser.quoted(1, 0) @command_args_parser.quoted(1, 0)
def impromptu(self, args): def impromptu(self, args: str) -> None:
"""/impromptu <jid> [<jid> ...]""" """/impromptu <jid> [<jid> ...]"""
if args is None: if args is None:
return self.help('impromptu') return self.help('impromptu')
jids = [] jids = set()
current_tab = self.core.tabs.current_tab
if isinstance(current_tab, tabs.ConversationTab):
jids.add(current_tab.general_jid)
for jid in common.shell_split(' '.join(args)): for jid in common.shell_split(' '.join(args)):
jids.append(safeJID(jid).bare) jids.add(safeJID(jid).bare)
self.core.impromptu(jids) asyncio.ensure_future(self.core.impromptu(jids))
self.core.information('Invited %s to a random room' % (' '.join(jids)), 'Info') self.core.information('Invited %s to a random room' % (' '.join(jids)), 'Info')
@command_args_parser.quoted(1, 1, ['']) @command_args_parser.quoted(1, 1, [''])
......
...@@ -15,11 +15,14 @@ import shutil ...@@ -15,11 +15,14 @@ import shutil
import time import time
import uuid import uuid
from collections import defaultdict from collections import defaultdict
from typing import Callable, Dict, List, Optional, Tuple, Type from typing import Callable, Dict, List, Optional, Set, Tuple, Type
from xml.etree import cElementTree as ET
from functools import partial
from slixmpp import JID from slixmpp import JID
from slixmpp.util import FileSystemPerJidCache from slixmpp.util import FileSystemPerJidCache
from slixmpp.xmlstream.handler import Callback from slixmpp.xmlstream.handler import Callback
from slixmpp.exceptions import IqError, IqTimeout
from poezio import connection from poezio import connection
from poezio import decorators from poezio import decorators
...@@ -869,7 +872,35 @@ class Core: ...@@ -869,7 +872,35 @@ class Core:
self.xmpp.plugin['xep_0030'].get_info( self.xmpp.plugin['xep_0030'].get_info(
jid=jid, timeout=5, callback=callback) jid=jid, timeout=5, callback=callback)
def impromptu(self, jids: List[JID]) -> None: def _impromptu_room_form(self, room, _jids):
# TODO: Use jids to generate user-friendly room name and description
fields = [
{'ftype': 'hidden', 'var': 'FORM_TYPE', 'value': 'http://jabber.org/protocol/muc#roomconfig'},
{'ftype': 'text-single', 'var': 'muc#roomconfig_roomname', 'value': 'Foo'},
{'ftype': 'text-single', 'var': 'muc#roomconfig_roomdesc', 'value': 'Bar'},
{'ftype': 'boolean', 'var': 'muc#roomconfig_changesubject', 'value': True},
{'ftype': 'boolean', 'var': 'muc#roomconfig_allowinvites', 'value': True},
{'ftype': 'boolean', 'var': 'muc#roomconfig_persistent', 'value': True},
{'ftype': 'boolean', 'var': 'muc#roomconfig_membersonly', 'value': True},
{'ftype': 'boolean', 'var': 'muc#roomconfig_publicroom', 'value': False},
{'ftype': 'list-single', 'var': 'muc#roomconfig_allowpm', 'value': 'none'},
{'ftype': 'list-single', 'var': 'muc#roomconfig_whois', 'value': 'anyone'},
]
form = self.xmpp['xep_0004'].make_form()
form['type'] = 'submit'
for field in fields:
form.add_field(**field)
iq = self.xmpp.Iq()
iq['type'] = 'set'
iq['to'] = room
query = ET.Element('{http://jabber.org/protocol/muc#owner}query')
query.append(form.xml)
iq.append(query)
return iq
async def impromptu(self, jids: Set[JID]) -> None:
""" """
Generates a new "Impromptu" room with a random localpart on the muc Generates a new "Impromptu" room with a random localpart on the muc
component of the user who initiated the request. One the room is component of the user who initiated the request. One the room is
...@@ -877,41 +908,43 @@ class Core: ...@@ -877,41 +908,43 @@ class Core:
contacts to join in. contacts to join in.
""" """
def callback(results): results = await self.xmpp['xep_0030'].get_info_from_domain()
muc_from_identity = ''
for info in results: muc_from_identity = ''
for identity in info['disco_info']['identities']: for info in results:
if identity[0] == 'conference' and identity[1] == 'text': for identity in info['disco_info']['identities']:
muc_from_identity = info['from'].bare if identity[0] == 'conference' and identity[1] == 'text':
muc_from_identity = info['from'].bare
# Use config.default_muc_service as muc component if available, # Use config.default_muc_service as muc component if available,
# otherwise find muc component by disco#items-ing the user domain. # otherwise find muc component by disco#items-ing the user domain.
# If not, give up # If not, give up
default_muc = config.get('default_muc_service', muc_from_identity) default_muc = config.get('default_muc_service', muc_from_identity)
if not default_muc: if not default_muc:
self.information( self.information(
"Error finding a MUC service to join. If your server does not " "Error finding a MUC service to join. If your server does not "
"provide one, set 'default_muc_service' manually to a MUC " "provide one, set 'default_muc_service' manually to a MUC "
"service that allows room creation.", "service that allows room creation.",
'Error' 'Error'
) )
return return
nick = self.own_nick nick = self.own_nick
room = uuid.uuid4().hex + '@' + default_muc room = uuid.uuid4().hex + '@' + default_muc
self.open_new_room(room, nick).join() self.open_new_room(room, nick).join()
self.information('Room %s created' % room, 'Info') iq = self._impromptu_room_form(room, jids)
try:
await iq.send()
except (IqError, IqTimeout):
self.information('Failed to create configure impromptu room.', 'Info')
# TODO: destroy? leave room.
return None
for jid in jids: self.information('Room %s created' % room, 'Info')
self.invite(jid, room)
asyncio.ensure_future( for jid in jids:
self.xmpp['xep_0030'].get_info_from_domain( self.invite(jid, room)
callback=callback,
)
)
def get_error_message(self, stanza, deprecated: bool = False): def get_error_message(self, stanza, deprecated: bool = False):
""" """
......
...@@ -79,6 +79,12 @@ class ConversationTab(OneToOneTab): ...@@ -79,6 +79,12 @@ class ConversationTab(OneToOneTab):
' allow you to see his presence, and allow them to' ' allow you to see his presence, and allow them to'
' see your presence.', ' see your presence.',
shortdesc='Add a user to your roster.') shortdesc='Add a user to your roster.')
self.register_command(
'invite',
self.core.command.impromptu,
desc='Invite people into an impromptu room.',
shortdesc='Invite other users to the discussion',
completion=self.core.completion.impromptu)
self.update_commands() self.update_commands()
self.update_keys() self.update_keys()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment