Merge branch 'invite_impromptu' into 'master'
Invite impromptu See merge request poezio/poezio!2
This commit is contained in:
commit
8a23706b72
8 changed files with 159 additions and 1 deletions
|
@ -218,6 +218,13 @@ These commands work in *any* tab.
|
|||
/invitations
|
||||
Show the pending invitations.
|
||||
|
||||
/impromptu
|
||||
**Usage:** ``/impromptu <jid> [jid ..]``
|
||||
|
||||
Invite specified JIDs into a newly created room.
|
||||
|
||||
.. versionadded:: 0.13
|
||||
|
||||
/activity
|
||||
**Usage:** ``/activity [<general> [specific] [comment]]``
|
||||
|
||||
|
@ -472,6 +479,14 @@ Normal Conversation tab commands
|
|||
Get the software version of the current interlocutor (usually its
|
||||
XMPP client and Operating System).
|
||||
|
||||
/invite
|
||||
**Usage:** ``/invite <jid> [jid ..]``
|
||||
|
||||
Invite specified JIDs, with this contact, into a newly
|
||||
created room.
|
||||
|
||||
.. versionadded:: 0.13
|
||||
|
||||
.. _rostertab-commands:
|
||||
|
||||
Contact list tab commands
|
||||
|
|
|
@ -81,6 +81,15 @@ and certificate validation.
|
|||
you know what you are doing, see the :ref:`ciphers` dedicated section
|
||||
for more details.
|
||||
|
||||
default_muc_service
|
||||
|
||||
**Default value:** ``[empty]``
|
||||
|
||||
If specified, will be used instead of the MUC service provided by
|
||||
the user domain.
|
||||
|
||||
.. versionadded:: 0.13
|
||||
|
||||
force_encryption
|
||||
|
||||
**Default value:** ``true``
|
||||
|
|
|
@ -49,6 +49,7 @@ DEFAULT_CONFIG = {
|
|||
'custom_host': '',
|
||||
'custom_port': '',
|
||||
'default_nick': '',
|
||||
'default_muc_service': '',
|
||||
'deterministic_nick_colors': True,
|
||||
'device_id': '',
|
||||
'nick_color_aliases': True,
|
||||
|
|
|
@ -6,6 +6,7 @@ import logging
|
|||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
import asyncio
|
||||
from xml.etree import cElementTree as ET
|
||||
|
||||
from slixmpp.exceptions import XMPPError
|
||||
|
@ -763,6 +764,24 @@ class CommandCore:
|
|||
self.core.invite(to.full, room, reason=reason)
|
||||
self.core.information('Invited %s to %s' % (to.bare, room), 'Info')
|
||||
|
||||
@command_args_parser.quoted(1, 0)
|
||||
def impromptu(self, args: str) -> None:
|
||||
"""/impromptu <jid> [<jid> ...]"""
|
||||
|
||||
if args is None:
|
||||
return self.help('impromptu')
|
||||
|
||||
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.add(safeJID(jid).bare)
|
||||
|
||||
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, [''])
|
||||
def decline(self, args):
|
||||
"""/decline <room@server.tld> [reason]"""
|
||||
|
|
|
@ -289,6 +289,19 @@ class CompletionCore:
|
|||
return Completion(
|
||||
the_input.new_completion, rooms, n, '', quotify=True)
|
||||
|
||||
def impromptu(self, the_input):
|
||||
"""Completion for /impromptu"""
|
||||
n = the_input.get_argument_position(quoted=True)
|
||||
onlines = []
|
||||
offlines = []
|
||||
for barejid in roster.jids():
|
||||
if len(roster[barejid]):
|
||||
onlines.append(barejid)
|
||||
else:
|
||||
offlines.append(barejid)
|
||||
comp = sorted(onlines) + sorted(offlines)
|
||||
return Completion(the_input.new_completion, comp, n, quotify=True)
|
||||
|
||||
def activity(self, the_input):
|
||||
"""Completion for /activity"""
|
||||
n = the_input.get_argument_position(quoted=True)
|
||||
|
|
|
@ -13,12 +13,16 @@ import pipes
|
|||
import sys
|
||||
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
|
||||
|
@ -868,6 +872,85 @@ class Core:
|
|||
self.xmpp.plugin['xep_0030'].get_info(
|
||||
jid=jid, timeout=5, callback=callback)
|
||||
|
||||
def _impromptu_room_form(self, room):
|
||||
fields = [
|
||||
('hidden', 'FORM_TYPE', 'http://jabber.org/protocol/muc#roomconfig'),
|
||||
('boolean', 'muc#roomconfig_changesubject', True),
|
||||
('boolean', 'muc#roomconfig_allowinvites', True),
|
||||
('boolean', 'muc#roomconfig_persistent', True),
|
||||
('boolean', 'muc#roomconfig_membersonly', True),
|
||||
('boolean', 'muc#roomconfig_publicroom', False),
|
||||
('list-single', 'muc#roomconfig_whois', 'anyone'),
|
||||
# MAM
|
||||
('boolean', 'muc#roomconfig_enablearchiving', True), # Prosody
|
||||
('boolean', 'mam', True), # Ejabberd community
|
||||
('boolean', 'muc#roomconfig_mam', True), # Ejabberd saas
|
||||
]
|
||||
|
||||
form = self.xmpp['xep_0004'].make_form()
|
||||
form['type'] = 'submit'
|
||||
for field in fields:
|
||||
form.add_field(
|
||||
ftype=field[0],
|
||||
var=field[1],
|
||||
value=field[2],
|
||||
)
|
||||
|
||||
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
|
||||
created and the first user has joined, send invites for specified
|
||||
contacts to join in.
|
||||
"""
|
||||
|
||||
results = await self.xmpp['xep_0030'].get_info_from_domain()
|
||||
|
||||
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
|
||||
|
||||
nick = self.own_nick
|
||||
localpart = uuid.uuid4().hex
|
||||
room = '{!s}@{!s}'.format(localpart, default_muc)
|
||||
|
||||
self.open_new_room(room, nick).join()
|
||||
iq = self._impromptu_room_form(room)
|
||||
try:
|
||||
await iq.send()
|
||||
except (IqError, IqTimeout):
|
||||
self.information('Failed to configure impromptu room.', 'Info')
|
||||
# TODO: destroy? leave room.
|
||||
return None
|
||||
|
||||
self.information('Room %s created' % room, 'Info')
|
||||
|
||||
for jid in jids:
|
||||
self.invite(jid, room)
|
||||
|
||||
def get_error_message(self, stanza, deprecated: bool = False):
|
||||
"""
|
||||
Takes a stanza of the form <message type='error'><error/></message>
|
||||
|
@ -1788,6 +1871,13 @@ class Core:
|
|||
desc='Invite jid in room with reason.',
|
||||
shortdesc='Invite someone in a room.',
|
||||
completion=self.completion.invite)
|
||||
self.register_command(
|
||||
'impromptu',
|
||||
self.command.impromptu,
|
||||
usage='<jid> [jid ...]',
|
||||
desc='Invite specified JIDs into a newly created room.',
|
||||
shortdesc='Invite specified JIDs into newly created room.',
|
||||
completion=self.completion.impromptu)
|
||||
self.register_command(
|
||||
'invitations',
|
||||
self.command.invitations,
|
||||
|
|
|
@ -97,6 +97,11 @@ class HandlerCore:
|
|||
self.core.xmpp.plugin['xep_0030'].get_info(
|
||||
jid=self.core.xmpp.boundjid.domain, callback=callback)
|
||||
|
||||
def find_identities(self, _):
|
||||
asyncio.ensure_future(
|
||||
self.core.xmpp['xep_0030'].get_info_from_domain(),
|
||||
)
|
||||
|
||||
def on_carbon_received(self, message):
|
||||
"""
|
||||
Carbon <received/> received
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
Loading…
Reference in a new issue