diff --git a/frontends/src/constants.py b/frontends/src/constants.py
deleted file mode 100644
index e3cd3dfb..00000000
--- a/frontends/src/constants.py
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# generic module for SàT frontends
-# Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Jérôme Poisson (goffi@goffi.org)
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program 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 Affero General Public License for more details.
-
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-
-
-from sat.core import constants
-from sat.core.i18n import _, D_
-from collections import OrderedDict # only available from python 2.7
-
-
-def getPresence():
- """We cannot do it directly in the Const class, if it is not encapsulated
- in a method we get a JS runtime SyntaxError: "missing ) in parenthetical".
- # TODO: merge this definition with those in primitivus.constants
- """
-
-
-class Const(constants.Const):
-
- PRESENCE = OrderedDict([("", _("Online")),
- ("chat", _("Free for chat")),
- ("away", _("Away from keyboard")),
- ("dnd", _("Do not disturb")),
- ("xa", _("Extended away"))])
-
- # from plugin_misc_text_syntaxes
- SYNTAX_XHTML = "XHTML"
- SYNTAX_CURRENT = "@CURRENT@"
- SYNTAX_TEXT = "text"
-
- # XMLUI
- SAT_FORM_PREFIX = "SAT_FORM_"
- SAT_PARAM_SEPARATOR = "_XMLUI_PARAM_" # used to have unique elements names
- XMLUI_STATUS_VALIDATED = "validated"
- XMLUI_STATUS_CANCELLED = constants.Const.XMLUI_DATA_CANCELLED
-
- # MUC
- ALL_OCCUPANTS = 1
- MUC_USER_STATES = {
- "active": u'✔',
- "inactive": u'☄',
- "gone": u'✈',
- "composing": u'✎',
- "paused": u"⦷"
- }
-
- # Roster
- GROUP_NOT_IN_ROSTER = D_('Not in roster')
-
- # Chats
- CHAT_ONE2ONE = 'one2one'
- CHAT_GROUP = 'group'
-
- # Widgets management
- # FIXME: should be in quick_frontend.constant, but Libervia doesn't inherit from it
- WIDGET_NEW = 'NEW'
- WIDGET_KEEP = 'KEEP'
- WIDGET_RAISE = 'RAISE'
- WIDGET_RECREATE = 'RECREATE'
-
diff --git a/frontends/src/primitivus/primitivus b/frontends/src/primitivus/primitivus
index 56e00995..d3a017ce 100755
--- a/frontends/src/primitivus/primitivus
+++ b/frontends/src/primitivus/primitivus
@@ -464,7 +464,6 @@ class PrimitivusApp(QuickApp, InputHistory):
def addContactList(self, profile):
contact_list = ContactList(self, on_click=self.contactSelected, on_change=lambda w: self.redraw(), profile=profile)
self.contact_lists_pile.contents.append((contact_list, ('weight', 1)))
- self.contact_lists[profile] = contact_list
return contact_list
def plugging_profiles(self):
diff --git a/frontends/src/primitivus/profile_manager.py b/frontends/src/primitivus/profile_manager.py
index 0b1d087a..148f2cc8 100644
--- a/frontends/src/primitivus/profile_manager.py
+++ b/frontends/src/primitivus/profile_manager.py
@@ -153,7 +153,7 @@ class ProfileManager(QuickProfileManager, urwid.WidgetWrap):
self.host.redraw()
def alert(self, title, message):
- popup = sat_widgets.alert(title, message, ok_cb=self.host.removePopUp)
+ popup = sat_widgets.Alert(title, message, ok_cb=self.host.removePopUp)
self.host.showPopUp(popup)
def onProfileChange(self, list_wid):
diff --git a/frontends/src/primitivus/status.py b/frontends/src/primitivus/status.py
index 00123cba..91158d45 100644
--- a/frontends/src/primitivus/status.py
+++ b/frontends/src/primitivus/status.py
@@ -20,7 +20,7 @@
from sat.core.i18n import _
import urwid
from urwid_satext import sat_widgets
-from sat_frontends.constants import Const as commonConst
+from sat_frontends.quick_frontend.constants import Const as commonConst
from sat_frontends.primitivus.constants import Const
diff --git a/frontends/src/quick_frontend/constants.py b/frontends/src/quick_frontend/constants.py
index 0cb1a26d..7cb6e4b1 100644
--- a/frontends/src/quick_frontend/constants.py
+++ b/frontends/src/quick_frontend/constants.py
@@ -17,18 +17,58 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-from sat_frontends import constants
+from sat.core import constants
+from sat.core.i18n import _, D_
+from collections import OrderedDict # only available from python 2.7
class Const(constants.Const):
- #Contact list
+ PRESENCE = OrderedDict([("", _("Online")),
+ ("chat", _("Free for chat")),
+ ("away", _("Away from keyboard")),
+ ("dnd", _("Do not disturb")),
+ ("xa", _("Extended away"))])
+
+ # from plugin_misc_text_syntaxes
+ SYNTAX_XHTML = "XHTML"
+ SYNTAX_CURRENT = "@CURRENT@"
+ SYNTAX_TEXT = "text"
+
+ # XMLUI
+ SAT_FORM_PREFIX = "SAT_FORM_"
+ SAT_PARAM_SEPARATOR = "_XMLUI_PARAM_" # used to have unique elements names
+ XMLUI_STATUS_VALIDATED = "validated"
+ XMLUI_STATUS_CANCELLED = constants.Const.XMLUI_DATA_CANCELLED
+
+ # MUC
+ ALL_OCCUPANTS = 1
+ MUC_USER_STATES = {
+ "active": u'✔',
+ "inactive": u'☄',
+ "gone": u'✈',
+ "composing": u'✎',
+ "paused": u"⦷"
+ }
+
+ # Roster
CONTACT_GROUPS = 'groups'
CONTACT_RESOURCES = 'resources'
CONTACT_MAIN_RESOURCE = 'main_resource'
CONTACT_SPECIAL = 'special'
- CONTACT_SPECIAL_GROUP = 'group' # group chat special entity
- CONTACT_SPECIAL_ALLOWED = (CONTACT_SPECIAL_GROUP,) # set of allowed values for special flag
- CONTACT_DATA_FORBIDDEN = {CONTACT_GROUPS, CONTACT_RESOURCES, CONTACT_MAIN_RESOURCE} # set of forbidden names for contact data
+ CONTACT_SPECIAL_GROUP = 'group' # group chat special entity
+ CONTACT_SPECIAL_ALLOWED = (CONTACT_SPECIAL_GROUP,) # set of allowed values for special flag
+ CONTACT_DATA_FORBIDDEN = {CONTACT_GROUPS, CONTACT_RESOURCES, CONTACT_MAIN_RESOURCE} # set of forbidden names for contact data
- LISTENERS = {'avatar'}
+ # Chats
+ CHAT_ONE2ONE = 'one2one'
+ CHAT_GROUP = 'group'
+
+ # Widgets management
+ # FIXME: should be in quick_frontend.constant, but Libervia doesn't inherit from it
+ WIDGET_NEW = 'NEW'
+ WIDGET_KEEP = 'KEEP'
+ WIDGET_RAISE = 'RAISE'
+ WIDGET_RECREATE = 'RECREATE'
+
+ LISTENERS = {'avatar', 'presence'}
diff --git a/frontends/src/quick_frontend/quick_app.py b/frontends/src/quick_frontend/quick_app.py
index 4b5083ac..51ad3df4 100644
--- a/frontends/src/quick_frontend/quick_app.py
+++ b/frontends/src/quick_frontend/quick_app.py
@@ -17,17 +17,26 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-from sat.core.i18n import _
-import sys
from sat.core.log import getLogger
log = getLogger(__name__)
+
+from sat.core.i18n import _
from sat.core import exceptions
+
from sat_frontends.tools import jid
from sat_frontends.quick_frontend.quick_widgets import QuickWidgetsManager
from sat_frontends.quick_frontend import quick_chat
-
from sat_frontends.quick_frontend.constants import Const as C
+import sys
+from collections import OrderedDict
+
+try:
+ # FIXME: to be removed when an acceptable solution is here
+ unicode('') # XXX: unicode doesn't exist in pyjamas
+except (TypeError, AttributeError): # Error raised is not the same depending on pyjsbuild options
+ unicode = str
+
class ProfileManager(object):
"""Class managing all data relative to one profile, and plugging in mechanism"""
@@ -75,11 +84,14 @@ class ProfileManager(object):
def _plug_profile_gotCachedValues(self, cached_values):
# TODO: watched plugin
+
+ # add the contact list and its listener
contact_list = self.host.addContactList(self.profile)
+ self.host.contact_lists[self.profile] = contact_list
for entity, data in cached_values.iteritems():
for key, value in data.iteritems():
- self.host.contact_lists[self.profile].setCache(jid.JID(entity), key, value)
+ contact_list.setCache(jid.JID(entity), key, value)
if not self.bridge.isConnected(self.profile):
self.host.setStatusOnline(False, profile=self.profile)
@@ -169,11 +181,18 @@ class ProfilesManager(object):
def unplug(self, profile):
if profile not in self._profiles:
raise ValueError('The profile [{}] is not plugged'.format(profile))
+
+ # remove the contact list and its listener
+ host = self._profiles[profile].host
+ host.contact_lists[profile].onDelete()
+ del host.contact_lists[profile]
+
del self._profiles[profile]
def chooseOneProfile(self):
return self._profiles.keys()[0]
+
class QuickApp(object):
"""This class contain the main methods needed for the frontend"""
@@ -196,7 +215,7 @@ class QuickApp(object):
self.selected_widget = None # widget currently selected (must be filled by frontend)
# listeners
- self._listeners = {} # key: listerner type ("avatar", "selected", etc), value: list of callbacks
+ self._listeners = {} # key: listener type ("avatar", "selected", etc), value: list of callbacks
## bridge ##
try:
@@ -287,31 +306,38 @@ class QuickApp(object):
handler(*args, **kwargs)
self.bridge.register(functionName, signalReceived, iface)
- def addListerner(self, type_, callback):
- """Add a listerner for an event
+ def addListener(self, type_, callback, profiles_filter=None):
+ """Add a listener for an event
/!\ don't forget to remove listener when not used anymore (e.g. if you delete a widget)
@param type_: type of event, can be:
- avatar: called when avatar data is updated
- args: (entity, avatar file, profile)
+ args: (entity, avatar file)
+ - presence: called when a presence is received
+ args: (entity, show, priority, statuses)
@param callback: method to call on event
+ @param profiles_filter (set[unicode]): if set and not empty, the
+ listener will be callable only by one of the given profiles.
"""
assert type_ in C.LISTENERS
- self._listeners.setdefault(type_, []).append(callback)
+ self._listeners.setdefault(type_, OrderedDict())[callback] = profiles_filter
def removeListener(self, type_, callback):
"""Remove a callback from listeners
- @param type_: same as for [addListerner]
+ @param type_: same as for [addListener]
@param callback: callback to remove
"""
assert type_ in C.LISTENERS
- self._listeners[type_].remove(callback)
+ self._listeners[type_].pop(callback)
- def callListeners(self, type_, *args):
- """Call all methods which listen of type_ event
+ def callListeners(self, type_, profile, *args):
+ """Call the methods which listen type_ event. If a profiles filter has
+ been register with a listener and profile argument is not None, the
+ listener will be called only if profile is in the profiles filter list.
- @param type_: same as for [addListerner]
+ @param type_: same as for [addListener]
+ @param profile (unicode): %(doc_profile)s
@param *args: arguments sent to callback
"""
assert type_ in C.LISTENERS
@@ -320,8 +346,9 @@ class QuickApp(object):
except KeyError:
pass
else:
- for listener in listeners:
- listener(*args)
+ for listener, profiles_filter in listeners.iteritems():
+ if profile is None or not profiles_filter or profile in profiles_filter:
+ listener(*args)
def check_profile(self, profile):
"""Tell if the profile is currently followed by the application"""
@@ -374,7 +401,7 @@ class QuickApp(object):
"""Tell the application to not follow anymore the profile"""
if not profile in self.profiles:
raise ValueError("The profile [{}] is not plugged".format(profile))
- self.profiles.remove(profile)
+ self.profiles.unplug(profile)
def clear_profile(self):
self.profiles.clear()
@@ -468,7 +495,7 @@ class QuickApp(object):
# if entity.bare in self.profiles[profile].data.get('watched',[]) and not entity.bare in self.profiles[profile]['onlineContact']:
# self.showAlert(_("Watched jid [%s] is connected !") % entity.bare)
- self.contact_lists[profile].updatePresence(entity, show, priority, statuses)
+ self.callListeners('presence', profile, entity, show, priority, statuses)
def roomJoinedHandler(self, room_jid_s, room_nicks, user_nick, profile):
"""Called when a MUC room is joined"""
@@ -614,10 +641,8 @@ class QuickApp(object):
def _subscribe_cb(self, answer, data):
entity, profile = data
- if answer:
- self.bridge.subscription("subscribed", entity.bare, profile_key=profile)
- else:
- self.bridge.subscription("unsubscribed", entity.bare, profile_key=profile)
+ type_ = "subscribed" if answer else "unsubscribed"
+ self.bridge.subscription(type_, unicode(entity.bare), profile_key=profile)
def subscribeHandler(self, type, raw_jid, profile):
"""Called when a subsciption management signal is received"""
@@ -632,7 +657,7 @@ class QuickApp(object):
# this is a subscriptionn request, we have to ask for user confirmation
self.showDialog(_("The contact %s wants to subscribe to your presence.\nDo you accept ?") % entity.bare, _('Subscription confirmation'), 'yes/no', answer_cb=self._subscribe_cb, answer_data=(entity, profile))
- def showDialog(self, message, title, type="info", answer_cb=None):
+ def showDialog(self, message, title, type="info", answer_cb=None, answer_data=None):
raise NotImplementedError
def showAlert(self, message):
@@ -650,8 +675,8 @@ class QuickApp(object):
elif (namespace, name) == ('General', C.SHOW_EMPTY_GROUPS):
self.contact_lists[profile].showEmptyGroups(C.bool(value))
- def contactDeletedHandler(self, jid, profile):
- target = jid.JID(jid)
+ def contactDeletedHandler(self, jid_s, profile):
+ target = jid.JID(jid_s)
self.contact_lists[profile].remove(target)
def entityDataUpdatedHandler(self, entity_s, key, value, profile):
@@ -663,7 +688,7 @@ class QuickApp(object):
if entity in self.contact_lists[profile]:
def gotFilename(filename):
self.contact_lists[profile].setCache(entity, 'avatar', filename)
- self.callListeners('avatar', entity, filename, profile)
+ self.callListeners('avatar', profile, entity, filename)
self.bridge.getAvatarFile(value, callback=gotFilename)
def askConfirmationHandler(self, confirm_id, confirm_type, data, profile):
@@ -687,8 +712,12 @@ class QuickApp(object):
def onExit(self):
"""Must be called when the frontend is terminating"""
+ to_unplug = []
for profile in self.profiles:
if self.bridge.isConnected(profile):
if C.bool(self.bridge.getParamA("autodisconnect", "Connection", profile_key=profile)):
#The user wants autodisconnection
self.bridge.disconnect(profile)
+ to_unplug.append(profile)
+ for profile in to_unplug:
+ self.unplug_profile(profile)
diff --git a/frontends/src/quick_frontend/quick_contact_list.py b/frontends/src/quick_frontend/quick_contact_list.py
index 2b487520..2dd1d84e 100644
--- a/frontends/src/quick_frontend/quick_contact_list.py
+++ b/frontends/src/quick_frontend/quick_contact_list.py
@@ -72,6 +72,10 @@ class QuickContactList(QuickWidget):
self.host.bridge.asyncGetParamA(C.SHOW_EMPTY_GROUPS, "General", profile_key=profile, callback=self._showEmptyGroups)
self.host.bridge.asyncGetParamA(C.SHOW_OFFLINE_CONTACTS, "General", profile_key=profile, callback=self._showOfflineContacts)
+ # FIXME: workaround for a pyjamas issue: calling hash on a class method always return a different value if that method is defined directly within the class (with the "def" keyword)
+ self.presenceListener = self.updatePresence
+ self.host.addListener('presence', self.presenceListener, [profile])
+
def __contains__(self, entity):
"""Check if entity is in contact list
@@ -92,17 +96,27 @@ class QuickContactList(QuickWidget):
"""
return self._roster
+ @property
+ def roster_entities_connected(self):
+ """Return all the bare JIDs of the roster entities that are connected.
+
+ @return: set(jid.JID)
+ """
+ return set([entity for entity in self._roster if self.getCache(entity, C.PRESENCE_SHOW) is not None])
+
@property
def roster_entities_by_group(self):
- """Return a dictionary binding the roster groups to their entities bare JIDs.
+ """Return a dictionary binding the roster groups to their entities bare
+ JIDs. This also includes the empty group (None key).
@return: dict{unicode: set(jid.JID)}
"""
return {group: self._groups[group]['jids'] for group in self._groups}
@property
- def roster_groups_by_entity(self, contact_jid_s):
- """Return a dictionary binding the entities bare JIDs to their roster groups.
+ def roster_groups_by_entity(self):
+ """Return a dictionary binding the entities bare JIDs to their roster
+ groups. The empty group is filtered out.
@return: dict{jid.JID: set(unicode)}
"""
@@ -212,6 +226,17 @@ class QuickContactList(QuickWidget):
assert special_type in C.CONTACT_SPECIAL_ALLOWED + (None,)
self.setCache(entity, C.CONTACT_SPECIAL, special_type)
+ def getSpecials(self, special_type=None):
+ """Return all the bare JIDs of the special roster entities of the type
+ specified by special_type. If special_type is None, return all specials.
+
+ @param special_type: one of special type (e.g. C.CONTACT_SPECIAL_GROUP) or None to return all specials.
+ @return: set(jid.JID)
+ """
+ if special_type is None:
+ return self._specials
+ return set([entity for entity in self._specials if self.getCache(entity, C.CONTACT_SPECIAL) == special_type])
+
def clearContacts(self):
"""Clear all the contact list"""
self.unselectAll()
@@ -425,3 +450,7 @@ class QuickContactList(QuickWidget):
return
self.show_resources = show
self.update()
+
+ def onDelete(self):
+ QuickWidget.onDelete(self)
+ self.host.removeListener('presence', self.presenceListener)
diff --git a/frontends/src/quick_frontend/quick_profile_manager.py b/frontends/src/quick_frontend/quick_profile_manager.py
index 8e16a24b..58832069 100644
--- a/frontends/src/quick_frontend/quick_profile_manager.py
+++ b/frontends/src/quick_frontend/quick_profile_manager.py
@@ -113,7 +113,7 @@ class QuickProfileManager(object):
self._autoconnect = False # manual mode
msg = _("Trying to plug an unknown profile key ({})".format(profile_key))
log.warning(msg)
- self.alert(_("Profile plugging in error"), msg, ok_cb=self.host.removePopUp)
+ self.alert(_("Profile plugging in error"), msg)
break
self.host.launchAction(C.AUTHENTICATE_PROFILE_ID, callback=authenticate_cb, profile=profile)
diff --git a/frontends/src/quick_frontend/quick_widgets.py b/frontends/src/quick_frontend/quick_widgets.py
index aac9f09b..0cbc4a4d 100644
--- a/frontends/src/quick_frontend/quick_widgets.py
+++ b/frontends/src/quick_frontend/quick_widgets.py
@@ -105,15 +105,13 @@ class QuickWidgetsManager(object):
if there is neither 'profile' nor 'profiles', None will be used for 'profiles'
if 'on_new_widget' is present it can have the following values:
C.WIDGET_NEW [default]: self.host.newWidget will be called on widget creation
- [callable]: this method will be called instead of self.host.newWidget,
- and can return another widget to modify the result of the present method
+ [callable]: this method will be called instead of self.host.newWidget
None: do nothing
if 'on_existing_widget' is present it can have the following values:
C.WIDGET_KEEP [default]: return the existing widget
C.WIDGET_RAISE: raise WidgetAlreadyExistsError
C.WIDGET_RECREATE: create a new widget *WITH A NEW HASH*
- [callable]: this method will be called with existing widget as argument,
- and can return another widget to modify the result of the present method
+ [callable]: this method will be called with existing widget as argument
if 'force_hash' is present, the hash given in value will be used instead of the one returned by class_.getWidgetHash
other keys will be used to instanciate class_ if the case happen (e.g. if type_ is present and class_ is a QuickChat subclass,
it will be used to create a new QuickChat instance).
@@ -171,9 +169,7 @@ class QuickWidgetsManager(object):
if on_new_widget == C.WIDGET_NEW:
self.host.newWidget(widget)
elif callable(on_new_widget):
- result = on_new_widget(widget)
- if isinstance(result, QuickWidget):
- widget = result
+ on_new_widget(widget)
else:
assert on_new_widget is None
else:
@@ -207,9 +203,7 @@ class QuickWidgetsManager(object):
log.debug(u"Widget already exists, a new one has been recreated with hash {}".format(new_kwargs['force_hash']))
break
elif callable(on_existing_widget):
- result = on_existing_widget(widget)
- if isinstance(result, QuickWidget):
- widget = result
+ on_existing_widget(widget)
else:
raise exceptions.InternalError("Unexpected on_existing_widget value ({})".format(on_existing_widget))
diff --git a/frontends/src/tools/xmlui.py b/frontends/src/tools/xmlui.py
index 2573f25d..dc483f68 100644
--- a/frontends/src/tools/xmlui.py
+++ b/frontends/src/tools/xmlui.py
@@ -20,7 +20,7 @@
from sat.core.i18n import _
from sat.core.log import getLogger
log = getLogger(__name__)
-from sat_frontends.constants import Const as C
+from sat_frontends.quick_frontend.constants import Const as C
from sat.core.exceptions import DataError
diff --git a/src/core/sat_main.py b/src/core/sat_main.py
index fd315b1d..d8ac3e87 100644
--- a/src/core/sat_main.py
+++ b/src/core/sat_main.py
@@ -640,7 +640,7 @@ class SAT(service.Service):
assert profile
d1 = self.profiles[profile].roster.removeItem(to_jid)
d2 = self.profiles[profile].presence.unsubscribe(to_jid)
- d_list = defer.DefferedList([d1, d2])
+ d_list = defer.DeferredList([d1, d2])
def check_result(list_result):
for success, value in list_result:
if not success:
diff --git a/src/plugins/plugin_xep_0085.py b/src/plugins/plugin_xep_0085.py
index 692733d8..e2625a46 100755
--- a/src/plugins/plugin_xep_0085.py
+++ b/src/plugins/plugin_xep_0085.py
@@ -126,16 +126,16 @@ class XEP_0085(object):
self.map[profile][to_jid]._onEvent('gone')
del self.map[profile]
- def updateEntityData(self, entity_jid, value, profile):
+ def updateCache(self, entity_jid, value, profile):
"""Update the entity data of the given profile for one or all contacts.
-
Reset the chat state(s) display if the notification has been disabled.
+
@param entity_jid: contact's JID, or C.ENTITY_ALL to update all contacts.
@param value: True, False or DELETE_VALUE to delete the entity data
@param profile: current profile
"""
if value == DELETE_VALUE:
- self.host.memory.delEntityData(entity_jid, ENTITY_KEY, profile)
+ self.host.memory.delEntityDatum(entity_jid, ENTITY_KEY, profile)
else:
self.host.memory.updateEntityData(entity_jid, ENTITY_KEY, value, profile_key=profile)
if not value or value == DELETE_VALUE:
@@ -151,7 +151,7 @@ class XEP_0085(object):
@param type_: parameter type
"""
if (category, name) == (PARAM_KEY, PARAM_NAME):
- self.updateEntityData(C.ENTITY_ALL, True if bool("true") else DELETE_VALUE, profile=profile)
+ self.updateCache(C.ENTITY_ALL, True if bool("true") else DELETE_VALUE, profile=profile)
return False
return True
@@ -173,11 +173,11 @@ class XEP_0085(object):
try:
domish.generateElementsNamed(message.elements(), name="active").next()
# contact enabled Chat State Notifications
- self.updateEntityData(from_jid, True, profile=profile)
+ self.updateCache(from_jid, True, profile=profile)
except StopIteration:
if message.getAttribute('type') == 'chat':
# contact didn't enable Chat State Notifications
- self.updateEntityData(from_jid, False, profile=profile)
+ self.updateCache(from_jid, False, profile=profile)
return True
except StopIteration:
pass
@@ -260,7 +260,7 @@ class XEP_0085(object):
except (exceptions.UnknownEntityError, KeyError):
if forceEntityData:
# enable it for the first time
- self.updateEntityData(to_jid, True, profile=profile)
+ self.updateCache(to_jid, True, profile=profile)
return True
# wait for the first message before sending states
return False