def get_user_achievements(user_id):
    """ @params user_id datastore user ID
           @return json of Achievements Objects as jsons completed by user: user_id
        returns Datastore lookup of AchievementsList Entity using user_id
    """
    achievements = UserDetails.get_by_id(int(user_id)).achievements
    return json.dumps(dict(user_id=user_id, achievements=achievements))
def user_achievements_all():
    from Models import UserDetails
    user_id = request.json['user_id']
    user_details = UserDetails.get_by_id(int(user_id))
    print user_details
    achievements = [json.loads(a) for a in user_details.achievements]
    return json.dumps(dict(status_code=200, achievements=achievements))
def update():
    try:
        from Models import Achievement, UserDetails
        from UserManagement import add_achievement
        user_id = request.json['user_id']
        print user_id
        user_details = UserDetails.get_by_id(int(user_id))
        if user_details is None:
            return json.dumps(dict(status_code=204, error_message="user_id not found"))
        lon = request.json["lon"]
        lat = request.json["lat"]
        from search import nearby_search
        nearby_places = nearby_search(lon, lat, 4500)
        achievement_ids = []
        for result in nearby_places:
            if int(result['radius']) >= int(result['distance']):
                achievement_id = result['achievement_id']
                added_id = add_achievement(int(achievement_id), int(user_id))
                if added_id is not None:
                    achievement_ids.append(int(added_id))
        if not achievement_ids:
            return json.dumps(dict(status_code=204))
        else:
            return json.dumps(dict(status_code=200, achievements=achievement_ids))
    except BaseException, ex:
        logging.exception("Uh Oh - %s" % ex)
        return json.dumps({"status_code": 400, "Exception": str(ex)})
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 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 provision(_key):
     user_details = UserDetails(id=_key.id(), achievements=[])
     user_details.put()