Daniel Brötzmann pushed to branch archive_cache at gajim / gajim
Commits: 8af47b1b by wurstsalat at 2022-08-27T14:03:15+02:00 Add more events
- - - - -
9 changed files:
- gajim/common/events.py - gajim/common/modules/contacts.py - gajim/common/modules/muc.py - gajim/common/storage/events.py - gajim/gtk/chat_stack.py - gajim/gtk/control.py - gajim/gtk/conversation/view.py - gajim/gtk/groupchat_nick_completion.py - gajim/gtk/groupchat_roster.py
Changes:
===================================== gajim/common/events.py ===================================== @@ -33,6 +33,7 @@ from nbxmpp.structs import RosterItem from nbxmpp.structs import TuneData from nbxmpp.const import InviteType +from nbxmpp.const import StatusCode
from gajim.common.file_props import FileProp from gajim.common.const import JingleState @@ -685,3 +686,35 @@ class MUCNicknameChanged(ApplicationEvent): new_name: str old_name: str timestamp: float + + +@dataclass +class MUCRoomConfigChanged(ApplicationEvent): + name: str = field(init=False, default='room-config-changed') + timestamp: float + status_codes: set[StatusCode] + + +@dataclass +class MUCRoomConfigFinished(ApplicationEvent): + name: str = field(init=False, default='room-config-finished') + timestamp: float + + +@dataclass +class MUCUserJoined(ApplicationEvent): + name: str = field(init=False, default='muc-user-joined') + timestamp: float + is_self: bool + nick: str + status_codes: Optional[set[StatusCode]] + + +@dataclass +class MUCUserLeft(ApplicationEvent): + name: str = field(init=False, default='muc-user-left') + timestamp: float + nick: str + status_codes: Optional[set[StatusCode]] + reason: Optional[str] + actor: Optional[str]
===================================== gajim/common/modules/contacts.py ===================================== @@ -15,11 +15,14 @@ from __future__ import annotations
from typing import Any +from typing import cast from typing import Iterator from typing import Optional from typing import Union from typing import overload
+import time + import cairo from nbxmpp.const import Affiliation from nbxmpp.const import Chatstate @@ -29,9 +32,11 @@ from nbxmpp.structs import DiscoInfo from nbxmpp.structs import LocationData from nbxmpp.structs import TuneData +from nbxmpp.structs import MessageProperties from nbxmpp.structs import MucSubject
from gajim.common import app +from gajim.common import events from gajim.common import types from gajim.common.const import PresenceShowExt from gajim.common.const import SimpleClientState @@ -933,12 +938,31 @@ def update_presence(self,
if not self._presence.available and presence.available: self._presence = presence - self.notify('user-joined', *args) + + properties = cast(MessageProperties, args[0]) + event = events.MUCUserJoined( + timestamp=time.time(), + is_self=properties.is_muc_self_presence, + nick=self.name, + status_codes=properties.muc_status_codes) + + app.storage.events.store(self, event) + self.notify('user-joined', event) return
if not presence.available: self._presence = presence - self.notify('user-left', *args) + + properties = cast(MessageProperties, args[0]) + event = events.MUCUserLeft( + timestamp=time.time(), + nick=self.name, + status_codes=properties.muc_status_codes, + reason=properties.muc_user.reason, + actor=properties.muc_user.actor) + + app.storage.events.store(self, event) + self.notify('user-left', event) return
signals: list[str] = []
===================================== gajim/common/modules/muc.py ===================================== @@ -44,11 +44,11 @@ from gi.repository import GLib
from gajim.common import app +from gajim.common import events from gajim.common import helpers from gajim.common import types from gajim.common.const import ClientState, KindConstant from gajim.common.const import MUCJoinedState -from gajim.common.events import MUCNicknameChanged from gajim.common.events import MessageModerated from gajim.common.events import MucAdded from gajim.common.events import MucDecline @@ -457,7 +457,11 @@ def _on_disco_result_after_config(self, task: Task) -> None: self._log.info('Configuration finished: %s', jid)
room = self._get_contact(jid.bare) - room.notify('room-config-finished') + event = events.MUCRoomConfigFinished(timestamp=time.time()) + + assert isinstance(room, GroupchatContact) + app.storage.events.store(room, event) + room.notify('room-config-finished', event)
def update_presence(self) -> None: mucs = self._get_mucs_with_state([MUCJoinedState.JOINED, @@ -587,14 +591,15 @@ def _on_muc_user_presence(self, presence = self._process_user_presence(properties) occupant.update_presence(presence, properties)
- event = MUCNicknameChanged(is_self=properties.is_self_presence, - new_name=new_occupant.name, - old_name=occupant.name, - timestamp=time.time()) + event = events.MUCNicknameChanged( + is_self=properties.is_self_presence, + new_name=new_occupant.name, + old_name=occupant.name, + timestamp=time.time())
app.storage.events.store(room, event)
- room.notify('user-nickname-changed', event) + room.notify('user-nickname-changed', event, occupant, new_occupant) return
is_joined = self._is_user_joined(properties.jid) @@ -894,12 +899,21 @@ def _on_config_change(self, if not properties.is_muc_config_change: return
- room_jid = str(properties.muc_jid) self._log.info('Received config change: %s %s', - room_jid, properties.muc_status_codes) + properties.muc_jid, properties.muc_status_codes)
- room = self._get_contact(room_jid) - room.notify('room-config-changed', properties) + assert properties.muc_status_codes is not None + event = events.MUCRoomConfigChanged( + timestamp=time.time(), + status_codes=properties.muc_status_codes) + + assert properties.muc_jid is not None + room = self._get_contact(properties.muc_jid) + + assert isinstance(room, GroupchatContact) + app.storage.events.store(room, event) + + room.notify('room-config-changed', event)
raise nbxmpp.NodeProcessed
===================================== gajim/common/storage/events.py ===================================== @@ -24,8 +24,8 @@ from collections import namedtuple
from nbxmpp.protocol import JID -from gajim.common.events import MUCNicknameChanged
+from gajim.common import events from gajim.common.storage.base import SqliteStorage from gajim.common.types import ChatContactT
@@ -43,6 +43,14 @@ PRAGMA user_version=1; '''
+EVENT_CLASSES: dict[str, Any] = { + 'muc-nickname-changed': events.MUCNicknameChanged, + 'room-config-changed': events.MUCRoomConfigChanged, + 'room-config-finished': events.MUCRoomConfigFinished, + 'muc-user-joined': events.MUCUserJoined, + 'muc-user-left': events.MUCUserLeft, +} + log = logging.getLogger('gajim.c.storage.events')
@@ -113,4 +121,5 @@ def load(self, for row in self._con.execute(insert_sql, (contact.account, contact.jid, timestamp)).fetchall(): - yield MUCNicknameChanged(**row.data, timestamp=row.timestamp) + event_class = EVENT_CLASSES[row.event] + yield event_class(**row.data, timestamp=row.timestamp)
===================================== gajim/gtk/chat_stack.py ===================================== @@ -297,8 +297,9 @@ def _on_user_joined(self, contact: GroupchatContact, _signal_name: str, _user_contact: GroupchatParticipant, - _properties: PresenceProperties + _event: events.MUCUserJoined ) -> None: + self._update_group_chat_actions(contact)
def _on_user_role_changed(self,
===================================== gajim/gtk/control.py ===================================== @@ -628,6 +628,10 @@ def _fetch_n_lines_history(self, # self._scrolled_view.set_history_complete(before, False)
for row in app.storage.events.load(self._contact, before, timestamp): + if isinstance(row, (events.MUCUserJoined, events.MUCUserLeft)): + self._process_join_left_event(row) + continue + self._process_event(row)
self._scrolled_view.block_signals(False) @@ -716,16 +720,17 @@ def add_message(self, def _on_user_nickname_changed(self, contact: types.GroupchatContact, _signal_name: str, - # old_contact: types.GroupchatParticipant, - # new_contact: types.GroupchatParticipant, - # properties: PresenceProperties + _old_contact: types.GroupchatParticipant, + _new_contact: types.GroupchatParticipant, event: events.MUCNicknameChanged ) -> None:
self._process_event(event)
- def _process_event(self, event) -> None: - if event == 'muc-nickname-changed': + def _process_event(self, event: Any) -> None: + message = None + + if isinstance(event, events.MUCNicknameChanged): if event.is_self: message = _('You are now known as %s') % event.new_name else: @@ -733,7 +738,129 @@ def _process_event(self, event) -> None: 'as {new_nick}').format(nick=event.old_name, new_nick=event.new_name)
- self.add_info_message(message, event.timestamp) + if isinstance(event, events.MUCRoomConfigChanged): + # http://www.xmpp.org/extensions/xep-0045.html#roomconfig-notify + status_codes = event.status_codes + changes: list[str] = [] + if StatusCode.SHOWING_UNAVAILABLE in status_codes: + changes.append(_('Group chat now shows unavailable members')) + + if StatusCode.NOT_SHOWING_UNAVAILABLE in status_codes: + changes.append(_('Group chat now does not show ' + 'unavailable members')) + + if StatusCode.CONFIG_NON_PRIVACY_RELATED in status_codes: + changes.append(_('A setting not related to privacy has been ' + 'changed')) + self.client.get_module('Discovery').disco_muc(self.contact.jid) + + if StatusCode.CONFIG_ROOM_LOGGING in status_codes: + # Can be a presence + # (see chg_contact_status in groupchat_control.py) + changes.append(_('Conversations are stored on the server')) + + if StatusCode.CONFIG_NO_ROOM_LOGGING in status_codes: + changes.append(_('Conversations are not stored on the server')) + + if StatusCode.CONFIG_NON_ANONYMOUS in status_codes: + changes.append(_('Group chat is now non-anonymous')) + + if StatusCode.CONFIG_SEMI_ANONYMOUS in status_codes: + changes.append(_('Group chat is now semi-anonymous')) + + if StatusCode.CONFIG_FULL_ANONYMOUS in status_codes: + changes.append(_('Group chat is now fully anonymous')) + + for message in changes: + self.add_info_message(message, event.timestamp) + return + + if isinstance(event, events.MUCRoomConfigFinished): + message = _('A new group chat has been created') + + if message is not None: + self.add_info_message(message, event.timestamp) + + def _process_join_left_event(self, + event: Any + ) -> None: + + message = None + + if isinstance(event, events.MUCUserJoined): + assert isinstance(self.contact, GroupchatContact) + + if not event.is_self: + if self.contact.is_joined: + self.conversation_view.add_muc_user_joined(event.nick) + return + + status_codes = event.status_codes or [] + + if not self.contact.is_joined: + # We just joined the room + message = _('You (%s) joined the group chat') % event.nick + + if StatusCode.NON_ANONYMOUS in status_codes: + message = _('Any participant is allowed to see your full ' + 'XMPP Address') + + if StatusCode.CONFIG_ROOM_LOGGING in status_codes: + message = _('Conversations are stored on the server') + + if StatusCode.NICKNAME_MODIFIED in status_codes: + message = _('The server has assigned or modified your ' + 'nickname in this group chat') + + if isinstance(event, events.MUCUserLeft): + status_codes = event.status_codes or [] + nick = event.nick + + reason = event.reason + reason = '' if reason is None else f': {reason}' + + actor = event.actor + # Group Chat: You have been kicked by Alice + actor = '' if actor is None else _(' by {actor}').format( + actor=actor) + + # Group Chat: We have been removed from the room + message = _('{nick} has been removed from the group ' + 'chat{by}{reason}') + + if StatusCode.REMOVED_ERROR in status_codes: + # Handle 333 before 307, some MUCs add both + self.conversation_view.add_muc_user_left( + nick, event.reason, error=True) + + elif StatusCode.REMOVED_KICKED in status_codes: + # Group Chat: User was kicked by Alice: reason + message = _('{nick} has been ' + 'kicked{actor}{reason}').format(nick=nick, + actor=actor, + reason=reason) + + elif StatusCode.REMOVED_BANNED in status_codes: + # Group Chat: User was banned by Alice: reason + message = _('{nick} has been ' + 'banned{actor}{reason}').format(nick=nick, + actor=actor, + reason=reason) + + elif StatusCode.REMOVED_AFFILIATION_CHANGE in status_codes: + reason = _(': Affiliation changed') + message = message.format(nick=nick, by=actor, reason=reason) + + elif StatusCode.REMOVED_NONMEMBER_IN_MEMBERS_ONLY in status_codes: + reason = _(': Group chat configuration changed to members-only') + message = message.format(nick=nick, by=actor, reason=reason) + + else: + self.conversation_view.add_muc_user_left(nick, event.reason) + return + + if message is not None: + self.add_info_message(message, event.timestamp)
def _on_muc_user_status_show_changed(self, contact: GroupchatContact, @@ -857,84 +984,29 @@ def _on_room_subject(self, def _on_room_config_changed(self, _contact: GroupchatContact, _signal_name: str, - properties: MessageProperties + event: events.MUCRoomConfigChanged ) -> None: - # http://www.xmpp.org/extensions/xep-0045.html#roomconfig-notify - - status_codes = properties.muc_status_codes - assert status_codes is not None - - changes: list[str] = [] - if StatusCode.SHOWING_UNAVAILABLE in status_codes: - changes.append(_('Group chat now shows unavailable members')) - - if StatusCode.NOT_SHOWING_UNAVAILABLE in status_codes: - changes.append(_('Group chat now does not show ' - 'unavailable members')) - - if StatusCode.CONFIG_NON_PRIVACY_RELATED in status_codes: - changes.append(_('A setting not related to privacy has been ' - 'changed')) - self.client.get_module('Discovery').disco_muc(self.contact.jid) - - if StatusCode.CONFIG_ROOM_LOGGING in status_codes: - # Can be a presence (see chg_contact_status in groupchat_control.py) - changes.append(_('Conversations are stored on the server')) - - if StatusCode.CONFIG_NO_ROOM_LOGGING in status_codes: - changes.append(_('Conversations are not stored on the server')) - - if StatusCode.CONFIG_NON_ANONYMOUS in status_codes: - changes.append(_('Group chat is now non-anonymous')) - - if StatusCode.CONFIG_SEMI_ANONYMOUS in status_codes: - changes.append(_('Group chat is now semi-anonymous'))
- if StatusCode.CONFIG_FULL_ANONYMOUS in status_codes: - changes.append(_('Group chat is now fully anonymous')) - - for change in changes: - self.add_info_message(change) + self._process_event(event)
def rejoin(self) -> None: self.client.get_module('MUC').join(self.contact.jid)
def _on_user_joined(self, - contact: GroupchatContact, + _contact: GroupchatContact, _signal_name: str, - user_contact: GroupchatParticipant, - properties: PresenceProperties + _user_contact: GroupchatParticipant, + event: events.MUCUserJoined ) -> None:
- nick = user_contact.name - if not properties.is_muc_self_presence: - if contact.is_joined: - self.conversation_view.add_muc_user_joined(nick) - return - - status_codes = properties.muc_status_codes or [] - - if not contact.is_joined: - # We just joined the room - self.add_info_message(_('You (%s) joined the group chat') % nick) - - if StatusCode.NON_ANONYMOUS in status_codes: - self.add_info_message( - _('Any participant is allowed to see your full XMPP Address')) - - if StatusCode.CONFIG_ROOM_LOGGING in status_codes: - self.add_info_message(_('Conversations are stored on the server')) - - if StatusCode.NICKNAME_MODIFIED in status_codes: - self.add_info_message( - _('The server has assigned or modified your nickname in this ' - 'group chat')) + self._process_join_left_event(event)
def _on_room_config_finished(self, _contact: GroupchatContact, - _signal_name: str + _signal_name: str, + event: events.MUCRoomConfigFinished ) -> None: - self.add_info_message(_('A new group chat has been created')) + self._process_event(event)
def _on_user_affiliation_changed(self, _contact: GroupchatContact, @@ -1060,57 +1132,11 @@ def _on_room_kicked(self, def _on_user_left(self, _contact: GroupchatContact, _signal_name: str, - user_contact: GroupchatParticipant, - properties: MessageProperties + _user_contact: GroupchatParticipant, + event: events.MUCUserLeft ) -> None: - status_codes = properties.muc_status_codes or [] - nick = user_contact.name - - assert properties.muc_user is not None - reason = properties.muc_user.reason - reason = '' if reason is None else f': {reason}' - - actor = properties.muc_user.actor - # Group Chat: You have been kicked by Alice - actor = '' if actor is None else _(' by {actor}').format(actor=actor) - - # Group Chat: We have been removed from the room - message = _('{nick} has been removed from the group chat{by}{reason}')
- if StatusCode.REMOVED_ERROR in status_codes: - # Handle 333 before 307, some MUCs add both - self.conversation_view.add_muc_user_left( - nick, properties.muc_user.reason, error=True) - - elif StatusCode.REMOVED_KICKED in status_codes: - # Group Chat: User was kicked by Alice: reason - message = _('{nick} has been ' - 'kicked{actor}{reason}').format(nick=nick, - actor=actor, - reason=reason) - self.add_info_message(message) - - elif StatusCode.REMOVED_BANNED in status_codes: - # Group Chat: User was banned by Alice: reason - message = _('{nick} has been ' - 'banned{actor}{reason}').format(nick=nick, - actor=actor, - reason=reason) - self.add_info_message(message) - - elif StatusCode.REMOVED_AFFILIATION_CHANGE in status_codes: - reason = _(': Affiliation changed') - message = message.format(nick=nick, by=actor, reason=reason) - self.add_info_message(message) - - elif StatusCode.REMOVED_NONMEMBER_IN_MEMBERS_ONLY in status_codes: - reason = _(': Group chat configuration changed to members-only') - message = message.format(nick=nick, by=actor, reason=reason) - self.add_info_message(message) - - else: - self.conversation_view.add_muc_user_left( - nick, properties.muc_user.reason) + self._process_join_left_event(event)
def _on_room_presence_error(self, _contact: GroupchatContact,
===================================== gajim/gtk/conversation/view.py ===================================== @@ -176,7 +176,7 @@ def add_muc_subject(self,
def add_muc_user_left(self, nick: str, - reason: str, + reason: Optional[str], error: bool = False) -> None: assert isinstance(self._contact, GroupchatContact) if not self._contact.settings.get('print_join_left'):
===================================== gajim/gtk/groupchat_nick_completion.py ===================================== @@ -18,7 +18,6 @@
import logging
-from nbxmpp.structs import PresenceProperties
from gi.repository import Gtk from gi.repository import Gdk @@ -27,6 +26,7 @@ from gajim.common import ged from gajim.common import types from gajim.common.events import GcMessageReceived +from gajim.common.events import MUCNicknameChanged from gajim.common.ged import EventHelper from gajim.common.helpers import jid_is_blocked from gajim.common.helpers import message_needs_highlight @@ -70,18 +70,18 @@ def switch_contact(self, contact: types.GroupchatContactT) -> None:
self._account = contact.account self._contact = contact - # self._contact.connect( - # 'user-nickname-changed', self._on_user_nickname_changed) + self._contact.connect( + 'user-nickname-changed', self._on_user_nickname_changed)
def _on_user_nickname_changed(self, _contact: types.GroupchatContact, _signal_name: str, + event: MUCNicknameChanged, old_contact: types.GroupchatParticipant, - new_contact: types.GroupchatParticipant, - properties: PresenceProperties + new_contact: types.GroupchatParticipant ) -> None:
- if properties.is_muc_self_presence: + if event.is_self: return
old_name = old_contact.name
===================================== gajim/gtk/groupchat_roster.py ===================================== @@ -25,7 +25,6 @@ from gi.repository import Gtk from gi.repository import GLib from nbxmpp.const import Affiliation -from nbxmpp.structs import PresenceProperties
from gajim.common import app from gajim.common import ged @@ -36,6 +35,7 @@ from gajim.common.const import AvatarSize from gajim.common.const import StyleAttr from gajim.common.events import ApplicationEvent +from gajim.common.events import MUCNicknameChanged from gajim.common.modules.contacts import GroupchatContact
from .menus import get_groupchat_roster_menu @@ -283,9 +283,9 @@ def _update_contact(self, def _on_user_nickname_changed(self, contact: types.GroupchatContact, _signal_name: str, + _event: MUCNicknameChanged, old_contact: types.GroupchatParticipant, - new_contact: types.GroupchatParticipant, - properties: PresenceProperties + new_contact: types.GroupchatParticipant ) -> None:
self._remove_contact(old_contact) @@ -500,7 +500,7 @@ def _load_roster(self) -> None: 'user-avatar-update': self._on_user_avatar_update, 'user-joined': self._on_user_joined, 'user-left': self._on_user_left, - # 'user-nickname-changed': self._on_user_nickname_changed, + 'user-nickname-changed': self._on_user_nickname_changed, 'user-role-changed': self._update_contact, 'user-status-show-changed': self._on_user_status_show_changed, })
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/commit/8af47b1b53332370dba67902d88575c2f...