Exemple #1
0
def create_playlist(playlist_name, user_id):
    print 'Creating new playlist %s for user %s' % (playlist_name, user_id)
    new_playlist = Playlist(user_id=user_id, name=playlist_name)
    DB_SESSION.add(new_playlist)
    DB_SESSION.commit()
    # Seed soundcloud_songs database table
    map(populate_soundcloud_songs, get_similar_artists(playlist_name))
    return new_playlist
Exemple #2
0
def get_similar_artists(artist, limit=10, min_song_ct=5, artist_first=True):
    """Returns a list of similar artist names to @artist."""
    # Skip the ORM and directly execute the SQL for performance reasons
    QUERYSTR = text('''
SELECT song1.artist, song2.artist, COUNT(sim.similarity) AS sim_count,
    scounts.count AS song_count,
    COUNT(sim.similarity) / CAST(scounts.count AS FLOAT) AS sim_count_norm
    FROM songs AS song1 JOIN similarities AS sim ON song1.song_id=sim.song1_id
    JOIN songs AS song2 ON sim.song2_id=song2.song_id
    JOIN (SELECT s.artist AS artist, COUNT(s.id) AS count
        FROM songs AS s
        GROUP BY s.artist) AS scounts ON song2.artist=scounts.artist
    WHERE song1.artist=:artist AND scounts.count > :count
    GROUP BY song1.artist, song2.artist, scounts.artist, scounts.count
    ORDER BY sim_count_norm DESC
    LIMIT :limit;
    ''')
    # This *should* be secure since it uses bound parameters which are
    # passed to the underlying DPAPI:
    # http://docs.sqlalchemy.org/en/rel_0_9/orm/session_api.html
    #     #sqlalchemy.orm.session.Session.execute
    # http://docs.sqlalchemy.org/en/rel_0_9/core/sqlelement.html
    #     #sqlalchemy.sql.expression.text
    # http://docs.sqlalchemy.org/en/rel_0_9/core/sqlelement.html
    #     #sqlalchemy.sql.expression.bindparam
    params = { 'artist': artist, 'count': min_song_ct, 'limit': limit }
    # Result tuple: ('artist1', 'artist2', sim_ct, song_ct, norm_sim_ct)
    artists = [row[1] for row in DB_SESSION.execute(QUERYSTR, params)]
    if artist_first:
        if artist in artists:
            artists.remove(artist)
        return [artist] + artists
    else:
        return artists
Exemple #3
0
def update_or_create(model, defaults={}, commit=True, **kwargs):
    """
    Equivalent of Django's update_or_create, with an additional option to
    commit the transaction (commits by default).
    @param model: Model to update, e.g. Song
    @param defaults: Parameters to update, e.g. {
        'playback_count': 1000, 'likes_count': 10
    }
    @param commit: Commit the transaction?
    @param **kwargs: Parameters to check uniqueness on, e.g. {
        'title': 'How We Do', 'artist': '50 Cent'
    }
    """
    model_instance = DB_SESSION.query(model).filter_by(**kwargs).first()
    if model_instance:
        for arg, value in defaults.iteritems():
            setattr(model_instance, arg, value)
        if commit:
            DB_SESSION.commit()
        return model_instance, True
    else:
        params = { k: v for k, v in kwargs.iteritems() }
        params.update(defaults)
        model_instance = model(**params)
        DB_SESSION.add(model_instance)
        if commit:
            DB_SESSION.commit()
        return model_instance, False
Exemple #4
0
def get_similar_songs(artist, limit=10):
    """Returns a list of similar (song, artist) tuples to @artist."""
    QUERYSTR = text('''
SELECT song1.artist, song2.title, song2.artist, SUM(sim.similarity) AS total_sim
    FROM songs AS song1 JOIN similarities AS sim ON song1.song_id=sim.song1_id
    JOIN songs AS song2 ON sim.song2_id=song2.song_id
    WHERE song1.artist=:artist
    GROUP BY song1.artist, song2.title, song2.artist
    ORDER BY total_sim DESC
    LIMIT :limit;
    ''')
    params = { 'artist': artist, 'limit': limit }
    # Result tuple: ('artist1', 'song2', 'artist2', sim)
    return ['%s %s' % (row[1], row[2])
            for row in DB_SESSION.execute(QUERYSTR, params)]
Exemple #5
0
def artists():
    def artist_filter(artist_str):
        stop_words = ['ft.', 'feat', 'featuring', '_', '+', '/', '|']
        artist_str = artist_str.lower()
        for stop_word in stop_words:
            if stop_word in artist_str:
                return False
        return True

    # Result set is a list of tuples [('[Artist]',), ...]
    artists = [s[0] for s in DB_SESSION.query(Song.artist.distinct())
               if artist_filter(s[0])]
    return jsonify({
        'length': len(artists),
        'data': artists
    })
Exemple #6
0
def create_user(username, token, secret):
    new_account = User(username=username, token=token, secret=secret)
    DB_SESSION.add(new_account)
    DB_SESSION.commit()
    return new_account
Exemple #7
0
 def delete_playlist(playlist_name, user_id):
         playlist = (Playlist.query
                             .filter_by(user_id=user.id, name=playlist_name)
                             .one())
         DB_SESSION.delete(playlist)
         DB_SESSION.commit()
Exemple #8
0
def shutdown_session(exception=None):
    DB_SESSION.remove()