Welcome to mirror list, hosted at ThFree Co, Russian Federation.

avatar_hash.py « extensions - github.com/mrDoctorWho/vk4xmpp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 85b0ca0d0f9e53db291d314a19e03267a67c804b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# coding: utf-8
# This file is a part of VK4XMPP transport
# © simpleApps, 2014 (30.08.14 14:58PM GMT) — 2015.

from hashlib import sha1

"""
Implements XEP-0153: vCard-Based Avatars
"""

class AvatarHash(object):
	def __init__(self):
		runDatabaseQuery("create table if not exists avatar_hash "
			"(id text unique, sha text, updated integer)", set=True)

		self.baseHash = self.hashPhotos([{"uid": TransportID, "photo": URL_VCARD_NO_IMAGE}])
		self.pending = set([])

	join = lambda uids: ",".join([str(uid) for uid in uids])
	join = staticmethod(join)

	def getLocalHashes(self, uids):
		data = runDatabaseQuery("select id, sha, updated from avatar_hash where id in (%s)" % self.join(uids)) or []
		result = {}
		for key in data:
			uid, (sha, updated) = int(key[0]), key[1:]
			if (time.time() - updated) >= PHOTO_LIFE_DURATION:  # Better to send something instead of nothing
				self.pending.add(uid)
			result[uid] = sha
		result.update(self.baseHash)
		return result

	def getPhotos(self, user, uids=None):
		length = len(uids)
		data = []
		if length > PHOTO_REQUEST_LIMIT:
			for i in xrange(0, length, PHOTO_REQUEST_LIMIT):
				current = uids[i:i+PHOTO_REQUEST_LIMIT]
				data += self.sendPhotoRequest(user, current)
		else:
			data = self.sendPhotoRequest(user, uids)
		return data

	def sendPhotoRequest(self, user, uids):
		data = user.vk.method("execute.getPhotos_new",
			{"users": self.join(uids), "size": PhotoSize}) or []
		return data

	def hashPhotos(self, photos):
		result = {}
		for key in photos:
			url, uid = key["photo"], key["uid"]
			result[uid] = sha1(utils.getLinkData(url, False)).hexdigest()
		return result

	def getHashes(self, user, uids):
		photos = self.getPhotos(user, uids)
		hashes = self.hashPhotos(photos)
		date = time.time()
		return (hashes, date)

	def makeHashes(self, user, uids=None):
		uids = uids or user.friends.keys()
		local = self.getLocalHashes(uids)
		if len(local) > 1:
			for uid in uids:
				if uid not in local:
					self.pending.add(uid)
		else:
			logger.debug("avatar_hash: updating hash database for user (jid: %s)", user.source)
			hashes, date = self.getHashes(user, uids)
			if hashes:
				sql = "insert into avatar_hash (id, sha, updated) values "
				for uid, value in hashes.iteritems():
					sql += "(%s, %s, %s)," % (uid, repr(value), date)
					local[uid] = value
				runDatabaseQuery(sql[:-1], set=True)
		local.update(self.baseHash)
		return local

	def updateHashes(self, user):
		hashes, date = self.getHashes(user, list(self.pending))
		for uid, hash in hashes.iteritems():
			runDatabaseQuery("update avatar_hash set sha=?, updated=? where id=?", (hash, date, uid), set=True)


def addPresenceHash(prs, destination, source):
	if destination in Transport and not prs.getType():
		user = Transport[destination]
		if user.settings.avatar_hash:
			x = prs.setTag("x", namespace=xmpp.NS_VCARD_UPDATE)
			uid = vk2xmpp(source)
			hashes = getattr(user, "hashes", {})
			if not hashes:
				user.hashes = hashes = Avatars.getLocalHashes(user.friends)
			hash = hashes.get(uid)
			if hash:
				x.setTagData("photo", hash)

@utils.threaded
def handleQueue():
	while ALIVE:
		if Queue:
			user = Queue.pop()
			user.hashes = Avatars.makeHashes(user)
			if Avatars.pending:
				utils.runThread(Avatars.updateHashes, (user,))
				Avatars.pending = set([])
		time.sleep(10)


def addUserToQueue(user):
	Queue.add(user)


if isdef("ENABLE_PHOTO_HASHES") and ENABLE_PHOTO_HASHES:
	if not isdef("PHOTO_REQUEST_LIMIT"):
		PHOTO_REQUEST_LIMIT = 280  # 280 folks
	if not isdef("PHOTO_LIFE_DURATION"):
		PHOTO_LIFE_DURATION = 604800  # 1 week
	Avatars = AvatarHash()
	Queue = set([])
	GLOBAL_USER_SETTINGS["avatar_hash"] = {"label": "Show my friends avatars", "value": 0}
	logger.debug("extension avatar_hash is loaded")
	registerHandler("evt01", handleQueue)
	registerHandler("evt05", addUserToQueue)
	registerHandler("prs02", addPresenceHash)

else:
	del AvatarHash, addPresenceHash, handleQueue, addUserToQueue