From 14f088c2d91c7748bc938b6980392369720c4b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Thu, 5 Jul 2018 18:52:43 +0200 Subject: [PATCH] Refactor UserMood into own module --- gajim/common/connection.py | 2 + gajim/common/connection_handlers.py | 26 ------ gajim/common/const.py | 106 ++++++++++++++++++++++- gajim/common/modules/user_mood.py | 88 +++++++++++++++++++ gajim/common/pep.py | 126 ---------------------------- gajim/dialogs.py | 13 +-- gajim/gtkgui_helpers.py | 7 +- gajim/gui_interface.py | 7 +- gajim/roster_window.py | 4 +- 9 files changed, 211 insertions(+), 168 deletions(-) create mode 100644 gajim/common/modules/user_mood.py diff --git a/gajim/common/connection.py b/gajim/common/connection.py index 2de15bb0f..7f134bb42 100644 --- a/gajim/common/connection.py +++ b/gajim/common/connection.py @@ -80,6 +80,7 @@ from gajim.common.modules.pep import PEP from gajim.common.modules.user_avatar import UserAvatar from gajim.common.modules.user_activity import UserActivity from gajim.common.modules.user_tune import UserTune +from gajim.common.modules.user_mood import UserMood from gajim.common.connection_handlers import * from gajim.common.contacts import GC_Contact from gajim.gtkgui_helpers import get_action @@ -676,6 +677,7 @@ class Connection(CommonConnection, ConnectionHandlers): self.register_module('UserAvatar', UserAvatar, self) self.register_module('UserActivity', UserActivity, self) self.register_module('UserTune', UserTune, self) + self.register_module('UserMood', UserMood, self) app.ged.register_event_handler('privacy-list-received', ged.CORE, self._nec_privacy_list_received) diff --git a/gajim/common/connection_handlers.py b/gajim/common/connection_handlers.py index 1ce8ba741..d5c05a31e 100644 --- a/gajim/common/connection_handlers.py +++ b/gajim/common/connection_handlers.py @@ -295,7 +295,6 @@ class ConnectionPEP(object): self._account = new_name def reset_awaiting_pep(self): - self.to_be_sent_mood = None self.to_be_sent_nick = None self.to_be_sent_location = None @@ -303,37 +302,12 @@ class ConnectionPEP(object): """ Send pep info that were waiting for connection """ - if self.to_be_sent_mood: - self.send_mood(*self.to_be_sent_mood) if self.to_be_sent_nick: self.send_nick(self.to_be_sent_nick) if self.to_be_sent_location: self.send_location(self.to_be_sent_location) self.reset_awaiting_pep() - def send_mood(self, mood, message=None): - if self.connected == 1: - # We are connecting, keep mood in mem and send it when we'll be - # connected - self.to_be_sent_mood = (mood, message) - return - if not self.pep_supported: - return - item = nbxmpp.Node('mood', {'xmlns': nbxmpp.NS_MOOD}) - if mood: - item.addChild(mood) - if message: - i = item.addChild('text') - i.addData(message) - self.get_module('PubSub').send_pb_publish('', nbxmpp.NS_MOOD, item, '0') - - def retract_mood(self): - if not self.pep_supported: - return - self.send_mood(None) - # not all client support new XEP, so we still retract - self.get_module('PubSub').send_pb_retract('', nbxmpp.NS_MOOD, '0') - def send_nickname(self, nick): if self.connected == 1: # We are connecting, keep nick in mem and send it when we'll be diff --git a/gajim/common/const.py b/gajim/common/const.py index e17331604..40dedafcd 100644 --- a/gajim/common/const.py +++ b/gajim/common/const.py @@ -4,6 +4,7 @@ from collections import namedtuple Option = namedtuple('Option', 'kind label type value name callback data desc enabledif props') Option.__new__.__defaults__ = (None,) * len(Option._fields) + @unique class OptionKind(IntEnum): ENTRY = 0 @@ -20,6 +21,7 @@ class OptionKind(IntEnum): CHANGEPASSWORD = 11 GPG = 12 + @unique class OptionType(IntEnum): ACCOUNT_CONFIG = 0 @@ -28,6 +30,7 @@ class OptionType(IntEnum): ACTION = 3 DIALOG = 4 + class AvatarSize(IntEnum): TAB = 16 ROSTER = 32 @@ -37,22 +40,26 @@ class AvatarSize(IntEnum): VCARD = 200 PUBLISH = 200 + class ArchiveState(IntEnum): NEVER = 0 ALL = 1 + @unique class PathLocation(IntEnum): CONFIG = 0 CACHE = 1 DATA = 2 + @unique class PathType(IntEnum): FILE = 0 FOLDER = 1 FOLDER_OPTIONAL = 2 + @unique class KindConstant(IntEnum): STATUS = 0 @@ -67,6 +74,7 @@ class KindConstant(IntEnum): def __str__(self): return str(self.value) + @unique class ShowConstant(IntEnum): ONLINE = 0 @@ -76,6 +84,7 @@ class ShowConstant(IntEnum): DND = 4 OFFLINE = 5 + @unique class TypeConstant(IntEnum): AIM = 0 @@ -94,6 +103,7 @@ class TypeConstant(IntEnum): MRIM = 13 NO_TRANSPORT = 14 + @unique class SubscriptionConstant(IntEnum): NONE = 0 @@ -101,11 +111,13 @@ class SubscriptionConstant(IntEnum): FROM = 2 BOTH = 3 + @unique class JIDConstant(IntEnum): NORMAL_TYPE = 0 ROOM_TYPE = 1 + @unique class IdleState(IntEnum): UNKNOWN = 0 @@ -113,26 +125,31 @@ class IdleState(IntEnum): AWAY = 2 AWAKE = 3 + @unique class RequestAvatar(IntEnum): SELF = 0 ROOM = 1 USER = 2 + @unique class BookmarkStorageType(IntEnum): PRIVATE = 0 PUBSUB = 1 + @unique class PEPHandlerType(IntEnum): NOTIFY = 0 RETRACT = 1 + @unique class PEPEventType(IntEnum): ACTIVITY = 0 TUNE = 1 + MOOD = 2 ACTIVITIES = { @@ -226,6 +243,93 @@ ACTIVITIES = { 'studying': _('Studying'), 'writing': _('Writing')}} +MOODS = { + 'afraid': _('Afraid'), + 'amazed': _('Amazed'), + 'amorous': _('Amorous'), + 'angry': _('Angry'), + 'annoyed': _('Annoyed'), + 'anxious': _('Anxious'), + 'aroused': _('Aroused'), + 'ashamed': _('Ashamed'), + 'bored': _('Bored'), + 'brave': _('Brave'), + 'calm': _('Calm'), + 'cautious': _('Cautious'), + 'cold': _('Cold'), + 'confident': _('Confident'), + 'confused': _('Confused'), + 'contemplative': _('Contemplative'), + 'contented': _('Contented'), + 'cranky': _('Cranky'), + 'crazy': _('Crazy'), + 'creative': _('Creative'), + 'curious': _('Curious'), + 'dejected': _('Dejected'), + 'depressed': _('Depressed'), + 'disappointed': _('Disappointed'), + 'disgusted': _('Disgusted'), + 'dismayed': _('Dismayed'), + 'distracted': _('Distracted'), + 'embarrassed': _('Embarrassed'), + 'envious': _('Envious'), + 'excited': _('Excited'), + 'flirtatious': _('Flirtatious'), + 'frustrated': _('Frustrated'), + 'grateful': _('Grateful'), + 'grieving': _('Grieving'), + 'grumpy': _('Grumpy'), + 'guilty': _('Guilty'), + 'happy': _('Happy'), + 'hopeful': _('Hopeful'), + 'hot': _('Hot'), + 'humbled': _('Humbled'), + 'humiliated': _('Humiliated'), + 'hungry': _('Hungry'), + 'hurt': _('Hurt'), + 'impressed': _('Impressed'), + 'in_awe': _('In Awe'), + 'in_love': _('In Love'), + 'indignant': _('Indignant'), + 'interested': _('Interested'), + 'intoxicated': _('Intoxicated'), + 'invincible': _('Invincible'), + 'jealous': _('Jealous'), + 'lonely': _('Lonely'), + 'lost': _('Lost'), + 'lucky': _('Lucky'), + 'mean': _('Mean'), + 'moody': _('Moody'), + 'nervous': _('Nervous'), + 'neutral': _('Neutral'), + 'offended': _('Offended'), + 'outraged': _('Outraged'), + 'playful': _('Playful'), + 'proud': _('Proud'), + 'relaxed': _('Relaxed'), + 'relieved': _('Relieved'), + 'remorseful': _('Remorseful'), + 'restless': _('Restless'), + 'sad': _('Sad'), + 'sarcastic': _('Sarcastic'), + 'satisfied': _('Satisfied'), + 'serious': _('Serious'), + 'shocked': _('Shocked'), + 'shy': _('Shy'), + 'sick': _('Sick'), + 'sleepy': _('Sleepy'), + 'spontaneous': _('Spontaneous'), + 'stressed': _('Stressed'), + 'strong': _('Strong'), + 'surprised': _('Surprised'), + 'thankful': _('Thankful'), + 'thirsty': _('Thirsty'), + 'tired': _('Tired'), + 'undefined': _('Undefined'), + 'weak': _('Weak'), + 'worried': _('Worried') +} + SSLError = { 2: _("Unable to get issuer certificate"), @@ -260,7 +364,7 @@ SSLError = { 31: _("Authority and issuer serial number mismatch"), 32: _("Key usage does not include certificate signing"), 50: _("Application verification failure"), - } +} THANKS = u"""\ diff --git a/gajim/common/modules/user_mood.py b/gajim/common/modules/user_mood.py new file mode 100644 index 000000000..f4f4cc968 --- /dev/null +++ b/gajim/common/modules/user_mood.py @@ -0,0 +1,88 @@ +# This file is part of Gajim. +# +# Gajim is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation; version 3 only. +# +# Gajim is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Gajim. If not, see . + +# XEP-0107: User Mood + +import logging + +import nbxmpp +from gi.repository import GLib + +from gajim.common.const import PEPEventType, MOODS +from gajim.common.exceptions import StanzaMalformed +from gajim.common.modules.pep import AbstractPEPModule, AbstractPEPData + +log = logging.getLogger('gajim.c.m.user_mood') + + +class UserMoodData(AbstractPEPData): + + type_ = PEPEventType.MOOD + + def __init__(self, mood): + self._pep_specific_data = mood + + def asMarkupText(self): + mood = self._translate_mood(self._pep_specific_data['mood']) + markuptext = '%s' % GLib.markup_escape_text(mood) + if 'text' in self._pep_specific_data: + text = self._pep_specific_data['text'] + markuptext += ' (%s)' % GLib.markup_escape_text(text) + return markuptext + + def _translate_mood(self, mood): + if mood in MOODS: + return MOODS[mood] + else: + return mood + + +class UserMood(AbstractPEPModule): + + name = 'mood' + namespace = nbxmpp.NS_MOOD + pep_class = UserMoodData + store_publish = True + _log = log + + def __init__(self, con): + AbstractPEPModule.__init__(self, con, con.name) + + self.handlers = [] + + def _extract_info(self, item): + mood_dict = {} + mood_tag = item.getTag('mood', namespace=nbxmpp.NS_MOOD) + if mood_tag is None: + raise StanzaMalformed('No mood node') + + for child in mood_tag.getChildren(): + name = child.getName().strip() + if name == 'text': + mood_dict['text'] = child.getData() + else: + mood_dict['mood'] = name + + return mood_dict or None + + def _build_node(self, data): + item = nbxmpp.Node('mood', {'xmlns': nbxmpp.NS_MOOD}) + if data is None: + return + mood, text = data + if mood: + item.addChild(mood) + if text: + item.addChild('text', payload=text) + return item diff --git a/gajim/common/pep.py b/gajim/common/pep.py index a250a4006..e5dd9e0d5 100644 --- a/gajim/common/pep.py +++ b/gajim/common/pep.py @@ -23,92 +23,6 @@ ## along with Gajim. If not, see . ## -MOODS = { - 'afraid': _('Afraid'), - 'amazed': _('Amazed'), - 'amorous': _('Amorous'), - 'angry': _('Angry'), - 'annoyed': _('Annoyed'), - 'anxious': _('Anxious'), - 'aroused': _('Aroused'), - 'ashamed': _('Ashamed'), - 'bored': _('Bored'), - 'brave': _('Brave'), - 'calm': _('Calm'), - 'cautious': _('Cautious'), - 'cold': _('Cold'), - 'confident': _('Confident'), - 'confused': _('Confused'), - 'contemplative': _('Contemplative'), - 'contented': _('Contented'), - 'cranky': _('Cranky'), - 'crazy': _('Crazy'), - 'creative': _('Creative'), - 'curious': _('Curious'), - 'dejected': _('Dejected'), - 'depressed': _('Depressed'), - 'disappointed': _('Disappointed'), - 'disgusted': _('Disgusted'), - 'dismayed': _('Dismayed'), - 'distracted': _('Distracted'), - 'embarrassed': _('Embarrassed'), - 'envious': _('Envious'), - 'excited': _('Excited'), - 'flirtatious': _('Flirtatious'), - 'frustrated': _('Frustrated'), - 'grateful': _('Grateful'), - 'grieving': _('Grieving'), - 'grumpy': _('Grumpy'), - 'guilty': _('Guilty'), - 'happy': _('Happy'), - 'hopeful': _('Hopeful'), - 'hot': _('Hot'), - 'humbled': _('Humbled'), - 'humiliated': _('Humiliated'), - 'hungry': _('Hungry'), - 'hurt': _('Hurt'), - 'impressed': _('Impressed'), - 'in_awe': _('In Awe'), - 'in_love': _('In Love'), - 'indignant': _('Indignant'), - 'interested': _('Interested'), - 'intoxicated': _('Intoxicated'), - 'invincible': _('Invincible'), - 'jealous': _('Jealous'), - 'lonely': _('Lonely'), - 'lost': _('Lost'), - 'lucky': _('Lucky'), - 'mean': _('Mean'), - 'moody': _('Moody'), - 'nervous': _('Nervous'), - 'neutral': _('Neutral'), - 'offended': _('Offended'), - 'outraged': _('Outraged'), - 'playful': _('Playful'), - 'proud': _('Proud'), - 'relaxed': _('Relaxed'), - 'relieved': _('Relieved'), - 'remorseful': _('Remorseful'), - 'restless': _('Restless'), - 'sad': _('Sad'), - 'sarcastic': _('Sarcastic'), - 'satisfied': _('Satisfied'), - 'serious': _('Serious'), - 'shocked': _('Shocked'), - 'shy': _('Shy'), - 'sick': _('Sick'), - 'sleepy': _('Sleepy'), - 'spontaneous': _('Spontaneous'), - 'stressed': _('Stressed'), - 'strong': _('Strong'), - 'surprised': _('Surprised'), - 'thankful': _('Thankful'), - 'thirsty': _('Thirsty'), - 'tired': _('Tired'), - 'undefined': _('Undefined'), - 'weak': _('Weak'), - 'worried': _('Worried')} - LOCATION_DATA = { 'accuracy': _('accuracy'), 'alt': _('alt'), @@ -193,45 +107,6 @@ class AbstractPEP(object): pass -class UserMoodPEP(AbstractPEP): - '''XEP-0107: User Mood''' - - type_ = 'mood' - namespace = nbxmpp.NS_MOOD - - def _extract_info(self, items): - mood_dict = {} - - for item in items.getTags('item'): - mood_tag = item.getTag('mood') - if mood_tag: - for child in mood_tag.getChildren(): - name = child.getName().strip() - if name == 'text': - mood_dict['text'] = child.getData() - else: - mood_dict['mood'] = name - - retracted = items.getTag('retract') or not 'mood' in mood_dict - return (mood_dict, retracted) - - def asMarkupText(self): - assert not self._retracted - untranslated_mood = self._pep_specific_data['mood'] - mood = self._translate_mood(untranslated_mood) - markuptext = '%s' % GLib.markup_escape_text(mood) - if 'text' in self._pep_specific_data: - text = self._pep_specific_data['text'] - markuptext += ' (%s)' % GLib.markup_escape_text(text) - return markuptext - - def _translate_mood(self, mood): - if mood in MOODS: - return MOODS[mood] - else: - return mood - - class UserNicknamePEP(AbstractPEP): '''XEP-0172: User Nickname''' @@ -347,5 +222,4 @@ class AvatarNotificationPEP(AbstractPEP): SUPPORTED_PERSONAL_USER_EVENTS = [ - UserMoodPEP, UserNicknamePEP, UserLocationPEP, AvatarNotificationPEP] diff --git a/gajim/dialogs.py b/gajim/dialogs.py index 8085a5dfc..b7ad8b760 100644 --- a/gajim/dialogs.py +++ b/gajim/dialogs.py @@ -52,6 +52,7 @@ from gajim.common import ged from gajim.common import const from gajim.options_dialog import OptionsDialog from gajim.common.const import Option, OptionKind, OptionType, ACTIVITIES +from gajim.common.const import MOODS from gajim.common import app from gajim.common import helpers @@ -505,7 +506,7 @@ class ChangeMoodDialog: # Order them first self.MOODS = [] - for mood in pep.MOODS: + for mood in MOODS: self.MOODS.append(mood) self.MOODS.sort() @@ -515,7 +516,7 @@ class ChangeMoodDialog: self.mood_buttons[mood].set_mode(False) self.mood_buttons[mood].add(gtkgui_helpers.load_mood_icon(mood)) self.mood_buttons[mood].set_relief(Gtk.ReliefStyle.NONE) - self.mood_buttons[mood].set_tooltip_text(pep.MOODS[mood]) + self.mood_buttons[mood].set_tooltip_text(MOODS[mood]) self.mood_buttons[mood].connect('clicked', self.on_mood_button_clicked, mood) table.attach(self.mood_buttons[mood], x, y, 1, 1) @@ -526,9 +527,9 @@ class ChangeMoodDialog: x = 0 y += 1 - if self.mood in pep.MOODS: + if self.mood in MOODS: self.mood_buttons[self.mood].set_active(True) - self.label.set_text(pep.MOODS[self.mood]) + self.label.set_text(MOODS[self.mood]) self.entry.set_sensitive(True) if self.text: self.entry.set_text(self.text) @@ -543,7 +544,7 @@ class ChangeMoodDialog: def on_mood_button_clicked(self, widget, data): if data: - self.label.set_text(pep.MOODS[data]) + self.label.set_text(MOODS[data]) self.entry.set_sensitive(True) else: self.label.set_text(_('None')) @@ -705,7 +706,7 @@ class ChangeStatusMessageDialog(TimeoutDialog): """ img = self.xml.get_object('mood_image') label = self.xml.get_object('mood_button_label') - if 'mood' in self.pep_dict and self.pep_dict['mood'] in pep.MOODS: + if 'mood' in self.pep_dict and self.pep_dict['mood'] in MOODS: img.set_from_pixbuf(gtkgui_helpers.load_mood_icon( self.pep_dict['mood']).get_pixbuf()) if self.pep_dict['mood_text']: diff --git a/gajim/gtkgui_helpers.py b/gajim/gtkgui_helpers.py index 6ffd59b17..d0e41c2f5 100644 --- a/gajim/gtkgui_helpers.py +++ b/gajim/gtkgui_helpers.py @@ -52,7 +52,7 @@ from gajim.common import i18n from gajim.common import app from gajim.common import pep from gajim.common import configpaths -from gajim.common.const import PEPEventType, ACTIVITIES +from gajim.common.const import PEPEventType, ACTIVITIES, MOODS from gajim.filechoosers import AvatarSaveDialog gtk_icon_theme = Gtk.IconTheme.get_default() @@ -623,10 +623,9 @@ def load_activity_icon(category, activity = None): return icon_list[activity] def get_pep_as_pixbuf(pep_class): - if isinstance(pep_class, pep.UserMoodPEP): - assert not pep_class._retracted + if pep_class == PEPEventType.MOOD: received_mood = pep_class._pep_specific_data['mood'] - mood = received_mood if received_mood in pep.MOODS else 'unknown' + mood = received_mood if received_mood in MOODS else 'unknown' pixbuf = load_mood_icon(mood).get_pixbuf() return pixbuf elif pep_class == PEPEventType.TUNE: diff --git a/gajim/gui_interface.py b/gajim/gui_interface.py index db4d84519..cd12c1746 100644 --- a/gajim/gui_interface.py +++ b/gajim/gui_interface.py @@ -99,7 +99,8 @@ from gajim.common.connection import Connection from gajim.common.file_props import FilesProp from gajim.common import pep from gajim import emoticons -from gajim.common.const import AvatarSize, SSLError, PEPEventType, ACTIVITIES +from gajim.common.const import AvatarSize, SSLError, PEPEventType +from gajim.common.const import ACTIVITIES, MOODS from gajim import roster_window from gajim import profile_window @@ -2474,9 +2475,9 @@ class Interface: @staticmethod def get_pep_icon(pep_obj): - if isinstance(pep_obj, pep.UserMoodPEP): + if pep_obj == PEPEventType.MOOD: received_mood = pep_obj._pep_specific_data['mood'] - mood = received_mood if received_mood in pep.MOODS else 'unknown' + mood = received_mood if received_mood in MOODS else 'unknown' return gtkgui_helpers.load_mood_icon(mood).get_pixbuf() elif pep_obj == PEPEventType.TUNE: path = os.path.join( diff --git a/gajim/roster_window.py b/gajim/roster_window.py index ed98b4573..f928b2abc 100644 --- a/gajim/roster_window.py +++ b/gajim/roster_window.py @@ -2107,9 +2107,9 @@ class RosterWindow: if 'mood' in pep_dict: mood = pep_dict['mood'] mood_text = pep_dict.get('mood_text', None) - connection.send_mood(mood, mood_text) + connection.get_module('UserMood').send((mood, mood_text)) else: - connection.retract_mood() + connection.get_module('UserMood').retract() def delete_pep(self, jid, account): if jid == app.get_jid_from_account(account):