diff --git a/gajim/common/helpers.py b/gajim/common/helpers.py index 76f9642297ce842c3caa5c753d656ff690289af0..6b9a37c47c0fd67ec8e98e63d2cd35dd33035e17 100644 --- a/gajim/common/helpers.py +++ b/gajim/common/helpers.py @@ -1213,14 +1213,6 @@ def get_groupchat_name(con, jid): return jid.split('@')[0] -def get_alternative_venue(error): - if error.condition == 'gone' and error.condition_data is not None: - uri = parse_uri(error.condition_data) - if uri.type == URIType.XMPP and uri.action == URIAction.JOIN: - return uri.data['jid'] - return None - - def is_affiliation_change_allowed(self_contact, contact, target_aff): if contact.affiliation.value == target_aff: # Contact has already the target affiliation diff --git a/gajim/common/modules/discovery.py b/gajim/common/modules/discovery.py index 67693f2c1fcb709a27e4d69a81233e93e9573cd2..2e863d5f98ae886483704ef2ac8cf12b2ed69e7e 100644 --- a/gajim/common/modules/discovery.py +++ b/gajim/common/modules/discovery.py @@ -18,10 +18,12 @@ from nbxmpp.namespaces import Namespace from nbxmpp.structs import StanzaHandler from nbxmpp.errors import StanzaError +from nbxmpp.errors import is_error from gajim.common import app from gajim.common.nec import NetworkIncomingEvent from gajim.common.nec import NetworkEvent +from gajim.common.modules.util import task from gajim.common.modules.base import BaseModule @@ -192,35 +194,49 @@ def _answer_disco_info(self, _con, stanza, _properties): if self._con.get_module('AdHocCommands').command_info_query(stanza): raise nbxmpp.NodeProcessed - def disco_muc(self, jid, callback=None): - if not app.account_is_available(self._account): - return + @task + def disco_muc(self, + jid, + request_vcard=False, + allow_redirect=False): + + _task = yield self._log.info('Request MUC info for %s', jid) - self.disco_info(jid, - callback=self._muc_info_received, - user_data=callback) + result = yield self._nbxmpp('MUC').request_info( + jid, + request_vcard=request_vcard, + allow_redirect=allow_redirect) - def _muc_info_received(self, task): - callback = task.get_user_data() - try: - result = task.finish() - except StanzaError as error: - result = error - self._log.warning(error) + if is_error(result): + raise result + if result.redirected: + self._log.info('MUC info received after redirect: %s -> %s', + jid, result.info.jid) else: - self._log.info('MUC info received: %s', result.jid) - app.storage.cache.set_last_disco_info(result.jid, result) - self._con.get_module('VCardAvatars').muc_disco_info_update(result) - app.nec.push_incoming_event(NetworkEvent( - 'muc-disco-update', - account=self._account, - room_jid=result.jid)) - - if callback is not None: - callback(result) + self._log.info('MUC info received: %s', result.info.jid) + + app.storage.cache.set_last_disco_info(result.info.jid, result.info) + + if result.vcard is not None: + avatar, avatar_sha = result.vcard.get_avatar() + if avatar is not None: + if not app.interface.avatar_exists(avatar_sha): + app.interface.save_avatar(avatar) + + app.storage.cache.set_muc_avatar_sha(result.info.jid, + avatar_sha) + app.interface.avatar_storage.invalidate_cache(result.info.jid) + + self._con.get_module('VCardAvatars').muc_disco_info_update(result.info) + app.nec.push_incoming_event(NetworkEvent( + 'muc-disco-update', + account=self._account, + room_jid=result.info.jid)) + + yield result def get_instance(*args, **kwargs): diff --git a/gajim/common/modules/muc.py b/gajim/common/modules/muc.py index 75032b1ca3bb696867b46caf928b5f9232fdbb8c..cb1fde0ffdd67a6cc67fcd78bb5caa14b9123089 100644 --- a/gajim/common/modules/muc.py +++ b/gajim/common/modules/muc.py @@ -24,7 +24,7 @@ from nbxmpp.const import StatusCode from nbxmpp.structs import StanzaHandler from nbxmpp.util import is_error_result -from nbxmpp.errors import is_error +from nbxmpp.errors import StanzaError from gi.repository import GLib @@ -159,17 +159,19 @@ def create(self, muc_data): self._manager.add(muc_data) self._create(muc_data) - def _on_disco_result(self, result): - if is_error(result): - self._log.info('Disco %s failed: %s', result.jid, result.get_text()) + def _on_disco_result(self, task): + try: + result = task.finish() + except StanzaError as error: + self._log.info('Disco %s failed: %s', error.jid, error.get_text()) app.nec.push_incoming_event( NetworkEvent('muc-join-failed', account=self._account, - room_jid=result.jid.bare, - error=result)) + room_jid=error.jid.bare, + error=error)) return - muc_data = self._manager.get(result.jid) + muc_data = self._manager.get(result.info.jid) if muc_data is None: self._log.warning('MUC Data not found, join aborted') return @@ -286,19 +288,22 @@ def _on_config_result(self, result): for jid in invites: self.invite(result.jid, jid) - def _on_disco_result_after_config(self, result): - if is_error(result): - self._log.info('Disco %s failed: %s', result.jid, result.get_text()) + def _on_disco_result_after_config(self, task): + try: + result = task.finish() + except StanzaError as error: + self._log.info('Disco %s failed: %s', error.jid, error.get_text()) return - muc_data = self._manager.get(result.jid) + jid = result.info.jid + muc_data = self._manager.get(jid) self._room_join_complete(muc_data) - self._log.info('Configuration finished: %s', result.jid) + self._log.info('Configuration finished: %s', jid) app.nec.push_incoming_event(NetworkEvent( 'muc-configuration-finished', account=self._account, - room_jid=result.jid)) + room_jid=jid)) def update_presence(self): mucs = self._manager.get_mucs_with_state([MUCJoinedState.JOINED, diff --git a/gajim/gtk/groupchat_join.py b/gajim/gtk/groupchat_join.py index 091e9ef7e7d4c9def254c5a7d1d5bd98617233c1..9fa6b2a244c4586d141e86b028ff69d40870330a 100644 --- a/gajim/gtk/groupchat_join.py +++ b/gajim/gtk/groupchat_join.py @@ -16,13 +16,12 @@ from gi.repository import Gdk from gi.repository import Pango -from nbxmpp.errors import is_error +from nbxmpp.errors import StanzaError from gajim.common import app from gajim.common.i18n import _ from gajim.common.i18n import get_rfc5646_lang from gajim.common.helpers import to_user_string -from gajim.common.helpers import get_alternative_venue from gajim.common.helpers import get_group_chat_nick from gajim.common.const import MUC_DISCO_ERRORS @@ -89,7 +88,10 @@ def __init__(self, account, jid): con = app.connections[self.account] con.get_module('Discovery').disco_muc( - jid, callback=self._disco_info_received) + jid, + allow_redirect=True, + request_vcard=True, + callback=self._disco_info_received) def _on_page_changed(self, stack, _param): name = stack.get_visible_child_name() @@ -97,22 +99,20 @@ def _on_page_changed(self, stack, _param): self._nick_chooser.set_sensitive(name == 'info') @ensure_not_destroyed - def _disco_info_received(self, result): - if is_error(result): - jid = get_alternative_venue(result) - if jid is None or self._redirected: - self._set_error(result) - return - - self.jid = jid - self._redirected = True - con = app.connections[self.account] - con.get_module('Discovery').disco_muc( - jid, callback=self._disco_info_received) - - elif result.is_muc: - self._muc_info_box.set_from_disco_info(result) - nickname = get_group_chat_nick(self.account, result.jid) + def _disco_info_received(self, task): + try: + result = task.finish() + except StanzaError as error: + self._log.info('Disco %s failed: %s', error.jid, error.get_text()) + self._set_error(error) + return + + if result.redirected: + self.jid = result.info.jid + + if result.info.is_muc: + self._muc_info_box.set_from_disco_info(result.info) + nickname = get_group_chat_nick(self.account, result.info.jid) self._nick_chooser.set_text(nickname) self._join_button.grab_default() self._stack.set_visible_child_name('info') diff --git a/gajim/gtk/start_chat.py b/gajim/gtk/start_chat.py index f776281109f1101d57883a3aa446dd791de45ce0..f340f83ab1de9001ec0ad62c8cd901ee0e767e90 100644 --- a/gajim/gtk/start_chat.py +++ b/gajim/gtk/start_chat.py @@ -14,7 +14,6 @@ import locale from enum import IntEnum -from functools import partial from gi.repository import Gdk from gi.repository import Gtk @@ -22,14 +21,13 @@ from gi.repository import Pango from nbxmpp.util import is_error_result -from nbxmpp.errors import is_error +from nbxmpp.errors import StanzaError from gajim.common import app from gajim.common.helpers import validate_jid from gajim.common.helpers import to_user_string from gajim.common.helpers import get_groupchat_name from gajim.common.helpers import get_group_chat_nick -from gajim.common.helpers import get_alternative_venue from gajim.common.i18n import _ from gajim.common.i18n import get_rfc5646_lang from gajim.common.const import AvatarSize @@ -293,34 +291,37 @@ def _start_new_chat(self, row): self.ready_to_destroy = False self._redirected = False - self._disco_muc(row.account, row.jid) + self._disco_muc(row.account, row.jid, request_vcard=row.new) else: app.interface.new_chat_from_jid(row.account, row.jid) self.ready_to_destroy = True - def _disco_muc(self, account, jid): + def _disco_muc(self, account, jid, request_vcard): self._ui.stack.set_visible_child_name('progress') con = app.connections[account] con.get_module('Discovery').disco_muc( - jid, callback=partial(self._disco_info_received, account)) + jid, + request_vcard=request_vcard, + allow_redirect=True, + callback=self._disco_info_received, + user_data=account) @ensure_not_destroyed - def _disco_info_received(self, account, result): - if is_error(result): - jid = get_alternative_venue(result) - if jid is None or self._redirected: - self._set_error(result) - return + def _disco_info_received(self, task): + try: + result = task.finish() + except StanzaError as error: + self._set_error(error) + return - self._redirected = True - self._disco_muc(account, jid) + account = task.get_user_data() - elif result.is_muc: + if result.info.is_muc: self._muc_info_box.set_account(account) - self._muc_info_box.set_from_disco_info(result) + self._muc_info_box.set_from_disco_info(result.info) self._nick_chooser.set_text(get_group_chat_nick( - account, result.jid)) + account, result.info.jid)) self._ui.stack.set_visible_child_name('info') else: @@ -371,7 +372,7 @@ def _on_select_clicked(self, *args): return self._redirected = False - self._disco_muc(account, selected_row.jid) + self._disco_muc(account, selected_row.jid, request_vcard=True) def _set_listbox(self, listbox): if self._current_listbox == listbox: