def get(self): lat = self.get_argument("lat") lon = self.get_argument("lon") user_tastes = self.redis.smembers("tastes::like::%s" % self.email) user_dislikes = self.redis.smembers("tastes::dislike::%s" % self.email) user_history = self.redis.lrange("places::history::%s" % self.email, 0, 5) place_reasons_key = "places::reasons::%s::%%s" % self.email place_scores = "places::score::%s" % str(uuid.uuid4()) self.redis.delete(place_scores) self.reason_keys = set() def process_businesses(businesses): for business in businesses: key = business["factual_id"] reason_key = place_reasons_key % key self.reason_keys.add(reason_key) score = 0 if business["$distance"] < 500: self.redis.sadd(reason_key, "distance") score += 1 else: distance = business["$distance"] if distance > 1000: distance -= 1000 score -= math.floor(distance / 500) # TODO: Add some sort of alternate lookup for the rating if it # isn't present. if "rating" in business: place_rating = business["rating"] if place_rating > 4: self.redis.sadd(reason_key, "great_rating") score += 2 elif place_rating > 3: self.redis.sadd(reason_key, "good_rating") score += 1 for category in business["cuisine"].split(", "): if category in user_dislikes: score -= 4 elif category in user_tastes: score += 3 self.redis.sadd(reason_key, "like:%s" % category) if key in user_history: score -= 3 else: self.redis.sadd(reason_key, "notrecent") # Add the data to redis for this session print place_scores, score, key self.redis.zadd(place_scores, key, score) def place_callback(data): # Generate a score for each venue. process_businesses(data) # Get the place with the best score. pick = self.redis.zrevrange(place_scores, 0, 1)[0] # Get the reasons for picking pick_reasons = self.redis.smembers(place_reasons_key % pick) # Delete all the used keys from Redis. map(self.redis.delete, self.reason_keys) self.redis.delete(place_scores) def pick_output(data): self.write({"result": "okay", "business": data, "reasons": list(pick_reasons), "stars": data["rating"] if "rating" in data else 3}) self.finish() print "Finished" print "Picked %s" % pick business_data(pick_output, pick, redis=self.redis) self.redis.lpush("places::history::%s" % self.email, pick) print "Searching Factual" fact_search(place_callback, latitude=lat, longitude=lon, categories=user_tastes, redis=self.redis)
def _render_choices(self, group_id, lat, lon): members = self.redis.smembers("group::%s" % group_id) user_tastes = self.redis.sunion(map(lambda i: "tastes::like::%s" % i, members)) user_dislikes = self.redis.sunion(map(lambda i: "tastes::dislike::%s" % i, members)) print "Tastes: ", user_tastes print "Dislikes: ", user_dislikes histories = set() for member in members: for h in self.redis.lrange("places::history::%s" % member, 0, 3): histories.add(h) place_scores = "places::group_score::%s" % group_id self.redis.delete(place_scores) def process_businesses(businesses): for business in businesses: key = business["factual_id"] score = 0 if business["$distance"] < 750: score += 1 else: distance = business["$distance"] if distance > 1000: distance -= 1000 score -= math.floor(distance / 500) if "rating" in business: place_rating = business["rating"] if place_rating > 4: score += 2 elif place_rating > 3: score += 1 for category in business["cuisine"].split(", "): if category in user_tastes and category in user_dislikes: continue if category in user_dislikes: score -= 2 elif category in user_tastes: score += 1 if key in histories: score -= 1 # Add the data to redis for this session print place_scores, score, key self.redis.zadd(place_scores, key, score) def place_callback(data): # Generate a score for each venue. process_businesses(data) # Get the places with the best scores. def get_tiny_business(choice): id_, score = choice return business_data(None, id_, self.redis)["name"], score, id_ picks = self.redis.zrevrange(place_scores, 0, 3, withscores=True) picks = map(get_tiny_business, picks) self.write({"result": "okay", "registered": "yes", "members": list(members), "choices": picks, "latitude": lat, "longitude": lon}) self.finish() fact_search(place_callback, latitude=lat, longitude=lon, categories=user_tastes, redis=self.redis)