quick frontend, primitivus, wix: MUC private messages management
/!\ not fully finished, backend part is not done yet /!\
- as resources are discarded to manage chat windows lists, a pretty dirty hack is done to work around this:
full jid is escaped using a prefix (it becomes invalid and resource is preserved).
- new quick_utils module, with helper methods. escapePrivate and unescapePrivate implementations
- MUC private messages are not managed in Wix yet
This commit is contained in:
parent
4225b694d0
commit
8ad8ca1933
5 changed files with 163 additions and 77 deletions
23
frontends/src/quick_frontend/constants.py
Normal file
23
frontends/src/quick_frontend/constants.py
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Primitivus: a SAT frontend
|
||||
Copyright (C) 2009, 2010, 2011, 2012 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 <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
import __builtin__
|
||||
|
||||
__builtin__.__dict__['const_PRIVATE_PREFIX'] = "@PRIVATE@"
|
||||
|
|
@ -22,8 +22,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
from logging import debug, info, warning, error
|
||||
from sat.tools.jid import JID
|
||||
from sat_frontends.bridge.DBus import DBusBridgeFrontend,BridgeExceptionNoService
|
||||
from sat_frontends.quick_frontend.quick_utils import escapePrivate, unescapePrivate
|
||||
from optparse import OptionParser
|
||||
|
||||
import sat_frontends.quick_frontend.constants
|
||||
|
||||
import gettext
|
||||
gettext.install('sat_frontend', "../i18n", unicode=True)
|
||||
|
||||
|
|
@ -46,7 +49,7 @@ class QuickApp():
|
|||
self.bridge.register("disconnected", self.disconnected)
|
||||
self.bridge.register("connectionError", self.connectionError)
|
||||
self.bridge.register("newContact", self.newContact)
|
||||
self.bridge.register("newMessage", self.newMessage)
|
||||
self.bridge.register("newMessage", self._newMessage)
|
||||
self.bridge.register("newAlert", self.newAlert)
|
||||
self.bridge.register("presenceUpdate", self.presenceUpdate)
|
||||
self.bridge.register("subscribe", self.subscribe)
|
||||
|
|
@ -230,17 +233,48 @@ class QuickApp():
|
|||
return
|
||||
entity=JID(JabberId)
|
||||
_groups = list(groups)
|
||||
self.contact_list._replace(entity, _groups, attributes)
|
||||
|
||||
def newMessage(self, from_jid, msg, type, to_jid, profile):
|
||||
self.contact_list.replace(entity, _groups, attributes)
|
||||
|
||||
def _newMessage(self, from_jid_s, msg, _type, to_jid_s, profile):
|
||||
"""newMessage premanagement: a dirty hack to manage private messages
|
||||
if a private MUC message is detected, from_jid or to_jid is prefixed and resource is escaped"""
|
||||
if not self.check_profile(profile):
|
||||
return
|
||||
sender=JID(from_jid)
|
||||
addr=JID(to_jid)
|
||||
win = addr if sender.short == self.profiles[profile]['whoami'].short else sender
|
||||
from_jid = JID(from_jid_s)
|
||||
to_jid = JID(to_jid_s)
|
||||
|
||||
from_me = from_jid.short == self.profiles[profile]['whoami'].short
|
||||
win = to_jid if from_me else from_jid
|
||||
|
||||
if _type != "groupchat" and self.contact_list.getSpecial(win) == "MUC":
|
||||
#we have a private message in a MUC room
|
||||
#XXX: normaly we use bare jid as key, here we need the full jid
|
||||
# so we cheat by replacing the "/" before the resource by
|
||||
# a "@", so the jid is invalid,
|
||||
new_jid = escapePrivate(win)
|
||||
if from_me:
|
||||
to_jid = new_jid
|
||||
else:
|
||||
from_jid = new_jid
|
||||
if new_jid not in self.contact_list:
|
||||
self.contact_list.add(new_jid)
|
||||
|
||||
self.newMessage(from_jid, to_jid, msg, _type, profile)
|
||||
|
||||
def newMessage(self, from_jid, to_jid, msg, _type, profile):
|
||||
from_me = from_jid.short == self.profiles[profile]['whoami'].short
|
||||
win = to_jid if from_me else from_jid
|
||||
|
||||
self.current_action_ids = set()
|
||||
self.current_action_ids_cb = {}
|
||||
self.chat_wins[win.short].printMessage(sender, msg, profile)
|
||||
|
||||
self.chat_wins[win.short].printMessage(from_jid, msg, profile)
|
||||
|
||||
def sendMessage(self, to_jid, message, subject='', mess_type="auto", profile_key="@DEFAULT@"):
|
||||
if to_jid.startswith(const_PRIVATE_PREFIX):
|
||||
to_jid = unescapePrivate(to_jid)
|
||||
mess_type = "chat"
|
||||
self.bridge.sendMessage(to_jid, message, subject, mess_type, profile_key)
|
||||
|
||||
def newAlert(self, msg, title, alert_type, profile):
|
||||
if not self.check_profile(profile):
|
||||
|
|
@ -292,13 +326,13 @@ class QuickApp():
|
|||
self.chat_wins[room_jid].setPresents(list(set([user_nick]+room_nicks)))
|
||||
self.contact_list.setSpecial(JID(room_jid), "MUC")
|
||||
|
||||
def roomLeft(self, room_jid, profile):
|
||||
def roomLeft(self, room_jid_s, profile):
|
||||
"""Called when a MUC room is left"""
|
||||
if not self.check_profile(profile):
|
||||
return
|
||||
debug (_("Room [%(room_jid)s] left by %(profile)s") % {'room_jid':room_jid, 'profile': profile})
|
||||
del self.chat_wins[room_jid]
|
||||
self.contact_list.remove(room_jid)
|
||||
debug (_("Room [%(room_jid)s] left by %(profile)s") % {'room_jid':room_jid_s, 'profile': profile})
|
||||
del self.chat_wins[room_jid_s]
|
||||
self.contact_list.remove(JID(room_jid_s))
|
||||
|
||||
def roomUserJoined(self, room_jid, user_nick, user_data, profile):
|
||||
"""Called when an user joined a MUC room"""
|
||||
|
|
@ -504,12 +538,12 @@ class QuickApp():
|
|||
if key == "nick":
|
||||
if jid in self.contact_list:
|
||||
self.contact_list.setCache(jid, 'nick', value)
|
||||
self.contact_list._replace(jid)
|
||||
self.contact_list.replace(jid)
|
||||
elif key == "avatar":
|
||||
if jid in self.contact_list:
|
||||
filename = self.bridge.getAvatarFile(value)
|
||||
self.contact_list.setCache(jid, 'avatar', filename)
|
||||
self.contact_list._replace(jid)
|
||||
self.contact_list.replace(jid)
|
||||
|
||||
def askConfirmation(self, type, id, data):
|
||||
raise NotImplementedError
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
from logging import debug, info, warning, error
|
||||
from sat.tools.jid import JID
|
||||
|
||||
from sat_frontends.quick_frontend.quick_utils import unescapePrivate
|
||||
|
||||
|
||||
class QuickChat():
|
||||
|
|
@ -110,6 +110,8 @@ class QuickChat():
|
|||
|
||||
def _get_nick(self, jid):
|
||||
"""Return nick of this jid when possible"""
|
||||
if jid.startswith(const_PRIVATE_PREFIX):
|
||||
return unescapePrivate(jid).resource
|
||||
return jid.resource if self.type == "group" else (self.host.contact_list.getCache(jid,'nick') or self.host.contact_list.getCache(jid,'name') or jid.node)
|
||||
|
||||
def printMessage(self, from_jid, msg, profile, timestamp):
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ class QuickContactList():
|
|||
def __init__(self):
|
||||
debug(_("Contact List init"))
|
||||
self._cache = {}
|
||||
self.specials={}
|
||||
|
||||
def update_jid(self, jid):
|
||||
"""Update the jid in the list when something changed"""
|
||||
|
|
@ -51,31 +52,34 @@ class QuickContactList():
|
|||
|
||||
def clearContacts(self, jid):
|
||||
"""Clear all the contact list"""
|
||||
raise NotImplementedError
|
||||
self.specials.clear()
|
||||
|
||||
def _replace(self, jid, groups=None, attributes=None):
|
||||
def replace(self, jid, groups=None, attributes=None):
|
||||
"""add a contact to the list if doesn't exist, else update it"""
|
||||
if attributes and 'name' in attributes:
|
||||
self.setCache(jid, 'name', attributes['name'])
|
||||
self.replace(jid, groups, attributes)
|
||||
|
||||
def replace(self, jid, groups, attributes):
|
||||
"""add a contact to the list if doesn't exist, else update it"""
|
||||
raise NotImplementedError
|
||||
|
||||
def remove(self, jid):
|
||||
"""remove a contact from the list"""
|
||||
raise NotImplementedError
|
||||
try:
|
||||
del self.specials[jid.short]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
def add(self, jid, param_groups=None):
|
||||
"""add a contact to the list"""
|
||||
raise NotImplementedError
|
||||
|
||||
def getSpecial(self, jid):
|
||||
"""Return special type of jid, or None if it's not special"""
|
||||
return self.specials.get(jid.short)
|
||||
|
||||
def setSpecial(self, jid, _type):
|
||||
"""Set entity as a special
|
||||
@param jid: jid of the entity
|
||||
@param _type: special type (e.g.: "MUC")
|
||||
"""
|
||||
raise NotImplementedError
|
||||
self.specials[jid.short] = _type
|
||||
|
||||
def updatePresence(self, jid, show, priority, statuses):
|
||||
"""Update entity's presence status
|
||||
|
|
|
|||
33
frontends/src/quick_frontend/quick_utils.py
Normal file
33
frontends/src/quick_frontend/quick_utils.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Primitivus: a SAT frontend
|
||||
Copyright (C) 2009, 2010, 2011, 2012 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 <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
from sat.tools.jid import JID
|
||||
|
||||
def escapePrivate(ori_jid):
|
||||
"""Escape a private jid"""
|
||||
return JID(const_PRIVATE_PREFIX + ori_jid.short + '@' + ori_jid.resource)
|
||||
|
||||
def unescapePrivate(escaped_jid):
|
||||
if not escaped_jid.startswith(const_PRIVATE_PREFIX):
|
||||
return escaped_jid
|
||||
escaped_split = tuple(escaped_jid[len(const_PRIVATE_PREFIX):].split('@'))
|
||||
assert(len(escaped_split) == 3)
|
||||
return JID("%s@%s/%s" % escaped_split)
|
||||
Loading…
Reference in a new issue