diff options
Diffstat (limited to 'sca-cpp/trunk/hosting/server/pictures.py')
-rw-r--r-- | sca-cpp/trunk/hosting/server/pictures.py | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/sca-cpp/trunk/hosting/server/pictures.py b/sca-cpp/trunk/hosting/server/pictures.py new file mode 100644 index 0000000000..fab7df47ce --- /dev/null +++ b/sca-cpp/trunk/hosting/server/pictures.py @@ -0,0 +1,141 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# Pictures collection implementation +from StringIO import StringIO +try: + from PIL import Image +except: + Image = None +from base64 import b64encode, b64decode +from urllib import urlopen +from util import * +from atomutil import * +from sys import debug + +# Convert a particular user id to a picture id +def pictureid(id): + return ('accounts', id, 'user.picture') + +# Convert image to a 50x50 PNG image +def to50x50png(url): + debug('pictures.py::to50x50png::url', url) + if Image is None: + return url + img = Image.open(StringIO(b64decode(url.split(',')[1])) if url.startswith('data:') else StringIO(urlopen(url).read())) + t = img.resize((50, 50)) + obuf = StringIO() + t.save(obuf, 'PNG') + return 'data:image/png;base64,' + b64encode(obuf.getvalue()).replace('\n', '') + +# Update the user's picture +def put(id, picture, user, cache): + debug('pictures.py::put::id', id) + debug('pictures.py::put::picture', picture) + + picid = user.get(()) if isNil(id) else car(id) + + # Only the admin can update other user's pictures + if picid != user.get(()) and user.get(()) != 'admin': + debug('pictures.py::put', 'not owner or admin', user.get(())) + return False + + # Get image and token from input picture + def image(c): + img = assoc("'image", c) + return None if isNil(img) else to50x50png(cadr(img)) + def token(c): + tok = assoc("'token", c) + return None if isNil(tok) else cadr(tok) + img = image(content(picture)) + tok = token(content(picture)) + + # Update the picture + # Put with an upload token + if not isNil(tok): + debug('pictures.py::put::token', tok) + + # Token alone, store token with existing image, if any + if isNil(img): + epicture = cache.get(pictureid(picid)) + eimg = None if isNil(epicture) else image(content(epicture)) + if isNil(eimg): + picentry = mkentry(title(picture), picid, picid, now(), ("'picture", ("'token", tok))) + debug('pictures.py::put::picentry', picentry) + return cache.put(pictureid(picid), picentry) + + debug('pictures.py::put::eimg', eimg) + picentry = mkentry(title(picture), picid, picid, now(), ("'picture", ("'image", eimg), ("'token", tok))) + debug('pictures.py::put::picentry', picentry) + return cache.put(pictureid(picid), picentry) + + # Token plus image, put image if token is valid, removing the token + debug('pictures.py::put::img', img) + epicture = cache.get(pictureid(picid)) + etok = None if isNil(epicture) else token(content(epicture)) + debug('pictures.py::put::etok', etok) + if isNil(etok) or tok != etok: + debug('pictures.py::put', 'invalid token', tok) + return False + + picentry = mkentry(title(picture), picid, picid, now(), ("'picture", ("'image", img))) + debug('pictures.py::put::picentry', picentry) + return cache.put(pictureid(picid), picentry) + + # Update picture image + if not isNil(img): + debug('pictures.py::put::img', img) + picentry = mkentry(title(picture), picid, picid, now(), ("'picture", ("'image", img))) + debug('pictures.py::put::picentry', picentry) + return cache.put(pictureid(picid), picentry) + + # Put default empty picture + picentry = mkentry(title(picture), picid, picid, now(), ()) + debug('pictures.py::put::picentry', picentry) + return cache.put(pictureid(picid), picentry) + +# Get a user's picture +def get(id, user, cache): + debug('pictures.py::get::id', id) + + # Get the requested picture + picid = user.get(()) if isNil(id) else car(id) + picture = cache.get(pictureid(picid)) + if isNil(picture): + return mkentry(picid, picid, picid, now(), ()) + + # Get image and token from picture + def image(c): + img = assoc("'image", c) + return None if isNil(img) else cadr(img) + def token(c): + tok = assoc("'token", c) + return None if isNil(tok) else cadr(tok) + img = image(content(picture)) + tok = token(content(picture)) + + # Return the picture + picc = (() if isNil(img) else (("'image", img),)) + (() if isNil(tok) or (user.get(()) != author(picture) and user.get(()) != 'admin') else (("'token", tok),)) + if isNil(picc): + picentry = mkentry(title(picture), picid, author(picture), updated(picture), ()) + debug('pictures.py::get::picentry', picentry) + return picentry + + picentry = mkentry(title(picture), picid, author(picture), updated(picture), ("'picture",) + picc) + debug('pictures.py::get::picentry', picentry) + return picentry + |