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 6c12956dd6
commit 7f1c9cd0db
4 changed files with 60 additions and 26 deletions

View File

@ -25,7 +25,7 @@ class SpectrumBackend:
self.m_data = "" self.m_data = ""
self.m_init_res = 0 self.m_init_res = 0
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 = protocol_pb2.ConversationMessage()
m.userName = user m.userName = user
m.buddyName = legacyName m.buddyName = legacyName
@ -33,7 +33,6 @@ class SpectrumBackend:
m.nickname = nickname m.nickname = nickname
m.xhtml = xhtml m.xhtml = xhtml
m.timestamp = str(timestamp) m.timestamp = str(timestamp)
m.pm = pm
message = WRAP(m.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_CONV_MESSAGE) message = WRAP(m.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_CONV_MESSAGE)
self.send(message) self.send(message)

View File

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

View File

@ -79,10 +79,18 @@ class Session(YowsupApp):
self.shouldBeConncted = True self.shouldBeConncted = True
super(Session, self).login(self.legacyName, self.password) 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): def updateRoomList(self):
rooms = [] rooms = []
for room, group in self.groups.iteritems(): 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.logger.debug("Got rooms: %s", rooms)
self.backend.handleRoomList(rooms) self.backend.handleRoomList(rooms)
@ -136,7 +144,7 @@ class Session(YowsupApp):
oroom.subject = subject oroom.subject = subject
else: else:
self.groups[room] = Group(room, owner, subject, subjectOwner) 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()) self._addParticipantsToRoom(room, group.getParticipants())
@ -150,6 +158,7 @@ class Session(YowsupApp):
self.updateRoomList() self.updateRoomList()
def joinRoom(self, room, nick): def joinRoom(self, room, nick):
room = self._lengthenGroupId(room)
if room in self.groups: if room in self.groups:
self.logger.info("Joining room: %s room=%s, nick=%s", self.logger.info("Joining room: %s room=%s, nick=%s",
self.legacyName, room, nick) self.legacyName, room, nick)
@ -165,11 +174,38 @@ class Session(YowsupApp):
ownerNick) ownerNick)
self.backend.handleRoomNicknameChanged(self.user, room, self.backend.handleRoomNicknameChanged(self.user, room,
group.subject) group.subject)
self._refreshParticipants(room)
else: else:
self.logger.warn("Room doesn't exist: %s", room) 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): def _addParticipantsToRoom(self, room, participants):
group = self.groups[room] group = self.groups[room]
group.participants = participants
for jid, _type in participants.iteritems(): for jid, _type in participants.iteritems():
buddy = jid.split("@")[0] buddy = jid.split("@")[0]
@ -190,7 +226,7 @@ class Session(YowsupApp):
buddyFull = self.user buddyFull = self.user
self.backend.handleParticipantChanged(self.user, buddyFull, 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): def _lastSeen(self, number, seconds):
@ -224,7 +260,7 @@ class Session(YowsupApp):
self.backend.handleDisconnected(self.user, 0, reason) self.backend.handleDisconnected(self.user, 0, reason)
self.password = None self.password = None
self.shouldBeConnected = False self.shouldBeConnected = False
# Called by superclass # Called by superclass
def onDisconnect(self): def onDisconnect(self):
self.logger.debug('Disconnected') self.logger.debug('Disconnected')
@ -236,9 +272,12 @@ class Session(YowsupApp):
' '.join(map(str, [_id, _from, timestamp, ' '.join(map(str, [_id, _from, timestamp,
type, participant, offline, items])) type, participant, offline, items]))
) )
buddy = self.buddies[_from.split('@')[0]] try:
self.backend.handleBuddyChanged(self.user, buddy.number.number, buddy = self.buddies[_from.split('@')[0]]
buddy.nick, buddy.groups, protocol_pb2.STATUS_ONLINE) self.backend.handleBuddyChanged(self.user, buddy.number.number,
buddy.nick, buddy.groups, protocol_pb2.STATUS_ONLINE)
except KeyError:
pass
# Called by superclass # Called by superclass
def onAck(self, _id, _class, _from, timestamp): def onAck(self, _id, _class, _from, timestamp):
@ -427,7 +466,7 @@ class Session(YowsupApp):
) )
except KeyError: except KeyError:
self.logger.error('Group not found: %s', room) 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 else: # private msg
buddy = sender buddy = sender
@ -451,10 +490,13 @@ class Session(YowsupApp):
"", timestamp) "", timestamp)
def sendGroupMessageToXMPP(self, room, buddy, messageContent, timestamp = ""): def sendGroupMessageToXMPP(self, room, buddy, messageContent, timestamp = ""):
self._refreshParticipants(room)
try: try:
nick = self.buddies[buddy].nick nick = self.buddies[buddy].nick
except KeyError: except KeyError:
nick = buddy nick = buddy
if nick == "":
nick = buddy
if timestamp: if timestamp:
timestamp = time.strftime("%Y%m%dT%H%M%S", time.gmtime(timestamp)) timestamp = time.strftime("%Y%m%dT%H%M%S", time.gmtime(timestamp))
@ -470,10 +512,10 @@ class Session(YowsupApp):
(buddy, messageContent, timestamp) (buddy, messageContent, timestamp)
) )
else: else:
self.logger.debug("Group message sent from %s to %s: %s", buddy, self.logger.debug("Group message sent from %s (%s) to %s: %s",
room, messageContent) buddy, nick, room, messageContent)
self.backend.handleMessage(self.user, room, messageContent, nick, self.backend.handleMessage(self.user, self._shortenGroupId(room),
"", timestamp, False) messageContent, nick, "", timestamp)
def changeStatus(self, status): def changeStatus(self, status):
if status != self.status: if status != self.status:
@ -504,7 +546,7 @@ class Session(YowsupApp):
self.backend.handleMessage(self.user, msg[0], msg[1], "", "", msg[2]) self.backend.handleMessage(self.user, msg[0], msg[1], "", "", msg[2])
# also for adding a new buddy # 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": if buddy != "bot":
self.buddies.update(buddy, nick, groups, image_hash) self.buddies.update(buddy, nick, groups, image_hash)
self.updateRoster() self.updateRoster()
@ -539,15 +581,6 @@ class Session(YowsupApp):
if receiptRequested: self.call("message_ack", (jid, messageId)) 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): def onGroupSubjectReceived(self, messageId, gjid, jid, subject, timestamp, receiptRequested):
room = gjid.split("@")[0] room = gjid.split("@")[0]
buddy = jid.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 # TODO Proper fix, this work around drops all duplicate messages even
# intentional ones. # intentional ones.
# IDEA there is an ID field in ConvMessage. If it is extracted it will work
usersMessage = self.lastMessage[user] usersMessage = self.lastMessage[user]
if buddy not in usersMessage or usersMessage[buddy] != message: if buddy not in usersMessage or usersMessage[buddy] != message:
self.sessions[user].sendMessageToWA(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.logger.debug("handleVCardRequest(user=%s, buddy=%s, ID=%s)", user, buddy, ID)
self.sessions[user].requestVCard(buddy, ID) self.sessions[user].requestVCard(buddy, ID)
# TODO # TODO
def handleBuddyBlockToggled(self, user, buddy, blocked): def handleBuddyBlockToggled(self, user, buddy, blocked):
pass pass