def getHashList(self,path_): #Each iteration, if we hit a directory, recurse #If not, choose the appropriate file, given the hashes, stored above completelist = [] locallist = [] path = robohash.get_data(path_) listdir = os.listdir(path) listdir.sort() for ls in listdir: if not ls.startswith("."): if os.path.isdir(path + "/" + ls): subfiles = self.getHashList(path + "/" + ls) if subfiles is not None: completelist = completelist + subfiles else: locallist.append( path + "/" + ls) if len(locallist) > 0: elementchoice = self.hasharray[self.iter] % len(locallist) luckyelement = locallist[elementchoice] locallist = [] locallist.append(luckyelement) self.iter += 1 completelist = completelist + locallist return completelist
def get(self,string=None): # gravatar is picky, it hates quers strings, allow us to fake them by using a uri # /abc.png/s_100x100/set_any = /abc.png?set=any&s=100x100 # # we use underscore as a replacement for = and / as a replacement for [&?] args = self.request.arguments.copy() for k in args.keys(): v = args[k] if type(v) is list: if len(v) > 0: args[k] = args[k][0] else: args[k] = "" # IF, and Only IF, there is an arg in the list, should we interpret slashes as params split = string.split('/') if len(split) > 1: for st in split: b = st.encode('ascii','ignore').split('_') if len(b) == 2: if b[0] in ['gravatar','ignoreext','size','set','bgset','color']: args[b[0]] = b[1] string = split[len(split)-1] colors = ['blue','brown','green','grey','orange','pink','purple','red','white','yellow'] sets = ['set1','set2','set3'] bgsets = ['bg1','bg2'] #Create a hash for the string as given if string is None: string = self.request.remote_ip # string = urllib.quote_plus(string) if "ignoreext" in args: client_ignoreext = tornado.escape.xhtml_escape(args["ignoreext"]) else: client_ignoreext = None #Change to a usuable format if string.endswith(('.png','.gif','.jpg','.bmp','.jpeg','.ppm','.datauri')): ext = string[string.rfind('.') +1 :len(string)] if ext.lower() == 'jpg': ext = 'jpeg' else: ext = "png" if client_ignoreext != "false": if string.endswith(('.png','.gif','.jpg','.bmp','.jpeg','.ppm','.datauri')): string = string[0:string.rfind('.')] r = Robohash(string) #Create 10 hashes. This should be long enough for the current crop of variables. #This is probably not insecure, sicne we'd be modding anyway. This just spreads it out more. r.createHashes(11) #Now, customize the request if possible. client_color = "" client_set = "" client_bgset = "" sizex = 300 sizey = 300 if "size" in args: sizelist = args["size"].split(tornado.escape.xhtml_escape("x"),3) if ((int(sizelist[0]) > 0) and (int(sizelist[0]) < 4096)): sizex = int(sizelist[0]) if ((int(sizelist[0]) > 0) and (int(sizelist[0]) < 4096)): sizey = int(sizelist[1]) if "gravatar" in args: if tornado.escape.xhtml_escape(args["gravatar"]) == 'yes': default = "404" # construct the url gravatar_url = "https://secure.gravatar.com/avatar/" + hashlib.md5(string.lower()).hexdigest() + "?" gravatar_url += urllib.urlencode({'default':default, 'size':str(sizey)}) if tornado.escape.xhtml_escape(args["gravatar"]) == 'hashed': string = urllib.quote(string) default = "404" # construct the url gravatar_url = "https://secure.gravatar.com/avatar/" + string + "?" gravatar_url += urllib.urlencode({'default':default, 'size':str(sizey)}) try: f = urllib2.urlopen(urllib2.Request(gravatar_url)) self.redirect(gravatar_url, permanent=False) return 0 except: badGravatar = True if "set" in args: if tornado.escape.xhtml_escape(args["set"]) == 'any': client_set = sets[r.hasharray[1] % len(sets) ] if args["set"] in sets: client_set = tornado.escape.xhtml_escape(args["set"]) else: #If no set specified, you get set 1 client_set = "set1" ##Let people define multiple sets, so I can add more. if "sets" in args: newsets = tornado.escape.xhtml_escape(args["sets"]).split(","); replaceset = [] for s in newsets: if s in sets: replaceset.append(s) client_set = replaceset[r.hasharray[1] % len(replaceset) ] if client_set == 'set1': client_set = colors[r.hasharray[0] % len(colors) ] if "color" in args: if args["color"] in colors: client_set = tornado.escape.xhtml_escape(args["color"]) if "bgset" in args: if args["bgset"] in bgsets: client_bgset = tornado.escape.xhtml_escape(args["bgset"]) else: client_bgset = bgsets[r.hasharray[2] % len(bgsets) ] #If they don't specify a color, use hashvalue if ((client_color == "") and (client_set == "")): client_set = colors[r.hasharray[0] % len(colors) ] self.set_header("Content-Type", "image/" + ext) hashlist = r.getHashList(client_set) #OK, here's where we do some creative sorting. #Basically, we have two integers before every file #The first one ensure FS order, which is necessary to match the RH.org server #The second one ensures build order. #The FS order is only necessary during picking elements. Now, we want the second sort #So create a new list, ordered by the second integer hlcopy = [] for element in hashlist: element = element[0:element.find("/",element.find("#") -4) +1] + element[element.find("#") +1:len(element)] hlcopy.append(element) #Now, combine them into tuples, and sort. A tuples list always sorts by the FIRST element. duality = zip(hlcopy,hashlist) duality.sort() pprint.pprint(duality) hlcopy,hashlist = zip(*duality) pprint.pprint(hlcopy) print "------" pprint.pprint(hashlist) rhash = Image.open(hashlist[0]) rhash = rhash.resize((1024,1024)) for png in hashlist: img = Image.open(png) img = img.resize((1024,1024)) rhash.paste(img,(0,0),img) if ext == 'bmp': #Flatten bmps r, g, b, a = rhash.split() rhash = Image.merge("RGB", (r, g, b)) if client_bgset is not "": bglist = [] path = robohash.get_data(client_bgset) backgrounds = os.listdir(path) backgrounds.sort() for ls in backgrounds: if not ls.startswith("."): bglist.append(path + "/" + ls) bg = Image.open(bglist[r.hasharray[3] % len(bglist)]) bg = bg.resize((1024,1024)) bg.paste(rhash,(0,0),rhash) rhash = bg rhash = rhash.resize((sizex,sizey),Image.ANTIALIAS) if ext != 'datauri': rhash.save(self,format=ext) else: fakefile = cStringIO.StringIO() rhash.save(fakefile,format='jpeg') fakefile.seek(0) data_uri = fakefile.read().encode("base64").replace("\n", "") self.write("data:image/jpeg;base64," + data_uri)