Download whatsapp profile pictures
Everytime the user requests a VCard the profile pictures are updated. The sha1hash hash of the picture is calculated and stored in buddy.
This commit is contained in:
parent
d2efa0dd7b
commit
4fd313e516
31
buddy.py
31
buddy.py
|
@ -48,7 +48,7 @@ class Number():
|
|||
|
||||
|
||||
class Buddy():
|
||||
def __init__(self, owner, number, nick, groups, id, db):
|
||||
def __init__(self, owner, number, nick, groups, image_hash, id, db):
|
||||
self.id = id
|
||||
self.db = db
|
||||
|
||||
|
@ -56,14 +56,16 @@ class Buddy():
|
|||
self.owner = owner
|
||||
self.number = number
|
||||
self.groups = groups
|
||||
self.image_hash = image_hash
|
||||
|
||||
def update(self, nick, groups):
|
||||
def update(self, nick, groups, image_hash):
|
||||
self.nick = nick
|
||||
self.groups = groups
|
||||
self.image_hash = image_hash
|
||||
|
||||
groups = u",".join(groups).encode("latin-1")
|
||||
cur = self.db.cursor()
|
||||
cur.execute("UPDATE buddies SET nick = %s, groups = %s WHERE owner_id = %s AND buddy_id = %s", (self.nick, groups, self.owner.id, self.number.id))
|
||||
cur.execute("UPDATE buddies SET nick = %s, groups = %s, image_hash = %s WHERE owner_id = %s AND buddy_id = %s", (self.nick, groups, image_hash, self.owner.id, self.number.id))
|
||||
self.db.commit()
|
||||
|
||||
def delete(self):
|
||||
|
@ -73,13 +75,13 @@ class Buddy():
|
|||
self.id = None
|
||||
|
||||
@staticmethod
|
||||
def create(owner, number, nick, groups, db):
|
||||
def create(owner, number, nick, groups, image_hash, db):
|
||||
groups = u",".join(groups).encode("latin-1")
|
||||
cur = db.cursor()
|
||||
cur.execute("REPLACE buddies (owner_id, buddy_id, nick, groups) VALUES (%s, %s, %s, %s)", (owner.id, number.id, nick, groups))
|
||||
cur.execute("REPLACE buddies (owner_id, buddy_id, nick, groups, image_hash) VALUES (%s, %s, %s, %s, %s)", (owner.id, number.id, nick, groups, image_hash))
|
||||
db.commit()
|
||||
|
||||
return Buddy(owner, number, nick, groups, cur.lastrowid, db)
|
||||
return Buddy(owner, number, nick, groups, image_hash, cur.lastrowid, db)
|
||||
|
||||
def __str__(self):
|
||||
return "%s (nick=%s, id=%s)" % (self.number, self.nick, self.id)
|
||||
|
@ -99,7 +101,8 @@ class BuddyList(dict):
|
|||
n.number AS number,
|
||||
b.nick AS nick,
|
||||
b.groups AS groups,
|
||||
n.state AS state
|
||||
n.state AS state,
|
||||
b.image_hash AS image_hash
|
||||
FROM buddies AS b
|
||||
LEFT JOIN numbers AS n
|
||||
ON b.buddy_id = n.id
|
||||
|
@ -109,20 +112,20 @@ class BuddyList(dict):
|
|||
ORDER BY b.owner_id DESC""", self.owner.id)
|
||||
|
||||
for i in range(cur.rowcount):
|
||||
id, number, nick, groups, state = cur.fetchone()
|
||||
self[number] = Buddy(self.owner, Number(number, state, self.db), nick.decode('latin1'), groups.split(","), id, self.db)
|
||||
id, number, nick, groups, state, image_hash = cur.fetchone()
|
||||
self[number] = Buddy(self.owner, Number(number, state, self.db), nick.decode('latin1'), groups.split(","), image_hash, id, self.db)
|
||||
|
||||
def update(self, number, nick, groups):
|
||||
def update(self, number, nick, groups, image_hash):
|
||||
if number in self:
|
||||
buddy = self[number]
|
||||
buddy.update(nick, groups)
|
||||
buddy.update(nick, groups, image_hash)
|
||||
else:
|
||||
buddy = self.add(number, nick, groups, 1)
|
||||
buddy = self.add(number, nick, groups, 1, image_hash)
|
||||
|
||||
return buddy
|
||||
|
||||
def add(self, number, nick, groups = [], state = 0):
|
||||
return Buddy.create(self.owner, Number(number, state, self.db), nick, groups, self.db)
|
||||
def add(self, number, nick, groups = [], state = 0, image_hash = ""):
|
||||
return Buddy.create(self.owner, Number(number, state, self.db), nick, groups, image_hash, self.db)
|
||||
|
||||
def remove(self, number):
|
||||
try:
|
||||
|
|
|
@ -13,6 +13,7 @@ CREATE TABLE IF NOT EXISTS `buddies` (
|
|||
`buddy_id` int(11) NOT NULL,
|
||||
`nick` varchar(255) NOT NULL,
|
||||
`groups` varchar(255) NOT NULL,
|
||||
`image_hash` varchar(40),
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
|
|
19
session.py
19
session.py
|
@ -110,6 +110,7 @@ class Session(YowsupApp):
|
|||
for number in add:
|
||||
buddy = self.buddies[number]
|
||||
self.subscribePresence(number)
|
||||
self.backend.handleBuddyChanged(self.user, number, buddy.nick, buddy.groups, protocol_pb2.STATUS_NONE, iconHash = buddy.image_hash if buddy.image_hash is not None else "")
|
||||
self.requestLastSeen(number, self._lastSeen)
|
||||
|
||||
def _lastSeen(self, number, seconds):
|
||||
|
@ -368,9 +369,9 @@ 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):
|
||||
def updateBuddy(self, buddy, nick, groups, image_hash =""):
|
||||
if buddy != "bot":
|
||||
self.buddies.update(buddy, nick, groups)
|
||||
self.buddies.update(buddy, nick, groups, image_hash)
|
||||
self.updateRoster()
|
||||
|
||||
def removeBuddy(self, buddy):
|
||||
|
@ -392,6 +393,20 @@ class Session(YowsupApp):
|
|||
else:
|
||||
self.logger.warn("Room doesn't exist: %s", room)
|
||||
|
||||
def requestVCard(self, buddy, ID):
|
||||
|
||||
def onSuccess(response, request):
|
||||
self.logger.debug('Sending VCard (%s) with image id %s',
|
||||
ID, response.pictureId)
|
||||
image_hash = utils.sha1hash(response.pictureData)
|
||||
self.logger.debug('Image hash is %s', image_hash)
|
||||
self.backend.handleVCard(self.user, ID, buddy, "", "", response.pictureData)
|
||||
obuddy = self.buddies[buddy]
|
||||
self.updateBuddy(buddy, obuddy.nick, obuddy.groups, image_hash)
|
||||
|
||||
self.logger.debug('Requesting profile picture of %s', buddy)
|
||||
self.requestProfilePicture(buddy, onSuccess = onSuccess)
|
||||
|
||||
# Not used
|
||||
def onLocationReceived(self, messageId, jid, name, preview, latitude, longitude, receiptRequested, isBroadcast):
|
||||
buddy = jid.split("@")[0]
|
||||
|
|
4
utils.py
4
utils.py
|
@ -26,6 +26,7 @@ import urllib
|
|||
import json
|
||||
import e4u
|
||||
import base64
|
||||
import hashlib
|
||||
|
||||
def shorten(url):
|
||||
url = urllib.urlopen("http://d.0l.de/add.json?type=URL&rdata=%s" % urllib.quote(url))
|
||||
|
@ -61,3 +62,6 @@ def softToUni(message):
|
|||
|
||||
def decodePassword(password):
|
||||
return base64.b64decode(bytes(password.encode("utf-8")))
|
||||
|
||||
def sha1hash(data):
|
||||
return hashlib.sha1(data).hexdigest()
|
||||
|
|
|
@ -101,6 +101,10 @@ class WhatsAppBackend(SpectrumBackend):
|
|||
self.logger.debug("handleStoppedTypingRequest(user=%s, buddy=%s)", user, buddy)
|
||||
self.sessions[user].sendTypingStopped(buddy)
|
||||
|
||||
def handleVCardRequest(self, user, buddy, ID):
|
||||
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
|
||||
|
@ -108,9 +112,6 @@ class WhatsAppBackend(SpectrumBackend):
|
|||
def handleLeaveRoomRequest(self, user, room):
|
||||
pass
|
||||
|
||||
def handleVCardRequest(self, user, buddy, ID):
|
||||
pass
|
||||
|
||||
def handleVCardUpdatedRequest(self, user, photo, nickname):
|
||||
pass
|
||||
|
||||
|
|
|
@ -206,13 +206,24 @@ class YowsupApp(object):
|
|||
- failure: (func) called when request has failed
|
||||
"""
|
||||
iq = LastseenIqProtocolEntity(phoneNumber + '@s.whatsapp.net')
|
||||
self.sendIq(iq, self._lastSeenSuccess(success), failure)
|
||||
self.sendIq(iq, onSuccess = self._lastSeenSuccess(success), onError = failure)
|
||||
|
||||
def _lastSeenSuccess(self, success):
|
||||
def func(response, request):
|
||||
success(response._from.split('@')[0], response.seconds)
|
||||
return func
|
||||
|
||||
def requestProfilePicture(self, phoneNumber, onSuccess = None, onFailure = None):
|
||||
"""
|
||||
Requests profile picture of whatsapp user
|
||||
Args:
|
||||
- phoneNumber: (str) the phone number of the user
|
||||
- success: (func) called when request is successfully processed.
|
||||
- failure: (func) called when request has failed
|
||||
"""
|
||||
iq = GetPictureIqProtocolEntity(phoneNumber + '@s.whatsapp.net')
|
||||
self.sendIq(iq, onSuccess = onSuccess, onError = onFailure)
|
||||
|
||||
def onAuthSuccess(self, status, kind, creation, expiration, props, nonce, t):
|
||||
"""
|
||||
Called when login is successful.
|
||||
|
|
Loading…
Reference in a new issue