diff --git a/Spectrum2/backend.py b/Spectrum2/backend.py index 3bef24f..75de4d2 100644 --- a/Spectrum2/backend.py +++ b/Spectrum2/backend.py @@ -37,6 +37,17 @@ class SpectrumBackend: message = WRAP(m.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_CONV_MESSAGE) self.send(message) + def handleMessageAck(self, user, legacyName, ID): + m = protocol_pb2.ConversationMessage() + m.userName = user + m.buddyName = legacyName + m.message = "" + m.id = ID + + message = WRAP(m.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_CONV_MESSAGE_ACK) + self.send(message) + + def handleAttention(self, user, buddyName, msg): m = protocol_pb2.ConversationMessage() m.userName = user @@ -243,7 +254,16 @@ class SpectrumBackend: if (payload.ParseFromString(data) == False): #TODO: ERROR return - self.handleMessageSendRequest(payload.userName, payload.buddyName, payload.message, payload.xhtml) + self.handleMessageSendRequest(payload.userName, payload.buddyName, payload.message, payload.xhtml, payload.id) + + def handleConvMessageAckPayload(self, data): + payload = protocol_pb2.ConversationMessage() + if (payload.ParseFromString(data) == False): + #TODO: ERROR + return + self.handleMessageAckRequest(payload.userName, payload.buddyName, payload.id) + + def handleAttentionPayload(self, data): payload = protocol_pb2.ConversationMessage() @@ -349,7 +369,14 @@ class SpectrumBackend: wrapper = protocol_pb2.WrapperMessage() - if (wrapper.ParseFromString(self.m_data[4:]) == False): + try: + parseFromString = wrapper.ParseFromString(self.m_data[4:]) + except: + parseFromString = True + self.logger.error("Parse from String exception") + + + if (parseFromString == False): self.m_data = self.m_data[expected_size+4:] return @@ -393,6 +420,8 @@ class SpectrumBackend: self.handleFTContinuePayload(wrapper.payload) elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_EXIT: self.handleExitRequest() + elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_CONV_MESSAGE_ACK: + self.handleConvMessageAckPayload(wrapper.payload) elif wrapper.type == protocol_pb2.WrapperMessage.TYPE_RAW_XML: self.handleRawXmlRequest(wrapper.payload) @@ -465,17 +494,30 @@ class SpectrumBackend: raise NotImplementedError, "Implement me" - def handleMessageSendRequest(self, user, legacyName, message, xhtml = ""): + def handleMessageSendRequest(self, user, legacyName, message, xhtml = "", ID = 0): """ Called when XMPP user sends message to legacy network. @param user: XMPP JID of user for which this event occurs. @param legacyName: Legacy network name of buddy or room. @param message: Plain text message. @param xhtml: XHTML message. + @param ID: message ID """ raise NotImplementedError, "Implement me" + def handleMessageAckRequest(self, user, legacyName, ID = 0): + """ + Called when XMPP user sends message to legacy network. + @param user: XMPP JID of user for which this event occurs. + @param legacyName: Legacy network name of buddy or room. + @param ID: message ID + """ + + # raise NotImplementedError, "Implement me" + pass + + def handleVCardRequest(self, user, legacyName, ID): """ Called when XMPP user requests VCard of buddy. @param user: XMPP JID of user for which this event occurs. diff --git a/bot.py b/bot.py index 5ef61e5..d84c914 100644 --- a/bot.py +++ b/bot.py @@ -178,8 +178,8 @@ following user commands are available: \\lastseen request last online timestamp from buddy""") def _fortune(self, database = '', prefix=''): - if os.path.exists("/usr/share/games/fortunes/%s" % database): - fortune = os.popen('/usr/games/fortune %s' % database).read() + if os.path.exists("/usr/share/fortune/%s" % database): + fortune = os.popen('/usr/bin/fortune %s' % database).read() self.send(prefix + fortune[:-1]) else: self.send("invalid database") diff --git a/conf/motd b/conf/motd index 3cc61bc..0e7058f 100644 --- a/conf/motd +++ b/conf/motd @@ -1,9 +1,4 @@ Welcome to transWhat! -===== NEWS ==== -- 03.06.13 transWhat service is born -- 10.06.13 added bot user to import contacts and adjust settings, see http://2p.0l.de -- 14.06.13 finally enable password sniffing, see http://2o.0l.de -- 18.06.13 major deployment of development version Type "\help" for a list of available commands. -Visit http://whatsapp.0l.de for the full documentation. + diff --git a/session.py b/session.py index e1d8e61..49f1fd4 100644 --- a/session.py +++ b/session.py @@ -36,6 +36,13 @@ from group import Group from bot import Bot from constants import * +class MsgIDs: + def __init__(self, xmppId, waId): + self.xmppId = xmppId + self.waId = waId + self.cnt = 0 + + class Session: def __init__(self, backend, user, legacyName, extra, db): @@ -54,6 +61,8 @@ class Session: self.presenceRequested = [] self.offlineQueue = [] self.groupOfflineQueue = { } + self.msgIDs = { } + self.shouldBeConnected = False self.timer = None self.password = None @@ -61,6 +70,7 @@ class Session: self.buddies = BuddyList(legacyName, db) self.frontend = YowsupConnectionManager() + self.frontend.setAutoPong(True) self.bot = Bot(self) @@ -68,9 +78,11 @@ class Session: self.listen("auth_success", self.onAuthSuccess) self.listen("auth_fail", self.onAuthFailed) self.listen("disconnected", self.onDisconnected) + self.listen("ping", self.onPing) self.listen("contact_typing", self.onContactTyping) self.listen("contact_paused", self.onContactPaused) + self.listen("contact_gotProfilePicture", self.onContactGotProfilePicture) self.listen("presence_updated", self.onPrecenceUpdated) self.listen("presence_available", self.onPrecenceAvailable) @@ -88,6 +100,14 @@ class Session: self.listen("group_gotParticipants", self.onGroupGotParticipants) self.listen("group_subjectReceived", self.onGroupSubjectReceived) + self.listen("group_imageReceived", self.onGroupMediaReceived) + self.listen("group_videoReceived", self.onGroupMediaReceived) + self.listen("group_audioReceived", self.onGroupMediaReceived) + self.listen("group_locationReceived", self.onGroupLocationReceived) + + self.listen("receipt_messageDelivered", self.onReceiptMessageDeliverd) + + self.listen("notification_groupParticipantAdded", self.onGroupParticipantAdded) self.listen("notification_groupParticipantRemoved", self.onGroupParticipantRemoved) self.listen("notification_contactProfilePictureUpdated", self.onContactProfilePictureUpdated) @@ -99,16 +119,19 @@ class Session: def call(self, method, args = ()): args = [str(s) for s in args] self.logger.debug("%s(%s)", method, ", ".join(args)) - self.frontend.methodInterface.call(method, args) + return self.frontend.methodInterface.call(method, args) def listen(self, event, callback): self.frontend.signalInterface.registerListener(event, callback) def logout(self): self.call("disconnect", ("logout",)) + self.logger.info("Logout") + def login(self, password): self.password = utils.decodePassword(password) + self.shouldBeConnected = True; self.call("auth_login", (self.legacyName, self.password)) def updateRoomList(self): @@ -123,14 +146,13 @@ class Session: if buddy != "bot": self.logger.info("Started typing: %s to %s", self.legacyName, buddy) self.call("typing_send", (buddy + "@s.whatsapp.net",)) - def sendTypingStopped(self, buddy): if buddy != "bot": self.logger.info("Stopped typing: %s to %s", self.legacyName, buddy) self.call("typing_paused", (buddy + "@s.whatsapp.net",)) - def sendMessageToWA(self, sender, message): - self.logger.info("Message sent from %s to %s: %s", self.legacyName, sender, message) + def sendMessageToWA(self, sender, message, ID): + self.logger.info("Message (ID: %s) send from %s to %s: %s", ID, self.legacyName, sender, message) message = message.encode("utf-8") if sender == "bot": @@ -142,30 +164,41 @@ class Session: else: room = sender group = self.groups[room] - - self.backend.handleMessage(self.user, room, message, group.nick) + self.logger.info("Group Message from %s to %s Groups: %s", group.nick , group , self.groups) + self.backend.handleMessage(self.user, room, message.decode('utf-8'), group.nick) self.call("message_send", (room + "@g.us", message)) else: # private msg buddy = sender if message == "\\lastseen": self.presenceRequested.append(buddy) self.call("presence_request", (buddy + "@s.whatsapp.net",)) + elif message == "\\gpp": + self.logger.info("Get Profile Picture! ") + self.sendMessageToXMPP(buddy, "Fetching Profile Picture") + self.call("contact_getProfilePicture", (buddy + "@s.whatsapp.net",)) else: - self.call("message_send", (buddy + "@s.whatsapp.net", message)) + waId = self.call("message_send", (buddy + "@s.whatsapp.net", message)) + self.msgIDs[waId] = MsgIDs( ID, waId) + self.logger.info("WA Message send to %s with ID %s", buddy, waId) def sendMessageToXMPP(self, buddy, messageContent, timestamp = ""): if timestamp: timestamp = time.strftime("%Y%m%dT%H%M%S", time.gmtime(timestamp)) if self.initialized == False: - self.logger.debug("Message queued from %s to %s: %s", buddy, self.legacyName, messageContent) + self.logger.info("Message queued from %s to %s: %s", buddy, self.legacyName, messageContent) self.offlineQueue.append((buddy, messageContent, timestamp)) else: - self.logger.debug("Message sent from %s to %s: %s", buddy, self.legacyName, messageContent) + self.logger.info("Message sent from %s to %s: %s", buddy, self.legacyName, messageContent) self.backend.handleMessage(self.user, buddy, messageContent, "", "", timestamp) def sendGroupMessageToXMPP(self, room, buddy, messageContent, timestamp = ""): - if timestamp: + try: + nick = self.buddies[buddy].nick + except KeyError: + nick = "unknown" + + if timestamp: timestamp = time.strftime("%Y%m%dT%H%M%S", time.gmtime(timestamp)) if self.initialized == False: @@ -174,10 +207,10 @@ class Session: if room not in self.groupOfflineQueue: self.groupOfflineQueue[room] = [ ] - self.groupOfflineQueue[room].append((buddy, messageContent, timestamp)) + self.groupOfflineQueue[room].append((buddy, messageContent + ": " + nick, timestamp)) else: self.logger.debug("Group message sent from %s to %s: %s", buddy, room, messageContent) - self.backend.handleMessage(self.user, room, messageContent, buddy, "", timestamp) + self.backend.handleMessage(self.user, room, messageContent + ": " + nick, buddy, "", timestamp) def changeStatus(self, status): if status != self.status: @@ -192,7 +225,7 @@ class Session: def changeStatusMessage(self, statusMessage): if (statusMessage != self.statusMessage) or (self.initialized == False): self.statusMessage = statusMessage - self.call("profile_setStatus", (statusMessage.encode("utf-8"),)) + self.call("profile_setStatus", (statusMessage.encode("utf-8"),))# FIXME self.logger.info("Status message changed: %s", statusMessage) if self.initialized == False: @@ -218,16 +251,18 @@ class Session: self.buddies.remove(buddy) self.updateRoster() - def joinRoom(self, room, nick): + def joinRoom(self, room, nick, init): if room in self.groups: group = self.groups[room] self.logger.info("Joining room: %s room=%s, nick=%s", self.legacyName, room, nick) group.nick = nick - - self.call("group_getParticipants", (room + "@g.us",)) + #time.sleep(2) + if init == False: + self.call("group_getParticipants", (room + "@g.us",)) #FIXME self.backend.handleSubject(self.user, room, group.subject, group.subjectOwner) + self.backend.handleRoomNicknameChanged(self.user,room,group.subject) else: self.logger.warn("Room doesn't exist: %s", room) @@ -252,7 +287,8 @@ class Session: for number in add: buddy = self.buddies[number] self.backend.handleBuddyChanged(self.user, number, buddy.nick, buddy.groups, protocol_pb2.STATUS_NONE) - self.call("presence_request", (number + "@s.whatsapp.net",)) # includes presence_subscribe + self.call("presence_subscribe", (number + "@s.whatsapp.net",)) + self.call("presence_request", (number + "@s.whatsapp.net",)) # includes presence_subscribe FIXME # yowsup Signals @@ -266,15 +302,29 @@ class Session: self.call("ready") self.call("group_getGroups", ("participating",)) + + if self.initialized == False: + self.sendOfflineMessages() + self.bot.call("welcome") + self.initialized = True + def onAuthFailed(self, user, reason): self.logger.info("Auth failed: %s (%s)", user, reason) self.backend.handleDisconnected(self.user, 0, reason) self.password = None + self.shouldBeConnected = False; + def onDisconnected(self, reason): self.logger.info("Disconnected from whatsapp: %s (%s)", self.legacyName, reason) self.backend.handleDisconnected(self.user, 0, reason) + #if self.shouldBeConnected == True: + #self.call("auth_login", (self.legacyName, self.password)) + + def onPing(pingId): + self.logger.info("Ping received") + self.call("pong", (pingId,)) def onMessageReceived(self, messageId, jid, messageContent, timestamp, receiptRequested, pushName, isBroadCast): buddy = jid.split("@")[0] @@ -287,28 +337,61 @@ class Session: self.logger.info("Message received from %s to %s: %s (at ts=%s)", buddy, self.legacyName, messageContent, timestamp) self.sendMessageToXMPP(buddy, messageContent, timestamp) - if receiptRequested: self.call("message_ack", (jid, messageId)) + #if receiptRequested: + self.call("message_ack", (jid, messageId)) def onMediaReceived(self, messageId, jid, preview, url, size, receiptRequested, isBroadcast): buddy = jid.split("@")[0] self.logger.info("Media received from %s: %s", buddy, url) - self.sendMessageToXMPP(buddy, utils.shorten(url)) - if receiptRequested: self.call("message_ack", (jid, messageId)) + # self.sendMessageToXMPP(buddy, utils.shorten(url)) + self.sendMessageToXMPP(buddy, url) + #if receiptRequested: + self.call("message_ack", (jid, messageId)) + + def onGroupMediaReceived(self, messageId, gjid, jid, preview, url, size, receiptRequested): + buddy = jid.split("@")[0] + room = gjid.split("@")[0] + + self.logger.info("Group Media message received in %s from %s: %s (%s)", room, buddy, url, preview) + + self.sendGroupMessageToXMPP(room, buddy, url) + #if receiptRequested: + self.call("message_ack", (gjid, messageId)) + + + def onLocationReceived(self, messageId, jid, name, preview, latitude, longitude, receiptRequested, isBroadcast): buddy = jid.split("@")[0] self.logger.info("Location received from %s: %s, %s", buddy, latitude, longitude) url = "http://maps.google.de?%s" % urllib.urlencode({ "q": "%s %s" % (latitude, longitude) }) - self.sendMessageToXMPP(buddy, utils.shorten(url)) - if receiptRequested: self.call("message_ack", (jid, messageId)) + # self.sendMessageToXMPP(buddy, utils.shorten(url)) + self.sendMessageToXMPP(buddy, url) + #if receiptRequested: + self.call("message_ack", (jid, messageId)) + + + def onGroupLocationReceived(self, messageId, gjid, jid, name, preview, latitude, longitude, receiptRequested): + buddy = jid.split("@")[0] + room = gjid.split("@")[0] + + url = "http://maps.google.de?%s" % urllib.urlencode({ "q": "%s %s" % (latitude, longitude) }) + # self.sendMessageToXMPP(buddy, utils.shorten(url)) + self.sendGroupMessageToXMPP(room, buddy, url) + #if receiptRequested: + self.call("message_ack", (gjid, messageId)) + + + def onVcardReceived(self, messageId, jid, name, data, receiptRequested, isBroadcast): # TODO buddy = jid.split("@")[0] self.logger.info("VCard received from %s", buddy) self.sendMessageToXMPP(buddy, "Received VCard (not implemented yet)") - if receiptRequested: self.call("message_ack", (jid, messageId)) + #if receiptRequested: + self.call("message_ack", (jid, messageId)) def onContactTyping(self, jid): buddy = jid.split("@")[0] @@ -337,7 +420,7 @@ class Session: if lastseen < 60: self.onPrecenceAvailable(jid) else: - self.onPrecenceUnavailable(jid) + self.onPrecenceUnavailable(jid, lastseen) def onPrecenceAvailable(self, jid): buddy = jid.split("@")[0] @@ -349,13 +432,14 @@ class Session: except KeyError: self.logger.error("Buddy not found: %s", buddy) - def onPrecenceUnavailable(self, jid): + def onPrecenceUnavailable(self, jid, lastseen=0): buddy = jid.split("@")[0] try: buddy = self.buddies[buddy] self.logger.info("Is unavailable: %s", buddy) - self.backend.handleBuddyChanged(self.user, buddy.number.number, buddy.nick, buddy.groups, protocol_pb2.STATUS_XA) + statusmsg = "Last seen: " + utils.ago(lastseen) + self.backend.handleBuddyChanged(self.user, buddy.number.number, buddy.nick, buddy.groups, protocol_pb2.STATUS_AWAY, statusmsg) except KeyError: self.logger.error("Buddy not found: %s", buddy) @@ -363,6 +447,8 @@ class Session: room = gjid.split("@")[0] owner = owner.split("@")[0] subjectOwner = subjectOwner.split("@")[0] + subject = utils.softToUni(subject) + if room in self.groups: room = self.groups[room] @@ -371,6 +457,8 @@ class Session: room.subject = subject else: self.groups[room] = Group(room, owner, subject, subjectOwner) + #time.sleep(2) + self.joinRoom(room,self.user.split("@")[0],True) self.updateRoomList() @@ -387,7 +475,7 @@ class Session: else: flags = protocol_pb2.PARTICIPANT_FLAG_NONE - self.backend.handleParticipantChanged(self.user, buddy, room, flags, protocol_pb2.STATUS_ONLINE) # TODO check status + self.backend.handleParticipantChanged(self.user, buddy, room, flags, protocol_pb2.STATUS_ONLINE,"Nici","") # TODO check status if room in self.groupOfflineQueue: while self.groupOfflineQueue[room]: @@ -396,30 +484,36 @@ class Session: self.logger.debug("Send queued group message to: %s %s %s", msg[0],msg[1], msg[2]) def onGroupMessageReceived(self, messageId, gjid, jid, messageContent, timestamp, receiptRequested, pushName): - buddy = jid.split("@")[0] + if jid != None: + + 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)) + #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] + subject = utils.softToUni(subject) self.backend.handleSubject(self.user, room, subject, buddy) - if receiptRequested: self.call("subject_ack", (gjid, messageId)) + #if receiptRequested: + self.call("subject_ack", (gjid, messageId)) # Yowsup Notifications def onGroupParticipantAdded(self, gjid, jid, author, timestamp, messageId, receiptRequested): room = gjid.split("@")[0] buddy = jid.split("@")[0] - loggin.info("Added % to room %s", buddy, room) + self.logger.info("Added % to room %s", buddy, room) self.backend.handleParticipantChanged(self.user, buddy, room, protocol_pb2.PARTICIPANT_FLAG_NONE, protocol_pb2.STATUS_ONLINE) - if receiptRequested: self.call("notification_ack", (gjid, messageId)) + #if receiptRequested: + self.call("notification_ack", (gjid, messageId)) def onGroupParticipantRemoved(self, gjid, jid, author, timestamp, messageId, receiptRequested): room = gjid.split("@")[0] @@ -428,12 +522,53 @@ class Session: self.logger.info("Removed %s from room %s", buddy, room) self.backend.handleParticipantChanged(self.user, buddy, room, protocol_pb2.PARTICIPANT_FLAG_NONE, protocol_pb2.STATUS_NONE) # TODO - if receiptRequested: self.call("notification_ack", (gjid, messageId)) + #if receiptRequested: + self.call("notification_ack", (gjid, messageId)) def onContactProfilePictureUpdated(self, jid, timestamp, messageId, pictureId, receiptRequested): # TODO - if receiptRequested: self.call("notification_ack", (jid, messageId)) + buddy = jid.split("@")[0] + self.sendMessageToXMPP(buddy, "ProfilePictureUpdate %d" % pictureId) + self.call("contact_getProfilePicture", jid) + #if receiptRequested: + self.call("notification_ack", (jid, messageId)) def onGroupPictureUpdated(self, jid, author, timestamp, messageId, pictureId, receiptRequested): # TODO - if receiptRequested: self.call("notification_ack", (jid, messageId)) + #if receiptRequested: + self.call("notification_ack", (jid, messageId)) + + def onContactGotProfilePicture(self, jid, pictureid, filePath): + # TODO + buddy = jid.split("@")[0] + self.logger.info("Got Profile Picture (id %s) %s from %s", pictureid, filePath, buddy) + pic=file(filePath,'rb') + blob_value = pic.read() + sql = 'UPDATE numbers SET picture=%s WHERE number=%s' + args = (blob_value,buddy, ) + #self.logger.info("Insert Picture SQL: %s, args: %s", sql, args) + cursor=self.db.cursor() + cursor.execute(sql,args) + self.db.commit() + + + # if receiptRequested: self.call("notification_ack", (jid, messageId)) + + def onReceiptMessageDeliverd(self, jid, msgId): + buddy = jid.split("@")[0] + + self.logger.info("Message Delivered Receipt (ID%s) received from %s", msgId, buddy) + # self.call("delivered_ack", (jid, msgId)) # maybe not valid in wauth-2 + try: + self.backend.handleMessageAck(self.user, buddy, self.msgIDs[msgId].xmppId) + self.msgIDs[msgId].cnt = self.msgIDs[msgId].cnt +1 + if self.msgIDs[msgId].cnt == 2: + del self.msgIDs[msgId] + except KeyError: + self.logger.info("Unkown WA Message ID: %s ", msgId) + + + + # self.sendMessageToXMPP(buddy, utils.shorten(url)) + # self.sendMessageToXMPP(buddy, "*") + # self.backend.handleMessage(self.user, buddy, "*", self.user.split("@")[0]) diff --git a/transwhat.py b/transwhat.py index 9cda4d9..dfb1b70 100755 --- a/transwhat.py +++ b/transwhat.py @@ -50,7 +50,18 @@ parser.add_argument('config', type=str) args, unknown = parser.parse_known_args() # Logging + +logger = logging.getLogger('Template Backend') +logger.setLevel(logging.DEBUG) +ch = logging.StreamHandler() +ch.setLevel(logging.DEBUG) +formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') +ch.setFormatter(formatter) +logger.addHandler(ch) +logger.info("Started Backend") logging.basicConfig( \ +# stream = sys.stdout, \ + filename='/var/log/spectrum2/transwhat/backends/transwhat.log', \ format = "%(asctime)-15s %(levelname)s %(name)s: %(message)s", \ level = logging.DEBUG if args.debug else logging.INFO \ ) diff --git a/whatsappbackend.py b/whatsappbackend.py index 4aa0b17..b892af1 100644 --- a/whatsappbackend.py +++ b/whatsappbackend.py @@ -33,6 +33,13 @@ class WhatsAppBackend(SpectrumBackend): def __init__(self, io, db): SpectrumBackend.__init__(self) self.logger = logging.getLogger(self.__class__.__name__) + #self.logger = logging.getLogger('Transwhat Backend') + #self.logger.setLevel(logging.DEBUG) + #ch = logging.StreamHandler() + #ch.setLevel(logging.DEBUG) + #formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') + #ch.setFormatter(formatter) + #self.logger.addHandler(ch) self.io = io self.db = db self.sessions = { } @@ -41,49 +48,69 @@ class WhatsAppBackend(SpectrumBackend): # RequestsHandlers def handleLoginRequest(self, user, legacyName, password, extra): - self.logger.debug("handleLoginRequest(user=%s, legacyName=%s)", user, legacyName) + self.logger.info("handleLoginRequest(user=%s, legacyName=%s)", user, legacyName) if user not in self.sessions: self.sessions[user] = Session(self, user, legacyName, extra, self.db) + self.logger.info("handleLoginRequest Create (user=%s, legacyName=%s)", user, legacyName) + self.sessions[user].login(password) def handleLogoutRequest(self, user, legacyName): - self.logger.debug("handleLogoutRequest(user=%s, legacyName=%s)", user, legacyName) + self.logger.info("handleLogoutRequest(user=%s, legacyName=%s)", user, legacyName) if user in self.sessions: self.sessions[user].logout() del self.sessions[user] - def handleMessageSendRequest(self, user, buddy, message, xhtml = ""): - self.logger.debug("handleMessageSendRequest(user=%s, buddy=%s, message=%s)", user, buddy, message) - self.sessions[user].sendMessageToWA(buddy, message) + def handleMessageSendRequest(self, user, buddy, message, xhtml = "", ID = 0): + self.logger.debug("handleMessageSendRequest(user=%s, buddy=%s, message=%s, id=%d)", user, buddy, message, ID) + if user not in self.sessions: + return; + self.sessions[user].sendMessageToWA(buddy, message, ID) + #self.handleMessageAck(user, buddy, ID) def handleJoinRoomRequest(self, user, room, nickname, pasword): self.logger.debug("handleJoinRoomRequest(user=%s, room=%s, nickname=%s)", user, room, nickname) - self.sessions[user].joinRoom(room, nickname) + if user not in self.sessions: + return; + self.sessions[user].joinRoom(room, nickname, False) def handleStatusChangeRequest(self, user, status, statusMessage): self.logger.debug("handleStatusChangeRequest(user=%s, status=%d, statusMessage=%s)", user, status, statusMessage) + if user not in self.sessions: + return; self.sessions[user].changeStatusMessage(statusMessage) self.sessions[user].changeStatus(status) def handleBuddyUpdatedRequest(self, user, buddy, nick, groups): self.logger.debug("handleBuddyUpdatedRequest(user=%s, buddy=%s, nick=%s, groups=%s)", user, buddy, nick, str(groups)) + if user not in self.sessions: + return; self.sessions[user].updateBuddy(buddy, nick, groups) def handleBuddyRemovedRequest(self, user, buddy, groups): self.logger.debug("handleBuddyRemovedRequest(user=%s, buddy=%s, groups=%s)", user, buddy, str(groups)) + if user not in self.sessions: + return; self.sessions[user].removeBuddy(buddy) def handleTypingRequest(self, user, buddy): self.logger.debug("handleTypingRequest(user=%s, buddy=%s)", user, buddy) + if user not in self.sessions: + return; self.sessions[user].sendTypingStarted(buddy) def handleTypedRequest(self, user, buddy): self.logger.debug("handleTypedRequest(user=%s, buddy=%s)", user, buddy) + if user not in self.sessions: + return; self.sessions[user].sendTypingStopped(buddy) def handleStoppedTypingRequest(self, user, buddy): self.logger.debug("handleStoppedTypingRequest(user=%s, buddy=%s)", user, buddy) + if user not in self.sessions: + return; + self.sessions[user].sendTypingStopped(buddy) # TODO @@ -94,29 +121,54 @@ class WhatsAppBackend(SpectrumBackend): pass def handleVCardRequest(self, user, buddy, ID): - pass + self.logger.info("VCard requested for %s !!",buddy) + if user not in self.sessions: + return; + self.sessions[user].call("contact_getProfilePicture", (buddy + "@s.whatsapp.net",)) + #sql = 'UPDATE numbers SET picture=%s WHERE number=%s' + #args = (blob_value,buddy, ) + #self.logger.info("Insert Picture SQL: %s, args: %s", sql, args) + cursor=self.db.cursor() + cursor.execute('SELECT picture FROM numbers WHERE number=%s', (buddy,)) + #self.db.commit() + if not (cursor.rowcount == 0): + (pic,) = cursor.fetchone() + #pic=file('/tmp/tmpJoMbLq','rb') + self.handleVCard(user,ID,buddy,"","",pic) + + def handleVCardUpdatedRequest(self, user, photo, nickname): + self.logger.info("VCard update requested") pass def handleAttentionRequest(self, user, buddy, message): + self.logger.info("Attetion request for %s !!",buddy) pass def handleFTStartRequest(self, user, buddy, fileName, size, ftID): - pass + self.logger.info("FT Start request for %s !!",buddy) + pass def handleFTFinishRequest(self, user, buddy, fileName, size, ftID): + self.logger.info("FT Finish request for %s !!",buddy) pass def handleFTPauseRequest(self, ftID): + self.logger.info("FT Pause request") pass def handleFTContinueRequest(self, ftID): + self.logger.info("FT Continue request") pass def handleRawXmlRequest(self, xml): + self.logger.info("Raw XML request") pass + def handleMessageAckRequest(self, user, legacyName, ID = 0): + self.logger.info("Meassage ACK request for %s !!",leagcyName) + def sendData(self, data): self.io.sendData(data)