def get_greatest(_achievements):
     assert(_achievements is not None)
     _greatest = Achievement.get_by_id(int(_achievements[0]["id"]))
     for _achievement in _achievements[1:]:
         _candidate = Achievement.get_by_id(int(_achievement["id"]))
         if _candidate.points >= _greatest.points:
             _greatest = _candidate
     return _greatest
def get_nearby_achievements(location, radius=None):
    """ @param location a dictionary containing "lng" and "lat" entries
        @param radius radius of google places search
        @return list of Achievement objects as json
        Does a google Places nearby_search lookup,
        Retrieves all Datastore Places entries s.t. place_id is in search results
        Retrieves all Datastore Achievements s.t. achievement_id is in a Places achievements list
        return set of Achievements as a json objects
    """
    google_places = GooglePlaces(API_KEY)
    location = {"lng": location['lon'], "lat": location['lat']}
    query_results = google_places.nearby_search(lat_lng=location, rankby=ranking.DISTANCE, keyword='[Achievement]')

    result = {}
    achievements = []
    for place in query_results.places:
        query = Place.gql("WHERE id = '" + str(place.id) + "'")
        place_object = query.get()
        if place_object != None:
            for achievement_id in place_object.achievements:
                achievement_obj = Achievement.get_by_id(int(achievement_id))
                achievements.append(achievement_obj.to_dict())
            result["status_code"] = 200
        else:
            result["status_code"] = 404
    result["achievements"] = achievements
    return json.dumps(result)
def get_achievement_photo(achievement_id):
    try:
        from Tools import rescale
        from Models import Achievement
        import cloudstorage as gcs
        from search import nearby_search
        if achievement_id == 'nearby':
            print 'nearby'
            lon = request.query['lon']
            lat = request.query['lat']
            place_documents = nearby_search(lon, lat, 500000)
            print place_documents
            if place_documents is None:
                return json.dumps({'status_code': 204})
            achievement_id = place_documents[0]['achievement_id']
            print achievement_id
        achievement = Achievement.get_by_id(int(achievement_id))
        pictures = list(achievement.pictures)
        picture_id = pictures[0]
        size = [int(request.query['x']), int(request.query['y'])]
        gcs_filename = '/thebucket/picture/' + picture_id + '/photo'
        gcs_file = gcs.open(gcs_filename)
        data = gcs_file.read()
        return rescale.rescale(data, *size)
    except BaseException, ex:
        logging.exception("Exception: %s" % ex)
        print(str(ex))
        return json.dumps({"status_code": 400})
def get_achievement(achievement_id):
    result = {'achievement_id': achievement_id}
    achievement = Achievement.get_by_id(int(achievement_id))
    if achievement is None:
        result['status_code'] = 404
    else:
        result['status_code'] = 200
        result['achievement'] = json.dumps(achievement.to_dict())
    return result
def user_achievements_latest_and_greatest():
    from Models import UserDetails, Achievement
    user_id = request.json['user_id']
    print "user_id" + str(user_id)
    user_details = UserDetails.get_by_id(int(user_id))
    print user_details
    achievements = [json.loads(a) for a in user_details.achievements]
    if achievements is not None:
        latest = achievements[0]
        greatest = Achievement.get_by_id(int(achievements[0]['id']))
        for achievement in achievements[1:]:
            candidate = Achievement.get_by_id(int(achievement['id']))
            if candidate.points > greatest.points:
                greatest = candidate
            if int(achievement['time']) > int(latest['time']):
                latest = achievement
        latest_id = latest['id']
        greatest_id = greatest.key.id()
        print latest_id
        print greatest_id
        return json.dumps(dict(status_code=200, latest_id=int(latest_id), greatest_id=greatest_id))
    else:
        return json.dumps(dict(status_code=204))
def add_achievement(achievement_id, user_id):
    from Models import UserDetails, Achievement
    user_details = UserDetails.get_by_id(int(user_id))
    achievement = Achievement.get_by_id(int(achievement_id))
    if achievement is None or user_details is None:
        print achievement_id
        print user_id
        return None
    print achievement.to_dict()
    print user_details.to_dict()
    if not user_details.achievements:
        achievements = []
    else:
        achievements = [json.loads(a) for a in user_details.achievements]
    print achievements
    if not any(d.get('id', None) == int(achievement_id) for d in achievements):
        # user does not have achievement
        def get_greatest(_achievements):
            assert(_achievements is not None)
            _greatest = Achievement.get_by_id(int(_achievements[0]["id"]))
            for _achievement in _achievements[1:]:
                _candidate = Achievement.get_by_id(int(_achievement["id"]))
                if _candidate.points >= _greatest.points:
                    _greatest = _candidate
            return _greatest

        achievement_entry = {"id": int(achievement_id),
                             "time": time.time()}
        achievements.append(achievement_entry)
        if user_details.score is None:
            user_details.score = 0
        user_details.score += achievement.points
        greatest = get_greatest(achievements)
        user_details.greatest = greatest.key
        user_details.greatest_thumbnail = greatest.thumbnail
        user_details.latest = achievement.key
        user_details.latest_thumbnail = achievement.thumbnail
        print achievements
        user_details.achievements = list(json.dumps(a) for a in achievements)
        print user_details.achievements
        user_details.put()
        print user_details.to_dict()
        return achievement_id
    else:
        print "User already has achievement"
def achievement_info(achievement_id):
    try:
        from Models import Achievement
        from Tools import decode
        print request.json
        d = dict(decode.decode_dict(request.json))
        print d
        num_pictures = d['num_pictures']
        print num_pictures
        achievement = Achievement.get_by_id(int(achievement_id))
        print achievement
        pictures = achievement.pictures
        return json.dumps(
            {
                "picture_ids": pictures[1:int(num_pictures)],
                "achievement_name": achievement.name,
                "achievement_description": achievement.description,
                "points": achievement.points
            })
    except BaseException, ex:
        logging.exception("Exception: %s" % ex)
        print(str(ex))
        return json.dumps({"status_code": 400})