merged souliane changes
This commit is contained in:
commit
27c26487c3
1 changed files with 149 additions and 133 deletions
|
|
@ -17,17 +17,26 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue