Shorten the name of groupchats to overcome truncation bug

The names of groupchats are truncated internally to 22 characters.
This causes many problems with groupchats, since spectrum incorrectly
identifies the chat by the long name.

To overcome this the phoneNumber-unixTime is converted to hexadecimal,
to shorten the groupchat below 22 characters
This commit is contained in:
moyamo 2015-09-21 20:30:11 +02:00
parent ecfa2d7f85
commit 29d92b456e
4 changed files with 60 additions and 26 deletions

View file

@ -27,7 +27,7 @@ class SpectrumBackend:
self.m_init_res = 0
self.logger = logging.getLogger(self.__class__.__name__)
def handleMessage(self, user, legacyName, msg, nickname = "", xhtml = "", timestamp = "", pm = True):
def handleMessage(self, user, legacyName, msg, nickname = "", xhtml = "", timestamp = ""):
m = protocol_pb2.ConversationMessage()
m.userName = user
m.buddyName = legacyName
@ -35,7 +35,6 @@ class SpectrumBackend:
m.nickname = nickname
m.xhtml = xhtml
m.timestamp = str(timestamp)
m.pm = pm
message = WRAP(m.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_CONV_MESSAGE)
self.send(message)

View file

@ -23,7 +23,6 @@ __status__ = "Prototype"
"""
from Spectrum2 import protocol_pb2
from Yowsup.Contacts.contacts import WAContactsSyncRequest
import logging
@ -61,7 +60,8 @@ class Buddy():
def update(self, nick, groups, image_hash):
self.nick = nick
self.groups = groups
self.image_hash = image_hash
if image_hash is not None:
self.image_hash = image_hash
groups = u",".join(groups).encode("latin-1")
cur = self.db.cursor()

View file

@ -79,10 +79,18 @@ class Session(YowsupApp):
self.shouldBeConncted = True
super(Session, self).login(self.legacyName, self.password)
def _shortenGroupId(self, gid):
# FIXME: will have problems if number begins with 0
return '-'.join(hex(int(s))[2:] for s in gid.split('-'))
def _lengthenGroupId(self, gid):
# FIXME: will have problems if number begins with 0
return '-'.join(str(int(s, 16)) for s in gid.split('-'))
def updateRoomList(self):
rooms = []
for room, group in self.groups.iteritems():
rooms.append([room, group.subject])
rooms.append([self._shortenGroupId(room), group.subject])
self.logger.debug("Got rooms: %s", rooms)
self.backend.handleRoomList(rooms)
@ -136,7 +144,7 @@ class Session(YowsupApp):
oroom.subject = subject
else:
self.groups[room] = Group(room, owner, subject, subjectOwner)
self.joinRoom(room, self.user.split("@")[0])
self.joinRoom(self._shortenGroupId(room), self.user.split("@")[0])
self._addParticipantsToRoom(room, group.getParticipants())
@ -150,6 +158,7 @@ class Session(YowsupApp):
self.updateRoomList()
def joinRoom(self, room, nick):
room = self._lengthenGroupId(room)
if room in self.groups:
self.logger.info("Joining room: %s room=%s, nick=%s",
self.legacyName, room, nick)
@ -165,11 +174,38 @@ class Session(YowsupApp):
ownerNick)
self.backend.handleRoomNicknameChanged(self.user, room,
group.subject)
self._refreshParticipants(room)
else:
self.logger.warn("Room doesn't exist: %s", room)
def _refreshParticipants(self, room):
group = self.groups[room]
for jid in group.participants:
buddy = jid.split("@")[0]
self.logger.info("Added %s to room %s", buddy, room)
try:
nick = self.buddies[buddy].nick
except KeyError:
nick = buddy
if nick == "":
nick = buddy
buddyFull = buddy
if buddy == group.owner:
flags = protocol_pb2.PARTICIPANT_FLAG_MODERATOR
else:
flags = protocol_pb2.PARTICIPANT_FLAG_NONE
if buddy == self.legacyName:
nick = group.nick
flags = flags | protocol_pb2.PARTICIPANT_FLAG_ME
buddyFull = self.user
self.backend.handleParticipantChanged(
self.user, buddyFull, self._shortenGroupId(room), flags,
protocol_pb2.STATUS_ONLINE, buddy, nick)
def _addParticipantsToRoom(self, room, participants):
group = self.groups[room]
group.participants = participants
for jid, _type in participants.iteritems():
buddy = jid.split("@")[0]
@ -190,7 +226,7 @@ class Session(YowsupApp):
buddyFull = self.user
self.backend.handleParticipantChanged(self.user, buddyFull,
room, flags, protocol_pb2.STATUS_ONLINE, buddy, nick)
self._shortenGroupId(room), flags, protocol_pb2.STATUS_ONLINE, buddy, nick)
def _lastSeen(self, number, seconds):
@ -224,7 +260,7 @@ class Session(YowsupApp):
self.backend.handleDisconnected(self.user, 0, reason)
self.password = None
self.shouldBeConnected = False
# Called by superclass
def onDisconnect(self):
self.logger.debug('Disconnected')
@ -236,9 +272,12 @@ class Session(YowsupApp):
' '.join(map(str, [_id, _from, timestamp,
type, participant, offline, items]))
)
buddy = self.buddies[_from.split('@')[0]]
self.backend.handleBuddyChanged(self.user, buddy.number.number,
buddy.nick, buddy.groups, protocol_pb2.STATUS_ONLINE)
try:
buddy = self.buddies[_from.split('@')[0]]
self.backend.handleBuddyChanged(self.user, buddy.number.number,
buddy.nick, buddy.groups, protocol_pb2.STATUS_ONLINE)
except KeyError:
pass
# Called by superclass
def onAck(self, _id, _class, _from, timestamp):
@ -427,7 +466,7 @@ class Session(YowsupApp):
)
except KeyError:
self.logger.error('Group not found: %s', room)
self.sendTextMessage(room + '@g.us', message)
self.sendTextMessage(self._lengthenGroupId(room) + '@g.us', message)
else: # private msg
buddy = sender
@ -451,10 +490,13 @@ class Session(YowsupApp):
"", timestamp)
def sendGroupMessageToXMPP(self, room, buddy, messageContent, timestamp = ""):
self._refreshParticipants(room)
try:
nick = self.buddies[buddy].nick
except KeyError:
nick = buddy
if nick == "":
nick = buddy
if timestamp:
timestamp = time.strftime("%Y%m%dT%H%M%S", time.gmtime(timestamp))
@ -470,10 +512,10 @@ class Session(YowsupApp):
(buddy, messageContent, timestamp)
)
else:
self.logger.debug("Group message sent from %s to %s: %s", buddy,
room, messageContent)
self.backend.handleMessage(self.user, room, messageContent, nick,
"", timestamp, False)
self.logger.debug("Group message sent from %s (%s) to %s: %s",
buddy, nick, room, messageContent)
self.backend.handleMessage(self.user, self._shortenGroupId(room),
messageContent, nick, "", timestamp)
def changeStatus(self, status):
if status != self.status:
@ -504,7 +546,7 @@ class Session(YowsupApp):
self.backend.handleMessage(self.user, msg[0], msg[1], "", "", msg[2])
# also for adding a new buddy
def updateBuddy(self, buddy, nick, groups, image_hash =""):
def updateBuddy(self, buddy, nick, groups, image_hash = None):
if buddy != "bot":
self.buddies.update(buddy, nick, groups, image_hash)
self.updateRoster()
@ -539,15 +581,6 @@ class Session(YowsupApp):
if receiptRequested: self.call("message_ack", (jid, messageId))
def onGroupMessageReceived(self, messageId, gjid, jid, messageContent, timestamp, receiptRequested, pushName):
buddy = jid.split("@")[0]
room = gjid.split("@")[0]
self.logger.info("Group message received in %s from %s: %s", room, buddy, messageContent)
self.sendGroupMessageToXMPP(room, buddy, utils.softToUni(messageContent), timestamp)
if receiptRequested: self.call("message_ack", (gjid, messageId))
def onGroupSubjectReceived(self, messageId, gjid, jid, subject, timestamp, receiptRequested):
room = gjid.split("@")[0]
buddy = jid.split("@")[0]

View file

@ -67,6 +67,7 @@ class WhatsAppBackend(SpectrumBackend):
#
# TODO Proper fix, this work around drops all duplicate messages even
# intentional ones.
# IDEA there is an ID field in ConvMessage. If it is extracted it will work
usersMessage = self.lastMessage[user]
if buddy not in usersMessage or usersMessage[buddy] != message:
self.sessions[user].sendMessageToWA(buddy, message)
@ -105,6 +106,7 @@ class WhatsAppBackend(SpectrumBackend):
self.logger.debug("handleVCardRequest(user=%s, buddy=%s, ID=%s)", user, buddy, ID)
self.sessions[user].requestVCard(buddy, ID)
# TODO
def handleBuddyBlockToggled(self, user, buddy, blocked):
pass