Commit e91ba351 authored by Philipp Hörist's avatar Philipp Hörist

MUC: Configure all rooms automatically on creation

parent 0322b4a5
Pipeline #3747 passed with stages
in 2 minutes and 40 seconds
......@@ -1616,3 +1616,23 @@ def get_resource(account):
'rand': rand})
app.config.set_per('accounts', account, 'resource', resource)
return resource
def get_default_muc_config():
return {
# XEP-0045 options
'muc#roomconfig_allowinvites': True,
'muc#roomconfig_publicroom': False,
'muc#roomconfig_membersonly': True,
'muc#roomconfig_persistentroom': True,
'muc#roomconfig_whois': 'anyone',
'muc#roomconfig_moderatedroom': False,
# Ejabberd options
'allow_voice_requests': False,
'public_list': False,
# Prosody options
'{http://prosody.im/protocol/muc}roomconfig_allowmemberinvites': True,
'muc#roomconfig_enablearchiving': True,
}
......@@ -32,6 +32,7 @@ from gajim.common.const import KindConstant
from gajim.common.const import MUCJoinedState
from gajim.common.structs import MUCData
from gajim.common.helpers import AdditionalDataDict
from gajim.common.helpers import get_default_muc_config
from gajim.common import idle
from gajim.common.caps_cache import muc_caps_cache
from gajim.common.nec import NetworkEvent
......@@ -100,8 +101,6 @@ class MUC(BaseModule):
priority=49)
]
self._register_callback('request_config', self._config_received)
self._muc_data = {}
def pass_disco(self, from_, identities, features, _data, _node):
......@@ -168,6 +167,77 @@ class MUC(BaseModule):
'%s/%s' % (room_jid, muc.nick),
typ='unavailable')
def configure_room(self, room_jid):
self._nbxmpp('MUC').request_config(room_jid,
callback=self._on_room_config)
def _on_room_config(self, result):
if is_error_result(result):
self._log.info('Error: %s', result)
app.nec.push_incoming_event(NetworkEvent(
'muc-configuration-failed',
account=self._account,
room_jid=result.jid,
error=result))
return
self._log.info('Configure room: %s', result.jid)
self._apply_config(result.form)
self.set_config(result.jid,
result.form,
callback=self._on_config_result)
@staticmethod
def _apply_config(form, config=None):
if config is None:
config = get_default_muc_config()
for var, value in config.items():
try:
field = form[var]
except KeyError:
pass
else:
field.value = value
def _on_config_result(self, result):
if is_error_result(result):
self._log.info('Error: %s', result)
app.nec.push_incoming_event(NetworkEvent(
'muc-configuration-failed',
account=self._account,
room_jid=result.jid,
error=result))
return
self._log.info('Configuration finished: %s', result.jid)
app.nec.push_incoming_event(NetworkEvent(
'muc-configuration-finished',
account=self._account,
room_jid=result.jid))
self._con.get_module('Discovery').disco_muc(
result.jid, partial(self._on_disco_update, result.jid), update=True)
# If this is an automatic room creation
try:
invites = app.automatic_rooms[self._account][result.jid]['invities']
except KeyError:
return
user_list = {}
for jid in invites:
user_list[jid] = {'affiliation': 'member'}
self.set_affiliation(result.jid, user_list)
for jid in invites:
self.invite(result.jid, jid)
def _on_disco_update(self, room_jid):
app.nec.push_incoming_event(NetworkEvent(
'muc-disco-update',
account=self._account,
room_jid=room_jid))
def update_presence(self, auto=False):
mucs = self.get_mucs_with_state([MUCJoinedState.JOINED,
MUCJoinedState.JOINING])
......@@ -292,6 +362,8 @@ class MUC(BaseModule):
if properties.is_muc_self_presence:
self._log.info('Self presence: %s', properties.jid)
self._raise_muc_event('muc-self-presence', properties)
if properties.is_new_room:
self.configure_room(room_jid)
else:
self._log.info('User joined: %s', properties.jid)
self._raise_muc_event('muc-user-joined', properties)
......@@ -531,18 +603,9 @@ class MUC(BaseModule):
type_ = InviteType.DIRECT
password = app.gc_passwords.get(room, None)
self._log.info('Inivte %s to %s', to, room)
self._nbxmpp('MUC').invite(room, to, reason, password, continue_, type_)
def _config_received(self, result):
if is_error_result(result):
return
app.nec.push_incoming_event(NetworkEvent(
'muc-config',
conn=self._con,
dataform=result.form,
jid=result.jid))
def get_instance(*args, **kwargs):
return MUC(*args, **kwargs), 'MUC'
......@@ -38,6 +38,7 @@ from nbxmpp.const import Affiliation
from nbxmpp.const import Role
from nbxmpp.const import Error
from nbxmpp.const import PresenceType
from nbxmpp.util import is_error_result
from gi.repository import Gtk
from gi.repository import Gdk
......@@ -326,6 +327,8 @@ class GroupchatControl(ChatControlBase):
('muc-subject', ged.GUI1, self._on_subject),
('muc-captcha-challenge', ged.GUI1, self._on_captcha_challenge),
('muc-voice-approval', ged.GUI1, self._on_voice_approval),
('muc-disco-update', ged.GUI1, self._on_disco_update),
('muc-configuration-finished', ged.GUI1, self._on_configuration_finished),
('gc-message-received', ged.GUI1, self._nec_gc_message_received),
('mam-decrypted-message-received', ged.GUI1, self._nec_mam_decrypted_message_received),
('update-gc-avatar', ged.GUI1, self._nec_update_avatar),
......@@ -593,8 +596,8 @@ class GroupchatControl(ChatControlBase):
desc = app.css_config.get_font('.gajim-group-row')
renderer.set_property('font-desc', desc)
def _on_room_created(self):
@event_filter(['account', 'room_jid'])
def _on_disco_update(self, _event):
if self.parent_win is None:
return
win = self.parent_win.window
......@@ -663,20 +666,27 @@ class GroupchatControl(ChatControlBase):
DestroyMucDialog(self.room_jid, destroy_handler=_on_confirm)
def _on_configure_room(self, _action, _param):
win = app.get_app_window('GroupchatConfig', self.account, self.room_jid)
if win is not None:
win.present()
return
contact = app.contacts.get_gc_contact(
self.account, self.room_jid, self.nick)
if contact.affiliation.is_owner:
con = app.connections[self.account]
con.get_module('MUC').request_config(self.room_jid)
con.get_module('MUC').request_config(
self.room_jid, callback=self._on_configure_form_received)
elif contact.affiliation.is_admin:
win = app.get_app_window(
'GroupchatConfig', self.account, self.room_jid)
if win is not None:
win.present()
else:
GroupchatConfig(self.account,
self.room_jid,
contact.affiliation.value)
GroupchatConfig(self.account,
self.room_jid,
contact.affiliation.value)
def _on_configure_form_received(self, result):
if is_error_result(result):
log.info('Error %s %s', result.jid, result)
return
GroupchatConfig(self.account, result.jid, 'owner', result.form)
def _on_print_join_left(self, action, param):
action.set_state(param)
......@@ -1694,8 +1704,6 @@ class GroupchatControl(ChatControlBase):
@event_filter(['account', 'room_jid'])
def _on_self_presence(self, event):
nick = event.properties.muc_nickname
affiliation = event.properties.affiliation
jid = str(event.properties.jid)
status_codes = event.properties.muc_status_codes or []
if not self.is_connected:
......@@ -1704,24 +1712,6 @@ class GroupchatControl(ChatControlBase):
self.add_contact_to_roster(nick)
self.got_connected()
if self.room_jid in app.automatic_rooms[self.account] and \
app.automatic_rooms[self.account][self.room_jid]['invities']:
if self.room_jid not in app.interface.instances[self.account]['gc_config']:
con = app.connections[self.account]
if affiliation.is_owner:
# We need to configure the room if it's a new one.
# We cannot know it's a new one. Status 201 is not
# sent by all servers.
con.get_module('MUC').request_config(self.room_jid)
elif 'continue_tag' in app.automatic_rooms[self.account][self.room_jid]:
# We just need to invite contacts
for jid in app.automatic_rooms[self.account][self.room_jid]['invities']:
con.get_module('MUC').invite(self.room_jid, jid)
self.add_info_message(
_('%(jid)s has been '
'invited in this room') % {'jid': jid})
if StatusCode.NON_ANONYMOUS in status_codes:
self.add_info_message(
_('Any occupant is allowed to see your full JID'))
......@@ -1734,16 +1724,13 @@ class GroupchatControl(ChatControlBase):
self.add_info_message(\
_('The server has assigned or modified your roomnick'))
if event.properties.is_new_room:
app.connections[self.account].get_module('Discovery').disco_muc(
self.room_jid, self._on_room_created, update=True)
self.add_info_message(_('A new room has been created'))
con = app.connections[self.account]
con.get_module('MUC').request_config(self.room_jid)
# Update Actions
self.update_actions()
@event_filter(['account', 'room_jid'])
def _on_configuration_finished(self, _event):
self.add_info_message(_('A new room has been created'))
@event_filter(['account', 'room_jid'])
def _on_nickname_changed(self, event):
nick = event.properties.muc_nickname
......
......@@ -108,7 +108,6 @@ from gajim.gtk.join_groupchat import JoinGroupchatWindow
from gajim.gtk.filechoosers import FileChooserDialog
from gajim.gtk.emoji_data import emoji_data
from gajim.gtk.emoji_data import emoji_ascii_data
from gajim.gtk.groupchat_config import GroupchatConfig
from gajim.gtk.filetransfer import FileTransfersWindow
from gajim.gtk.http_upload_progress import HTTPUploadProgressWindow
from gajim.gtk.roster_item_exchange import RosterItemExchangeWindow
......@@ -456,52 +455,6 @@ class Interface:
'unsubscribed', 'gajim-unsubscribed',
event_type, obj.jid)
def handle_event_gc_config(self, obj):
#('GC_CONFIG', account, (jid, form_node)) config is a dict
account = obj.conn.name
if obj.jid in app.automatic_rooms[account]:
if 'continue_tag' in app.automatic_rooms[account][obj.jid]:
# We're converting chat to muc. allow participants to invite
for f in obj.dataform.iter_fields():
if f.var == 'muc#roomconfig_allowinvites':
f.value = True
elif f.var == 'muc#roomconfig_publicroom':
f.value = False
elif f.var == 'muc#roomconfig_membersonly':
f.value = True
elif f.var == 'public_list':
f.value = False
obj.conn.get_module('MUC').set_config(obj.jid, obj.dataform.get_purged())
user_list = {}
for jid in app.automatic_rooms[account][obj.jid]['invities']:
user_list[jid] = {'affiliation': 'member'}
obj.conn.get_module('MUC').set_affiliation(obj.jid, user_list)
else:
# use default configuration
obj.conn.get_module('MUC').set_config(obj.jid, obj.form_node)
# invite contacts
# check if it is necessary to add <continue />
continue_tag = False
if 'continue_tag' in app.automatic_rooms[account][obj.jid]:
continue_tag = True
if 'invities' in app.automatic_rooms[account][obj.jid]:
for jid in app.automatic_rooms[account][obj.jid]['invities']:
obj.conn.get_module('MUC').invite(
obj.jid, jid, continue_=continue_tag)
gc_control = self.msg_win_mgr.get_gc_control(obj.jid,
account)
if gc_control:
gc_control.add_info_message(
_('%(jid)s has been invited in this room') % {
'jid': jid})
del app.automatic_rooms[account][obj.jid]
else:
win = app.get_app_window('GroupchatConfig', account, obj.jid)
if win is not None:
win.present()
else:
GroupchatConfig(account, obj.jid, 'owner', obj.dataform)
def handle_event_gc_decline(self, event):
gc_control = self.msg_win_mgr.get_gc_control(str(event.muc),
event.account)
......@@ -1275,7 +1228,6 @@ class Interface:
'message-not-sent': [self.handle_event_msgnotsent],
'message-sent': [self.handle_event_msgsent],
'metacontacts-received': [self.handle_event_metacontacts],
'muc-config': [self.handle_event_gc_config],
'our-show': [self.handle_event_status],
'password-required': [self.handle_event_password_required],
'plain-connection': [self.handle_event_plain_connection],
......
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