/usr/share/pymsnt/src/avatar.py is in pymsnt 0.11.3+hg224-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | # Copyright 2005-2006 James Bunton <james@delx.cjb.net>
# Licensed for distribution under the GPL version 2, check COPYING for details
from debug import LogEvent, INFO, WARN, ERROR
from twisted.internet import reactor
from twisted.words.xish.domish import Element
import base64, os, os.path
try:
from hashlib import sha1
except ImportError:
from sha import sha as sha1
import utils
import config
SPOOL_UMASK = 0077
def parsePhotoEl(photo):
""" Pass the photo element as an avatar, returns the avatar imageData """
imageData = ""
imageType = ""
for e in photo.elements():
if(e.name == "BINVAL"):
imageData = base64.decodestring(e.__str__())
elif(e.name == "TYPE"):
imageType = e.__str__()
if(imageType != "image/png"):
imageData = utils.convertToPNG(imageData)
return imageData
class Avatar:
""" Represents an Avatar. Does not store the image in memory. """
def __init__(self, imageData, avatarCache):
self.__imageHash = sha1(imageData).hexdigest()
self.__avatarCache = avatarCache
def getImageHash(self):
""" Returns the SHA1 hash of the avatar. """
return self.__imageHash
def getImageData(self):
""" Returns this Avatar's imageData. This loads data from a file. """
return self.__avatarCache.getAvatarData(self.__imageHash)
def makePhotoElement(self):
""" Returns an XML Element that can be put into the vCard. """
photo = Element((None, "PHOTO"))
cType = photo.addElement("TYPE")
cType.addContent("image/png")
binval = photo.addElement("BINVAL")
binval.addContent(base64.encodestring(self.getImageData()).replace("\n", ""))
return photo
def makeDataElement(self):
""" Returns an XML Element that can be put into a jabber:x:avatar IQ stanza. """
data = Element((None, "data"))
data["mimetype"] = "image/png"
data.addContent(base64.encodestring(self.getImageData()).replace("\n", ""))
return data
def __eq__(self, other):
return (other and self.__imageHash == other.__imageHash)
class AvatarCache:
""" Manages avatars on disk. Avatars are stored according to their SHA1 hash.
The layout is config.spooldir / config.jid / avatars / "first two characters of SHA1 hash" """
def dir(self, key):
""" Returns the full path to the directory that a
particular key is in. Creates that directory if it doesn't already exist. """
X = os.path.sep
d = os.path.os.path.abspath(config.spooldir) + X + "avatars" + X + key[0:3] + X
if not os.path.exists(d):
os.makedirs(d)
return d
def setAvatar(self, imageData):
""" Writes an avatar to disk according to its key.
Returns an Avatar object. """
avatar = Avatar(imageData, self)
key = avatar.getImageHash()
LogEvent(INFO, "", "Setting avatar %s" % (key))
prev_umask = os.umask(SPOOL_UMASK)
try:
f = open(self.dir(key) + key, 'wb')
f.write(imageData)
f.close()
except (OSError, IOError), e:
LogEvent(WARN, "", "IOError writing to avatar %s - %s" % (key, str(e)))
os.umask(prev_umask)
return avatar
def getAvatar(self, key):
""" Loads the avatar with SHA1 hash of 'key' from disk and returns an Avatar object """
imageData = self.getAvatarData(key)
if imageData:
return Avatar(imageData, self)
else:
return None
def getAvatarData(self, key):
""" Loads the avatar with SHA1 hash of 'key' from disk and returns the data """
try:
filename = self.dir(key) + key
if os.path.isfile(filename):
LogEvent(INFO, "Getting avatar.")
f = open(filename, "rb")
data = f.read()
f.close()
return data
else:
LogEvent(INFO, "", "Avatar not found.")
except (OSError, IOError):
LogEvent(WARN, "", "IOError reading avatar.")
else:
return None
|