From 19358e9c28bd451f5c875e28b025b48651187841 Mon Sep 17 00:00:00 2001 From: Colin Davis <cdavis@darkenedsky.com> Date: Tue, 5 Jul 2011 19:31:17 -0400 Subject: [PATCH] send as img --- static/images/out.png | Bin 16701 -> 0 bytes webfront.py | 113 ++++++++++++++++++++++++++++++------------ 2 files changed, 82 insertions(+), 31 deletions(-) delete mode 100644 static/images/out.png diff --git a/static/images/out.png b/static/images/out.png deleted file mode 100644 index f0ebe322e7e97b2e8e4ba1139847b95cfa09877e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16701 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 K(zTN2VgC<_!Ug#N diff --git a/webfront.py b/webfront.py index e3bc393..2dcf504 100755 --- a/webfront.py +++ b/webfront.py @@ -10,56 +10,107 @@ import tornado.web import tornado.escape import socket import re -import os +import robohash +import os import pprint import Image -import random +import hashlib +import urllib try: from hashlib import md5 as md5_func except ImportError: from md5 import new as md5_func -def getPNG(path): - completelist = [] - locallist = [] - for ls in os.listdir(path): - if not ls.startswith("."): - if os.path.isdir(path + "/" + ls): - subfiles = getPNG(path + "/" + ls) - if subfiles is not None: - completelist = completelist + subfiles - else: - locallist.append( path + "/" + ls) - - if len(locallist) > 0: - luckyelement = locallist[random.randrange(0,len(locallist))] - locallist = [] - locallist.append(luckyelement) - - completelist = completelist + locallist - return completelist - - -class MainHandler(tornado.web.RequestHandler): - def get(self): - #Generate a robohash- - hashlist = getPNG(random.choice(['blue','brown','green','orange','grey','pink','purple','red','white','yellow'])) +class Robohash(object): + def __init__(self,string): + hash = hashlib.sha512() + hash.update(string) + self.hexdigest = hash.hexdigest() + self.hasharray = [] + + def createHashes(self,count): + #Create and store a series of hash-values + #Basically, split up a hash (SHA/md5/etc) into X parts + for i in range(0,count): + #Get 1/numblocks of the hash + blocksize = (len(self.hexdigest) / count) + currentstart = (1 + i) * blocksize - blocksize + currentend = (1 +i) * blocksize + self.hasharray.append(int(self.hexdigest[currentstart:currentend],16)) + + def dirCount(self,path): + #return the count of just the directories beneath me. + return sum([len(dirs) for (root, dirs, files) in os.walk(path)]) + + def getHashList(self,map): + #Kinda a complicated function. + #Basically, we're recursively calling ourselves, and keeping track of the depth + #Since we use two return values, we're storing them in a map. + #Each iteration, if we hit a directory, recurse + #If not, choose the appropriate file, given the hashes, stored above + path = map['path'] + depth = map['depth'] + completelist = [] + locallist = [] + for ls in os.listdir(path): + if not ls.startswith("."): + if os.path.isdir(path + "/" + ls): + returnval = self.getHashList({'path': path + "/" + ls ,'depth': depth + 1}) + subfiles = returnval['completelist'] + if subfiles is not None: + completelist = completelist + subfiles + else: + locallist.append( path + "/" + ls) + + if len(locallist) > 0: + elementchoice = self.hasharray[map['depth']] % len (locallist) + luckyelement = locallist[elementchoice] + locallist = [] + locallist.append(luckyelement) + + completelist = completelist + locallist + return {'completelist':completelist,'depth':depth} + + + + + +class ImgHandler(tornado.web.RequestHandler): + def get(self,string=None): + self.content_type = 'application/json' + #Create a hash for the string as given + if string is None: + string = self.request.remote_ip + string = urllib.quote_plus(string) + r = Robohash(string) + r.createHashes(r.dirCount("blue")) + + #Change to a usuable format + if string.endswith(('.png','.gif','.jpg','bmp','im','jpeg','pcx','ppm','tiff','xbm')): + ext = string[string.rfind('.') +1 :len(string)] + else: + ext = "png" + self.set_header("Content-Type", "image/" + ext) + hashlist = r.getHashList({'path':"blue",'depth':0})['completelist'] hashlist.sort() + pprint.pprint(hashlist) robohash = Image.open(hashlist[0]) for png in hashlist: img = Image.open(png) robohash.paste(img,(0,0),img) - robohash.save("static/images/out.png") - self.write("Running in Random mode:<br>") - self.write("<img src='/images/out.png'>") + robohash.save(self,format=ext) + # self.write("Running in Random mode:<br>") + # self.write("<img src='/images/" + string + "'>") application = tornado.web.Application([ - (r"/", MainHandler), (r"/images/(.*)", tornado.web.StaticFileHandler, {"path": os.path.join(os.path.dirname(__file__), "static/images")}), + (r"/", ImgHandler), + (r"/(.*)", ImgHandler), + ]) if __name__ == "__main__":