summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--poezio/core/commands.py13
-rw-r--r--poezio/core/core.py95
-rw-r--r--poezio/tabs/conversationtab.py6
3 files changed, 79 insertions, 35 deletions
diff --git a/poezio/core/commands.py b/poezio/core/commands.py
index f301e801..86df9a93 100644
--- a/poezio/core/commands.py
+++ b/poezio/core/commands.py
@@ -6,6 +6,7 @@ import logging
log = logging.getLogger(__name__)
+import asyncio
from xml.etree import cElementTree as ET
from slixmpp.exceptions import XMPPError
@@ -764,17 +765,21 @@ class CommandCore:
self.core.information('Invited %s to %s' % (to.bare, room), 'Info')
@command_args_parser.quoted(1, 0)
- def impromptu(self, args):
+ def impromptu(self, args: str) -> None:
"""/impromptu <jid> [<jid> ...]"""
if args is None:
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)):
- 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')
@command_args_parser.quoted(1, 1, [''])
diff --git a/poezio/core/core.py b/poezio/core/core.py
index edec3b0c..9ffa59a9 100644
--- a/poezio/core/core.py
+++ b/poezio/core/core.py
@@ -15,11 +15,14 @@ import shutil
import time
import uuid
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.util import FileSystemPerJidCache
from slixmpp.xmlstream.handler import Callback
+from slixmpp.exceptions import IqError, IqTimeout
from poezio import connection
from poezio import decorators
@@ -869,7 +872,35 @@ class Core:
self.xmpp.plugin['xep_0030'].get_info(
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
component of the user who initiated the request. One the room is
@@ -877,41 +908,43 @@ class Core:
contacts to join in.
"""
- def callback(results):
- muc_from_identity = ''
+ results = await self.xmpp['xep_0030'].get_info_from_domain()
- for info in results:
- for identity in info['disco_info']['identities']:
- if identity[0] == 'conference' and identity[1] == 'text':
- muc_from_identity = info['from'].bare
+ muc_from_identity = ''
+ for info in results:
+ for identity in info['disco_info']['identities']:
+ if identity[0] == 'conference' and identity[1] == 'text':
+ muc_from_identity = info['from'].bare
- # Use config.default_muc_service as muc component if available,
- # otherwise find muc component by disco#items-ing the user domain.
- # If not, give up
- default_muc = config.get('default_muc_service', muc_from_identity)
- if not default_muc:
- self.information(
- "Error finding a MUC service to join. If your server does not "
- "provide one, set 'default_muc_service' manually to a MUC "
- "service that allows room creation.",
- 'Error'
- )
- return
+ # Use config.default_muc_service as muc component if available,
+ # otherwise find muc component by disco#items-ing the user domain.
+ # If not, give up
+ default_muc = config.get('default_muc_service', muc_from_identity)
+ if not default_muc:
+ self.information(
+ "Error finding a MUC service to join. If your server does not "
+ "provide one, set 'default_muc_service' manually to a MUC "
+ "service that allows room creation.",
+ 'Error'
+ )
+ return
- nick = self.own_nick
- room = uuid.uuid4().hex + '@' + default_muc
+ nick = self.own_nick
+ room = uuid.uuid4().hex + '@' + default_muc
- self.open_new_room(room, nick).join()
- self.information('Room %s created' % room, 'Info')
+ self.open_new_room(room, nick).join()
+ 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.invite(jid, room)
+ self.information('Room %s created' % room, 'Info')
- asyncio.ensure_future(
- self.xmpp['xep_0030'].get_info_from_domain(
- callback=callback,
- )
- )
+ for jid in jids:
+ self.invite(jid, room)
def get_error_message(self, stanza, deprecated: bool = False):
"""
diff --git a/poezio/tabs/conversationtab.py b/poezio/tabs/conversationtab.py
index 7e7a7488..94f1d719 100644
--- a/poezio/tabs/conversationtab.py
+++ b/poezio/tabs/conversationtab.py
@@ -79,6 +79,12 @@ class ConversationTab(OneToOneTab):
' allow you to see his presence, and allow them to'
' see your presence.',
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_keys()