From 7f1c9cd0dbc837773b51cb2b643161ecb5982f40 Mon Sep 17 00:00:00 2001 From: moyamo Date: Mon, 21 Sep 2015 20:30:11 +0200 Subject: [PATCH] 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 --- Spectrum2/backend.py | 3 +- buddy.py | 4 +-- session.py | 77 +++++++++++++++++++++++++++++++------------- whatsappbackend.py | 2 ++ 4 files changed, 60 insertions(+), 26 deletions(-) diff --git a/Spectrum2/backend.py b/Spectrum2/backend.py index afbdec8..a027adc 100644 --- a/Spectrum2/backend.py +++ b/Spectrum2/backend.py @@ -25,7 +25,7 @@ class SpectrumBackend: self.m_data = "" 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.userName = user m.buddyName = legacyName @@ -33,7 +33,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) diff --git a/buddy.py b/buddy.py index 1ab9944..e07ec46 100644 --- a/buddy.py +++ b/buddy.py @@ -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() diff --git a/session.py b/session.py index b59544a..d65361f 100644 --- a/session.py +++ b/session.py @@ -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] diff --git a/whatsappbackend.py b/whatsappbackend.py index b7b9827..b973f76 100644 --- a/whatsappbackend.py +++ b/whatsappbackend.py @@ -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