예제 #1
0
def add_rating(user, gid):
    """Take the DJ spot (if it is available)."""
    group = g.store.get(Group, gid)
    if group is None:
        raise helpers.BadRequest(errors.INVALID_GROUP, "group does not exist")
    try:
        artist = request.form['artist']
        title = request.form['title']
        rating = max(1, min(5, int(request.form['rating'])))
    except KeyError:
        raise helpers.BadRequest(errors.MISSING_FIELD,
                                 "missing artist, title or rating")
    except ValueError:
        raise helpers.BadRequest(errors.INVALID_RATING, "rating is invalid")
    if user.group != group:
        raise helpers.Unauthorized("you are not in this group")
    track = g.store.find(Track, (Track.artist == artist) &
                         (Track.title == title)).one()
    if track is None:
        raise helpers.BadRequest(errors.INVALID_TRACK, "track not found")
    # Add a group event.
    event = GroupEvent(group, user, events.RATING)
    event.payload = {
        'artist': track.artist,
        'title': track.title,
        'rating': rating,
    }
    g.store.add(event)
    # Add a library entry.
    set_rating(user, track.artist, track.title, rating)
    return helpers.success()
예제 #2
0
def set_master(user, gid):
    """Take the DJ spot (if it is available)."""
    group = g.store.get(Group, gid)
    if group is None:
        raise helpers.BadRequest(errors.INVALID_GROUP, "group does not exist")
    try:
        uid = int(request.form['uid'])
    except (KeyError, ValueError):
        raise helpers.BadRequest(errors.MISSING_FIELD, "cannot parse uid")
    if user.id != uid or user.group != group:
        raise helpers.Unauthorized("user not self or not in group")
    if group.master != None and group.master != user:
        raise helpers.Unauthorized("someone else is already here")
    group.master = user
    event = GroupEvent(group, user, events.MASTER, None)
    g.store.add(event)
    return helpers.success()
예제 #3
0
def leave_master(user, gid):
    """Leave the DJ spot."""
    group = g.store.get(Group, gid)
    if group is None:
        raise helpers.BadRequest(errors.INVALID_GROUP, "group does not exist")
    if group.master != None and group.master != user:
        raise helpers.Unauthorized("you are not the master")
    group.master = None
    return helpers.success()
예제 #4
0
def get_tracks(master, gid):
    """Get the next tracks."""
    group = g.store.get(Group, gid)
    if group is None:
        raise helpers.BadRequest(errors.INVALID_GROUP, "group does not exist")
    if group.master != master:
        raise helpers.Unauthorized("you are not the DJ")
    # Get all the tracks in the master's library that haven't been played.
    played_filter = get_played_filter(group)
    remaining = filter(
        played_filter,
        g.store.find(LibEntry,
                     (LibEntry.user == master) & (LibEntry.is_valid == True)
                     & (LibEntry.is_local == True)))
    if len(remaining) == 0:
        raise helpers.NotFound(errors.TRACKS_DEPLETED,
                               'no more tracks to play')
    # Partition tracks based on whether we can embed them in the latent space.
    with_feats = list()
    points = list()
    no_feats = list()
    for entry in remaining:
        point = predict.get_point(entry.track)
        if point is not None:
            with_feats.append(entry)
            points.append(point)
        else:
            no_feats.append(entry)
    # For the users that can be modelled: predict their ratings.
    models = filter(lambda model: model.is_nontrivial(),
                    [predict.Model(user) for user in group.users])
    if models is not None:
        ratings = [model.score(points) for model in models]
        agg = predict.aggregate(ratings)
    else:
        # Not a single user can be modelled! just order the songs randomly.
        agg = range(len(with_feats))
        random.shuffle(agg)
    # Construct the playlist, decreasing order of scores.
    playlist = [
        entry for entry, score in sorted(
            zip(with_feats, agg), key=itemgetter(1), reverse=True)
    ]
    # Randomize songs for which we don't have features.
    random.shuffle(no_feats)
    playlist.extend(no_feats)
    # Craft the JSON response.
    tracks = list()
    for entry in playlist[:MAX_TRACKS]:
        tracks.append({
            'artist': entry.track.artist,
            'title': entry.track.title,
            'local_id': entry.local_id,
        })
    return jsonify(playlist_id=get_playlist_id(group), tracks=tracks)
예제 #5
0
def skip_track(user, gid):
    """Skip the track that is currently being played."""
    group = g.store.get(Group, gid)
    if group is None:
        raise helpers.BadRequest(errors.INVALID_GROUP, "group does not exist")
    if group.master != user:
        raise helpers.Unauthorized("you are not the master")
    results = g.store.find(GroupEvent, (GroupEvent.event_type == events.PLAY)
                           & (GroupEvent.group == group))
    play_event = results.order_by(Desc(GroupEvent.created)).first()
    if play_event is None:
        raise helpers.BadRequest(errors.NO_CURRENT_TRACK, "no track to skip")
    payload = {
        'artist': play_event.payload.get('artist'),
        'title': play_event.payload.get('title'),
        'master': {
            'uid': user.id,
            'nickname': user.nickname
        },
    }
    event = GroupEvent(group, user, events.SKIP, payload)
    g.store.add(event)
    return helpers.success()
예제 #6
0
def play_track(user, gid):
    """Register the track that is currently playing."""
    group = g.store.get(Group, gid)
    if group is None:
        raise helpers.BadRequest(errors.INVALID_GROUP, "group does not exist")
    if group.master != user:
        raise helpers.Unauthorized("you are not the master")
    try:
        artist = request.form['artist']
        title = request.form['title']
    except KeyError:
        raise helpers.BadRequest(errors.MISSING_FIELD,
                                 "missing artist and / or title")
    track = g.store.find(Track, (Track.artist == artist) &
                         (Track.title == title)).one()
    if track is None:
        raise helpers.BadRequest(errors.INVALID_TRACK, "track not found")
    payload = {
        'artist': track.artist,
        'title': track.title,
        'master': {
            'uid': user.id,
            'nickname': user.nickname
        },
    }
    payload['stats'] = list()
    # TODO Something better than random scores :)
    for resident in group.users:
        payload['stats'].append({
            'uid': resident.id,
            'nickname': resident.nickname,
            'score': int(random.random() * 100),
            'predicted': True  #if random.random() > 0.2 else False
        })
    event = GroupEvent(group, user, events.PLAY, payload)
    g.store.add(event)
    return helpers.success()