Exemple #1
0
def change_username_post(uid):
    code, user = UserManager.get(store, uid)
    if code != UserManager.SUCCESS:
        return redirect(url_for('index'))

    username = request.form.get('user')
    if username in ('', None):
        flash('The username is required')
        return render_template('change_username.html', user = user)
    if user.name != username and store.find(User, User.name == username).one():
        flash('This name is already taken')
        return render_template('change_username.html', user = user)

    if request.form.get('admin') is None:
        admin = False
    else:
        admin = True

    if user.name != username or user.admin != admin:
        user.name = username
        user.admin = admin
        store.commit()
        flash("User '%s' updated." % username)
    else:
        flash("No changes for '%s'." % username)

    return redirect(url_for('user_profile', uid = uid))
Exemple #2
0
def do_user_import():
	if not request.files['file']:
		return render_template('importusers.html', admin = UserManager.get(store, session.get('userid'))[1].admin)

	users = []
	reader = csv.reader(request.files['file'])
	for id, name, mail, password, salt, admin, lfmsess, lfmstatus in reader:
		mail = None if mail == 'None' else mail
		admin = admin == 'True'
		lfmsess = None if lfmsess == 'None' else lfmsess
		lfmstatus = lfmstatus == 'True'

		user = User()
		user.id = uuid.UUID(id)
		user.name = name
		user.password = password
		user.salt = salt
		user.admin = admin
		user.lastfm_session = lfmsess
		user.lastfm_status = lfmstatus

		users.append(user)

	store.find(User).remove()
	for u in users:
		store.add(u)
	store.commit()

	return redirect(url_for('user_index'))
Exemple #3
0
def update_clients(uid, user):
    clients_opts = {}
    for key, value in request.form.iteritems():
        if '_' not in key:
            continue
        parts = key.split('_')
        if len(parts) != 2:
            continue
        client, opt = parts
        if not client or not opt:
            continue

        if client not in clients_opts:
            clients_opts[client] = { opt: value }
        else:
            clients_opts[client][opt] = value
    app.logger.debug(clients_opts)

    for client, opts in clients_opts.iteritems():
        prefs = store.get(ClientPrefs, (user.id, client))
        if not prefs:
            continue

        if 'delete' in opts and opts['delete'] in [ 'on', 'true', 'checked', 'selected', '1' ]:
            store.remove(prefs)
            continue

        prefs.format  =     opts['format']   if 'format'  in opts and opts['format']  else None
        prefs.bitrate = int(opts['bitrate']) if 'bitrate' in opts and opts['bitrate'] else None

    store.commit()
    flash('Clients preferences updated.')
    return user_profile(uid, user)
Exemple #4
0
def update_playlist():
    status, res = get_entity(request, Playlist, 'playlistId')
    if not status:
        return res

    if res.user_id != request.user.id and not request.user.admin:
        return request.error_formatter(50, "You're not allowed to delete a playlist that isn't yours")

    playlist = res
    name, comment, public = map(request.values.get, [ 'name', 'comment', 'public' ])
    to_add, to_remove = map(request.values.getlist, [ 'songIdToAdd', 'songIndexToRemove' ])
    try:
        to_add = map(uuid.UUID, to_add)
        to_remove = map(int, to_remove)
    except:
        return request.error_formatter(0, 'Invalid parameter')

    if name:
        playlist.name = name
    if comment:
        playlist.comment = comment
    if public:
        playlist.public = public in (True, 'True', 'true', 1, '1')

    for sid in to_add:
        track = store.get(Track, sid)
        if not track:
            return request.error_formatter(70, 'Unknown song')
        playlist.add(track)

    playlist.remove_at_indexes(to_remove)

    store.commit()
    return request.formatter({})
Exemple #5
0
def update_clients(uid):
	clients_opts = {}
	for client in set(map(lambda k: k.rsplit('_', 1)[0], request.form.keys())):
		clients_opts[client] = { k.rsplit('_', 1)[1]: v for k, v in filter(lambda (k, v): k.startswith(client), request.form.iteritems()) }
	app.logger.debug(clients_opts)

	if uid == 'me':
		userid = uuid.UUID(session.get('userid'))
	else:
		if not UserManager.get(store, session.get('userid'))[1].admin or not UserManager.get(store, uid)[0] is UserManager.SUCCESS:
			return redirect(url_for('index'))
		userid = uuid.UUID(uid)

	for client, opts in clients_opts.iteritems():
		prefs = store.get(ClientPrefs, (userid, client))
		if 'delete' in opts and opts['delete'] in [ 'on', 'true', 'checked', 'selected', '1' ]:
			store.remove(prefs)
			continue

		prefs.format  =     opts['format']   if 'format'  in opts and opts['format']  else None
		prefs.bitrate = int(opts['bitrate']) if 'bitrate' in opts and opts['bitrate'] else None

	store.commit()
	flash('Clients preferences updated.')
	return user_profile(uid)
Exemple #6
0
def change_username(uid):
    if not UserManager.get(store, session.get('userid'))[1].admin or not UserManager.get(store, uid)[0] is UserManager.SUCCESS:
        return redirect(url_for('index'))
    user = UserManager.get(store, uid)[1]
    if request.method == 'POST':
        username = request.form.get('user')
        if username in ('', None):
            flash('The username is required')
            return render_template('change_username.html', user = user, admin = UserManager.get(store, session.get('userid'))[1].admin)
        if request.form.get('admin') is None:
            admin = False
        else:
            admin = True
        changed = False
        if user.name != username or user.admin != admin:
            user.name = username
            user.admin = admin
            store.commit()
            flash("User '%s' updated." % username)
            return redirect(url_for('user_profile', uid = uid))
        else:
            flash("No changes for '%s'." % username)
            return redirect(url_for('user_profile', uid = uid))

    return render_template('change_username.html', user = user, admin = UserManager.get(store, session.get('userid'))[1].admin)
Exemple #7
0
def unstar():
	id, albumId, artistId = map(request.values.getlist, [ 'id', 'albumId', 'artistId' ])

	def try_unstar(ent, eid):
		try:
			uid = uuid.UUID(eid)
		except:
			return request.error_formatter(0, 'Invalid id')

		store.find(ent, ent.user_id == request.user.id, ent.starred_id == uid).remove()
		return None

	for eid in id:
		err = try_unstar(StarredTrack, eid)
		if err:
			return err
		err = try_unstar(StarredFolder, eid)
		if err:
			return err

	for alId in albumId:
		err = try_unstar(StarredAlbum, alId)
		if err:
			return err

	for arId in artistId:
		err = try_unstar(StarredArtist, arId)
		if err:
			return err

	store.commit()
	return request.formatter({})
Exemple #8
0
def change_username_post(uid):
    code, user = UserManager.get(store, uid)
    if code != UserManager.SUCCESS:
        return redirect(url_for('index'))

    username = request.form.get('user')
    if username in ('', None):
        flash('The username is required')
        return render_template('change_username.html', user = user)
    if user.name != username and store.find(User, User.name == username).one():
        flash('This name is already taken')
        return render_template('change_username.html', user = user)

    if request.form.get('admin') is None:
        admin = False
    else:
        admin = True

    if user.name != username or user.admin != admin:
        user.name = username
        user.admin = admin
        store.commit()
        flash("User '%s' updated." % username)
    else:
        flash("No changes for '%s'." % username)

    return redirect(url_for('user_profile', uid = uid))
Exemple #9
0
def update_clients(uid, user):
    clients_opts = {}
    for key, value in request.form.iteritems():
        if '_' not in key:
            continue
        parts = key.split('_')
        if len(parts) != 2:
            continue
        client, opt = parts
        if not client or not opt:
            continue

        if client not in clients_opts:
            clients_opts[client] = { opt: value }
        else:
            clients_opts[client][opt] = value
    app.logger.debug(clients_opts)

    for client, opts in clients_opts.iteritems():
        prefs = store.get(ClientPrefs, (user.id, client))
        if not prefs:
            continue

        if 'delete' in opts and opts['delete'] in [ 'on', 'true', 'checked', 'selected', '1' ]:
            store.remove(prefs)
            continue

        prefs.format  =     opts['format']   if 'format'  in opts and opts['format']  else None
        prefs.bitrate = int(opts['bitrate']) if 'bitrate' in opts and opts['bitrate'] else None

    store.commit()
    flash('Clients preferences updated.')
    return user_profile(uid, user)
Exemple #10
0
def unstar():
    id, albumId, artistId = map(request.args.getlist,
                                ['id', 'albumId', 'artistId'])

    def try_unstar(ent, eid):
        try:
            uid = uuid.UUID(eid)
        except:
            return request.error_formatter(0, 'Invalid id')

        store.find(ent, ent.user_id == request.user.id,
                   ent.starred_id == uid).remove()
        return None

    for eid in id:
        err = try_unstar(StarredTrack, eid)
        if err:
            return err
        err = try_unstar(StarredFolder, eid)
        if err:
            return err

    for alId in albumId:
        err = try_unstar(StarredAlbum, alId)
        if err:
            return err

    for arId in artistId:
        err = try_unstar(StarredArtist, arId)
        if err:
            return err

    store.commit()
    return request.formatter({})
Exemple #11
0
def do_user_import():
	if not request.files['file']:
		return render_template('importusers.html')

	users = []
	reader = csv.reader(request.files['file'])
	for id, name, mail, password, salt, admin, lfmsess, lfmstatus in reader:
		mail = None if mail == 'None' else mail
		admin = admin == 'True'
		lfmsess = None if lfmsess == 'None' else lfmsess
		lfmstatus = lfmstatus == 'True'

		user = User()
		user.id = uuid.UUID(id)
		user.name = name
		user.password = password
		user.salt = salt
		user.admin = admin
		user.lastfm_session = lfmsess
		user.lastfm_status = lfmstatus

		users.append(user)

	store.find(User).remove()
	for u in users:
		store.add(u)
	store.commit()

	return redirect(url_for('user_index'))
Exemple #12
0
def change_mail():
	user = UserManager.get(store, session.get('userid'))[1]
	if request.method == 'POST':
		mail = request.form.get('mail')
		# No validation, lol.
		user.mail = mail
		store.commit()
		return redirect(url_for('user_profile'))

	return render_template('change_mail.html', user = user)
Exemple #13
0
def add_chat_message():
	msg = request.args.get('message')
	if not msg:
		return request.error_formatter(10, 'Missing message')

	chat = ChatMessage()
	chat.user_id = request.user.id
	chat.message = msg
	store.add(chat)
	store.commit()
	return request.formatter({})
Exemple #14
0
def delete_playlist():
    status, res = get_entity(request, Playlist)
    if not status:
        return res

    if res.user_id != request.user.id and not request.user.admin:
        return request.error_formatter(50, "You're not allowed to delete a playlist that isn't yours")

    store.remove(res)
    store.commit()
    return request.formatter({})
Exemple #15
0
def add_chat_message():
    msg = request.args.get('message')
    if not msg:
        return request.error_formatter(10, 'Missing message')

    chat = ChatMessage()
    chat.user_id = request.user.id
    chat.message = msg
    store.add(chat)
    store.commit()
    return request.formatter({})
Exemple #16
0
def lastfm_unreg(uid):
	if uid == 'me':
		lfm = LastFm(UserManager.get(store, session.get('userid'))[1], app.logger)
	else:
		if not UserManager.get(store, session.get('userid'))[1].admin or not UserManager.get(store, uid)[0] is UserManager.SUCCESS:
			return redirect(url_for('index'))
		lfm = LastFm(UserManager.get(store, uid)[1], app.logger)
	lfm.unlink_account()
	store.commit()
	flash('Unliked LastFM account')
	return redirect(url_for('user_profile', uid = uid))
Exemple #17
0
def delete_playlist():
    status, res = get_entity(request, Playlist)
    if not status:
        return res

    if res.user_id != request.user.id and not request.user.admin:
        return request.error_formatter(
            50, "You're not allowed to delete a playlist that isn't yours")

    store.remove(res)
    store.commit()
    return request.formatter({})
Exemple #18
0
def lastfm_reg():
	token = request.args.get('token')
	if token in ('', None):
		flash('Missing LastFM auth token')
		return redirect(url_for('user_profile'))

	lfm = LastFm(UserManager.get(store, session.get('userid'))[1], app.logger)
	status, error = lfm.link_account(token)
	store.commit()
	flash(error if not status else 'Successfully linked LastFM account')

	return redirect(url_for('user_profile'))
Exemple #19
0
def lastfm_reg(uid, user):
    token = request.args.get('token')
    if token in ('', None):
        flash('Missing LastFM auth token')
        return redirect(url_for('user_profile', uid = uid))

    lfm = LastFm(app.config['LASTFM'], user, app.logger)
    status, error = lfm.link_account(token)
    store.commit()
    flash(error if not status else 'Successfully linked LastFM account')

    return redirect(url_for('user_profile', uid = uid))
Exemple #20
0
def get_client_prefs():
	if not request.path.startswith('/rest/'):
		return

	client = request.values.get('c')
	prefs = store.get(ClientPrefs, (request.user.id, client))
	if not prefs:
		prefs = ClientPrefs()
		prefs.user_id = request.user.id
		prefs.client_name = client
		store.add(prefs)
		store.commit()

	request.prefs = prefs
Exemple #21
0
def change_mail(uid):
	if uid == 'me':
		user = UserManager.get(store, session.get('userid'))[1]
	else:
		if not UserManager.get(store, session.get('userid'))[1].admin or not UserManager.get(store, uid)[0] is UserManager.SUCCESS:
			return redirect(url_for('index'))
		user = UserManager.get(store, uid)[1]
	if request.method == 'POST':
		mail = request.form.get('mail')
		# No validation, lol.
		user.mail = mail
		store.commit()
		return redirect(url_for('user_profile', uid = uid))

	return render_template('change_mail.html', user = user, admin = UserManager.get(store, session.get('userid'))[1].admin)
Exemple #22
0
def star():
    id, albumId, artistId = map(request.args.getlist,
                                ['id', 'albumId', 'artistId'])

    def try_star(ent, starred_ent, eid):
        try:
            uid = uuid.UUID(eid)
        except:
            return 2, request.error_formatter(0,
                                              'Invalid %s id' % ent.__name__)

        if store.get(starred_ent, (request.user.id, uid)):
            return 2, request.error_formatter(
                0, '%s already starred' % ent.__name__)
        e = store.get(ent, uid)
        if e:
            starred = starred_ent()
            starred.user_id = request.user.id
            starred.starred_id = uid
            store.add(starred)
        else:
            return 1, request.error_formatter(70,
                                              'Unknown %s id' % ent.__name__)

        return 0, None

    for eid in id:
        err, ferror = try_star(Track, StarredTrack, eid)
        if err == 1:
            err, ferror = try_star(Folder, StarredFolder, eid)
            if err:
                return ferror
        elif err == 2:
            return ferror

    for alId in albumId:
        err, ferror = try_star(Album, StarredAlbum, alId)
        if err:
            return ferror

    for arId in artistId:
        err, ferror = try_star(Artist, StarredArtist, arId)
        if err:
            return ferror

    store.commit()
    return request.formatter({})
Exemple #23
0
def get_client_prefs():
    if not request.path.startswith('/rest/'):
        return

    if 'c' not in request.values:
        return request.error_formatter(10, 'Missing required parameter')

    client = request.values.get('c')
    prefs = store.get(ClientPrefs, (request.user.id, client))
    if not prefs:
        prefs = ClientPrefs()
        prefs.user_id = request.user.id
        prefs.client_name = client
        store.add(prefs)
        store.commit()

    request.prefs = prefs
Exemple #24
0
def scan_folder(id = None):
	s = Scanner(store)
	if id is None:
		for folder in store.find(Folder, Folder.root == True):
			FolderManager.scan(store, folder.id, s)
	else:
		status = FolderManager.scan(store, id, s)
		if status != FolderManager.SUCCESS:
			flash(FolderManager.error_str(status))
			return redirect(url_for('folder_index'))

	added, deleted = s.stats()
	store.commit()

	flash('Added: %i artists, %i albums, %i tracks' % (added[0], added[1], added[2]))
	flash('Deleted: %i artists, %i albums, %i tracks' % (deleted[0], deleted[1], deleted[2]))
	return redirect(url_for('folder_index'))
Exemple #25
0
def lastfm_reg(uid):
	token = request.args.get('token')
	if token in ('', None):
		flash('Missing LastFM auth token')
		return redirect(url_for('user_profile', uid = uid))

	if uid == 'me':
		lfm = LastFm(UserManager.get(store, session.get('userid'))[1], app.logger)
	else:
		if not UserManager.get(store, session.get('userid'))[1].admin or not UserManager.get(store, uid)[0] is UserManager.SUCCESS:
			return redirect(url_for('index'))
		lfm = LastFm(UserManager.get(store, uid)[1], app.logger)
	status, error = lfm.link_account(token)
	store.commit()
	flash(error if not status else 'Successfully linked LastFM account')

	return redirect(url_for('user_profile', uid = uid))
Exemple #26
0
def get_client_prefs():
    if not request.path.startswith('/rest/'):
        return

    if 'c' not in request.values:
        return request.error_formatter(10, 'Missing required parameter')

    client = request.values.get('c')
    prefs = store.get(ClientPrefs, (request.user.id, client))
    if not prefs:
        prefs = ClientPrefs()
        prefs.user_id = request.user.id
        prefs.client_name = client
        store.add(prefs)
        store.commit()

    request.prefs = prefs
Exemple #27
0
def playlist_delete(uid):
	try:
		uid = uuid.UUID(uid)
	except:
		flash('Invalid playlist id')
		return redirect(url_for('playlist_index'))

	playlist = store.get(Playlist, uid)
	if not playlist:
		flash('Unknown playlist')
	elif str(playlist.user_id) != session.get('userid'):
		flash("You're not allowed to delete this playlist")
	else:
		store.remove(playlist)
		store.commit()
		flash('Playlist deleted')

	return redirect(url_for('playlist_index'))
Exemple #28
0
def update_clients():
	clients_opts = {}
	for client in set(map(lambda k: k.rsplit('_', 1)[0], request.form.keys())):
		clients_opts[client] = { k.rsplit('_', 1)[1]: v for k, v in filter(lambda (k, v): k.startswith(client), request.form.iteritems()) }
	app.logger.debug(clients_opts)

	for client, opts in clients_opts.iteritems():
		prefs = store.get(ClientPrefs, (uuid.UUID(session.get('userid')), client))
		if 'delete' in opts and opts['delete'] in [ 'on', 'true', 'checked', 'selected', '1' ]:
			store.remove(prefs)
			continue

		prefs.format  =     opts['format']   if 'format'  in opts and opts['format']  else None
		prefs.bitrate = int(opts['bitrate']) if 'bitrate' in opts and opts['bitrate'] else None

	store.commit()
	flash('Clients preferences updated.')
	return user_profile()
Exemple #29
0
def update_playlist():
    status, res = get_entity(request, Playlist, 'playlistId')
    if not status:
        return res

    if res.user_id != request.user.id and not request.user.admin:
        return request.error_formatter(
            50, "You're not allowed to delete a playlist that isn't yours")

    playlist = res
    name, comment, public = map(request.args.get,
                                ['name', 'comment', 'public'])
    to_add, to_remove = map(request.args.getlist,
                            ['songIdToAdd', 'songIndexToRemove'])
    try:
        to_add = set(map(uuid.UUID, to_add))
        to_remove = sorted(set(map(int, to_remove)))
    except:
        return request.error_formatter(0, 'Invalid parameter')

    if name:
        playlist.name = name
    if comment:
        playlist.comment = comment
    if public:
        playlist.public = public in (True, 'True', 'true', 1, '1')

    tracks = list(playlist.tracks)

    for sid in to_add:
        track = store.get(Track, sid)
        if not track:
            return request.error_formatter(70, 'Unknown song')
        if track not in playlist.tracks:
            playlist.tracks.add(track)

    for idx in to_remove:
        if idx < 0 or idx >= len(tracks):
            return request.error_formatter(0, 'Index out of range')
        playlist.tracks.remove(tracks[idx])

    store.commit()
    return request.formatter({})
Exemple #30
0
def scan_folder(id=None):
    scanner = Scanner(store)
    if id is None:
        for folder in store.find(Folder, Folder.root == True):
            scanner.scan(folder)
    else:
        status, folder = FolderManager.get(store, id)
        if status != FolderManager.SUCCESS:
            flash(FolderManager.error_str(status))
            return redirect(url_for("folder_index"))
        scanner.scan(folder)

    scanner.finish()
    added, deleted = scanner.stats()
    store.commit()

    flash("Added: %i artists, %i albums, %i tracks" % (added[0], added[1], added[2]))
    flash("Deleted: %i artists, %i albums, %i tracks" % (deleted[0], deleted[1], deleted[2]))
    return redirect(url_for("folder_index"))
Exemple #31
0
def scan_folder(id = None):
	scanner = Scanner(store)
	if id is None:
		for folder in store.find(Folder, Folder.root == True):
			scanner.scan(folder)
	else:
		status, folder = FolderManager.get(store, id)
		if status != FolderManager.SUCCESS:
			flash(FolderManager.error_str(status))
			return redirect(url_for('folder_index'))
		scanner.scan(folder)

	scanner.finish()
	added, deleted = scanner.stats()
	store.commit()

	flash('Added: %i artists, %i albums, %i tracks' % (added[0], added[1], added[2]))
	flash('Deleted: %i artists, %i albums, %i tracks' % (deleted[0], deleted[1], deleted[2]))
	return redirect(url_for('folder_index'))
Exemple #32
0
def star():
	id, albumId, artistId = map(request.values.getlist, [ 'id', 'albumId', 'artistId' ])

	def try_star(ent, starred_ent, eid):
		try:
			uid = uuid.UUID(eid)
		except:
			return 2, request.error_formatter(0, 'Invalid %s id' % ent.__name__)

		if store.get(starred_ent, (request.user.id, uid)):
			return 2, request.error_formatter(0, '%s already starred' % ent.__name__)
		e = store.get(ent, uid)
		if e:
			starred = starred_ent()
			starred.user_id = request.user.id
			starred.starred_id = uid
			store.add(starred)
		else:
			return 1, request.error_formatter(70, 'Unknown %s id' % ent.__name__)

		return 0, None

	for eid in id:
		err, ferror = try_star(Track, StarredTrack, eid)
		if err == 1:
			err, ferror = try_star(Folder, StarredFolder, eid)
			if err:
				return ferror
		elif err == 2:
			return ferror

	for alId in albumId:
		err, ferror = try_star(Album, StarredAlbum, alId)
		if err:
			return ferror

	for arId in artistId:
		err, ferror = try_star(Artist, StarredArtist, arId)
		if err:
			return ferror

	store.commit()
	return request.formatter({})
Exemple #33
0
def create_playlist():
    # Only(?) method where the android client uses form data rather than GET params
    playlist_id, name = map(
        lambda x: request.args.get(x) or request.form.get(x),
        ['playlistId', 'name'])
    # songId actually doesn't seem to be required
    songs = request.args.getlist('songId') or request.form.getlist('songId')
    try:
        playlist_id = uuid.UUID(playlist_id) if playlist_id else None
        songs = set(map(uuid.UUID, songs))
    except:
        return request.error_formatter(0, 'Invalid parameter')

    if playlist_id:
        playlist = store.get(Playlist, playlist_id)
        if not playlist:
            return request.error_formatter(70, 'Unknwon playlist')

        if playlist.user_id != request.user.id and not request.user.admin:
            return request.error_formatter(
                50, "You're not allowed to modify a playlist that isn't yours")

        playlist.tracks.clear()
        if name:
            playlist.name = name
    elif name:
        playlist = Playlist()
        playlist.user_id = request.user.id
        playlist.name = name
        store.add(playlist)
    else:
        return request.error_formatter(10, 'Missing playlist id or name')

    for sid in songs:
        track = store.get(Track, sid)
        if not track:
            return request.error_formatter(70, 'Unknown song')

        playlist.tracks.add(track)

    store.commit()
    return request.formatter({})
Exemple #34
0
def rate():
    id, rating = map(request.args.get, ['id', 'rating'])
    if not id or not rating:
        return request.error_formatter(10, 'Missing parameter')

    try:
        uid = uuid.UUID(id)
        rating = int(rating)
    except:
        return request.error_formatter(0, 'Invalid parameter')

    if not rating in xrange(6):
        return request.error_formatter(
            0, 'rating must be between 0 and 5 (inclusive)')

    if rating == 0:
        store.find(RatingTrack, RatingTrack.user_id == request.user.id,
                   RatingTrack.rated_id == uid).remove()
        store.find(RatingFolder, RatingFolder.user_id == request.user.id,
                   RatingFolder.rated_id == uid).remove()
    else:
        rated = store.get(Track, uid)
        rating_ent = RatingTrack
        if not rated:
            rated = store.get(Folder, uid)
            rating_ent = RatingFolder
            if not rated:
                return request.error_formatter(70, 'Unknown id')

        rating_info = store.get(rating_ent, (request.user.id, uid))
        if rating_info:
            rating_info.rating = rating
        else:
            rating_info = rating_ent()
            rating_info.user_id = request.user.id
            rating_info.rated_id = uid
            rating_info.rating = rating
            store.add(rating_info)

    store.commit()
    return request.formatter({})
Exemple #35
0
def update_playlist():
    status, res = get_entity(request, Playlist, "playlistId")
    if not status:
        return res

    if res.user_id != request.user.id and not request.user.admin:
        return request.error_formatter(50, "You're not allowed to delete a playlist that isn't yours")

    playlist = res
    name, comment, public = map(request.values.get, ["name", "comment", "public"])
    to_add, to_remove = map(request.values.getlist, ["songIdToAdd", "songIndexToRemove"])
    try:
        to_add = set(map(uuid.UUID, to_add))
        to_remove = sorted(set(map(int, to_remove)))
    except:
        return request.error_formatter(0, "Invalid parameter")

    if name:
        playlist.name = name
    if comment:
        playlist.comment = comment
    if public:
        playlist.public = public in (True, "True", "true", 1, "1")

    tracks = list(playlist.tracks)

    for sid in to_add:
        track = store.get(Track, sid)
        if not track:
            return request.error_formatter(70, "Unknown song")
        if track not in playlist.tracks:
            playlist.tracks.add(track)

    for idx in to_remove:
        if idx < 0 or idx >= len(tracks):
            return request.error_formatter(0, "Index out of range")
        playlist.tracks.remove(tracks[idx])

    store.commit()
    return request.formatter({})
Exemple #36
0
def create_playlist():
    # Only(?) method where the android client uses form data rather than GET params
    playlist_id, name = map(request.values.get, [ 'playlistId', 'name' ])
    # songId actually doesn't seem to be required
    songs = request.values.getlist('songId')
    try:
        playlist_id = uuid.UUID(playlist_id) if playlist_id else None
        songs = map(uuid.UUID, songs)
    except:
        return request.error_formatter(0, 'Invalid parameter')

    if playlist_id:
        playlist = store.get(Playlist, playlist_id)
        if not playlist:
            return request.error_formatter(70, 'Unknwon playlist')

        if playlist.user_id != request.user.id and not request.user.admin:
            return request.error_formatter(50, "You're not allowed to modify a playlist that isn't yours")

        playlist.clear()
        if name:
            playlist.name = name
    elif name:
        playlist = Playlist()
        playlist.user_id = request.user.id
        playlist.name = name
        store.add(playlist)
    else:
        return request.error_formatter(10, 'Missing playlist id or name')

    for sid in songs:
        track = store.get(Track, sid)
        if not track:
            store.rollback()
            return request.error_formatter(70, 'Unknown song')

        playlist.add(track)

    store.commit()
    return request.formatter({})
Exemple #37
0
def star():
    id, albumId, artistId = map(request.values.getlist, [ 'id', 'albumId', 'artistId' ])

    if not id and not albumId and not artistId:
        return request.error_formatter(10, 'Missing parameter')

    errors = []
    for eid in id:
        terr = try_star(Track, StarredTrack, eid)
        ferr = try_star(Folder, StarredFolder, eid)
        if terr and ferr:
            errors += [ terr, ferr ]

    for alId in albumId:
        errors.append(try_star(Album, StarredAlbum, alId))

    for arId in artistId:
        errors.append(try_star(Artist, StarredArtist, arId))

    store.commit()
    error = merge_errors(errors)
    return request.formatter({ 'error': error }, error = True) if error else request.formatter({})
Exemple #38
0
def rate():
	id, rating = map(request.values.get, [ 'id', 'rating' ])
	if not id or not rating:
		return request.error_formatter(10, 'Missing parameter')

	try:
		uid = uuid.UUID(id)
		rating = int(rating)
	except:
		return request.error_formatter(0, 'Invalid parameter')

	if not rating in xrange(6):
		return request.error_formatter(0, 'rating must be between 0 and 5 (inclusive)')

	if rating == 0:
		store.find(RatingTrack, RatingTrack.user_id == request.user.id, RatingTrack.rated_id == uid).remove()
		store.find(RatingFolder, RatingFolder.user_id == request.user.id, RatingFolder.rated_id == uid).remove()
	else:
		rated = store.get(Track, uid)
		rating_ent = RatingTrack
		if not rated:
			rated = store.get(Folder, uid)
			rating_ent = RatingFolder
			if not rated:
				return request.error_formatter(70, 'Unknown id')

		rating_info = store.get(rating_ent, (request.user.id, uid))
		if rating_info:
			rating_info.rating = rating
		else:
			rating_info = rating_ent()
			rating_info.user_id = request.user.id
			rating_info.rated_id = uid
			rating_info.rating = rating
			store.add(rating_info)

	store.commit()
	return request.formatter({})
Exemple #39
0
def playlist_update(uid):
	try:
		uid = uuid.UUID(uid)
	except:
		flash('Invalid playlist id')
		return redirect(url_for('playlist_index'))

	playlist = store.get(Playlist, uid)
	if not playlist:
		flash('Unknown playlist')
		return redirect(url_for('playlist_index'))

	if str(playlist.user_id) != session.get('userid'):
		flash("You're not allowed to edit this playlist")
	elif not request.form.get('name'):
		flash('Missing playlist name')
	else:
		playlist.name = request.form.get('name')
		playlist.public = request.form.get('public') in (True, 'True', 1, '1', 'on', 'checked')
		store.commit()
		flash('Playlist updated.')

	return playlist_details(uid)
Exemple #40
0
def update_playlist():
    status, res = get_entity(request, Playlist, 'playlistId')
    if not status:
        return res

    if res.user_id != request.user.id and not request.user.admin:
        return request.error_formatter(
            50, "You're not allowed to delete a playlist that isn't yours")

    playlist = res
    name, comment, public = map(request.values.get,
                                ['name', 'comment', 'public'])
    to_add, to_remove = map(request.values.getlist,
                            ['songIdToAdd', 'songIndexToRemove'])
    try:
        to_add = map(uuid.UUID, to_add)
        to_remove = map(int, to_remove)
    except:
        return request.error_formatter(0, 'Invalid parameter')

    if name:
        playlist.name = name
    if comment:
        playlist.comment = comment
    if public:
        playlist.public = public in (True, 'True', 'true', 1, '1')

    for sid in to_add:
        track = store.get(Track, sid)
        if not track:
            return request.error_formatter(70, 'Unknown song')
        playlist.add(track)

    playlist.remove_at_indexes(to_remove)

    store.commit()
    return request.formatter({})
Exemple #41
0
def upload_file():
    if request.method == 'POST':
        file = request.files['file']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        #return redirect(url_for('uploaded_file', filename=filename))
            playlist = Playlist()
            playlist.user_id = uuid.UUID(session.get('userid'))
            playlist.name = filename
            store.add(playlist)
            tracks = []
            with open(os.path.join(app.config['UPLOAD_FOLDER'], filename)) as f:
                for line in f:
                    if line[0] != '#':
                        line = line.rstrip()
                        line = line.decode('utf-8')
                        tracks.append(line)
                        track = store.find(Track, Track.path == line).one()
                        if track:
                            playlist.tracks.add(track)
            store.commit()
            return render_template('upload.html', tracks = tracks)
    return '''
Exemple #42
0
def unstar():
    id, albumId, artistId = map(request.values.getlist,
                                ['id', 'albumId', 'artistId'])

    if not id and not albumId and not artistId:
        return request.error_formatter(10, 'Missing parameter')

    errors = []
    for eid in id:
        terr = try_unstar(StarredTrack, eid)
        ferr = try_unstar(StarredFolder, eid)
        if terr and ferr:
            errors += [terr, ferr]

    for alId in albumId:
        errors.append(try_unstar(StarredAlbum, alId))

    for arId in artistId:
        errors.append(try_unstar(StarredArtist, arId))

    store.commit()
    error = merge_errors(errors)
    return request.formatter({'error': error},
                             error=True) if error else request.formatter({})
Exemple #43
0
def stream_media():
    status, res = get_entity(request, Track)
    if not status:
        return res

    maxBitRate, format, timeOffset, size, estimateContentLength = map(
        request.values.get, [
            'maxBitRate', 'format', 'timeOffset', 'size',
            'estimateContentLength'
        ])
    if format:
        format = format.lower()

    src_suffix = res.suffix()
    dst_suffix = res.suffix()
    dst_bitrate = res.bitrate
    dst_mimetype = res.content_type

    if request.prefs.format:
        dst_suffix = request.prefs.format
    if request.prefs.bitrate and request.prefs.bitrate < dst_bitrate:
        dst_bitrate = request.prefs.bitrate

    if maxBitRate:
        try:
            maxBitRate = int(maxBitRate)
        except:
            return request.error_formatter(0, 'Invalid bitrate value')

        if dst_bitrate > maxBitRate and maxBitRate != 0:
            dst_bitrate = maxBitRate

    if format and format != 'raw' and format != src_suffix:
        dst_suffix = format
        dst_mimetype = mimetypes.guess_type(
            'dummyname.' + dst_suffix, False)[0] or 'application/octet-stream'

    if format != 'raw' and (dst_suffix != src_suffix
                            or dst_bitrate != res.bitrate):
        config = app.config['TRANSCODING']
        transcoder = config.get('transcoder_{}_{}'.format(
            src_suffix, dst_suffix))
        decoder = config.get('decoder_' + src_suffix) or config.get('decoder')
        encoder = config.get('encoder_' + dst_suffix) or config.get('encoder')
        if not transcoder and (not decoder or not encoder):
            transcoder = config.get('transcoder')
            if not transcoder:
                message = 'No way to transcode from {} to {}'.format(
                    src_suffix, dst_suffix)
                app.logger.info(message)
                return request.error_formatter(0, message)

        transcoder, decoder, encoder = map(
            lambda x: prepare_transcoding_cmdline(x, res.path, src_suffix,
                                                  dst_suffix, dst_bitrate),
            [transcoder, decoder, encoder])
        try:
            if transcoder:
                dec_proc = None
                proc = subprocess.Popen(transcoder, stdout=subprocess.PIPE)
            else:
                dec_proc = subprocess.Popen(decoder, stdout=subprocess.PIPE)
                proc = subprocess.Popen(encoder,
                                        stdin=dec_proc.stdout,
                                        stdout=subprocess.PIPE)
        except:
            return request.error_formatter(
                0, 'Error while running the transcoding process')

        def transcode():
            try:
                while True:
                    data = proc.stdout.read(8192)
                    if not data:
                        break
                    yield data
            except:
                if dec_proc != None:
                    dec_proc.terminate()
                proc.terminate()

            if dec_proc != None:
                dec_proc.wait()
            proc.wait()

        app.logger.info(
            'Transcoding track {0.id} for user {1.id}. Source: {2} at {0.bitrate}kbps. Dest: {3} at {4}kbps'
            .format(res, request.user, src_suffix, dst_suffix, dst_bitrate))
        response = Response(transcode(), mimetype=dst_mimetype)
    else:
        response = send_file(res.path, mimetype=dst_mimetype, conditional=True)

    res.play_count = res.play_count + 1
    res.last_play = now()
    request.user.last_play = res
    request.user.last_play_date = now()
    store.commit()

    return response
Exemple #44
0
def lastfm_unreg(uid, user):
    lfm = LastFm(user, app.logger)
    lfm.unlink_account()
    store.commit()
    flash('Unlinked LastFM account')
    return redirect(url_for('user_profile', uid = uid))
Exemple #45
0
def lastfm_unreg():
	lfm = LastFm(UserManager.get(store, session.get('userid'))[1], app.logger)
	lfm.unlink_account()
	store.commit()
	flash('Unliked LastFM account')
	return redirect(url_for('user_profile'))
Exemple #46
0
def stream_media():
	status, res = get_entity(request, Track)
	if not status:
		return res

	maxBitRate, format, timeOffset, size, estimateContentLength, client = map(request.values.get, [ 'maxBitRate', 'format', 'timeOffset', 'size', 'estimateContentLength', 'c' ])
	if format:
		format = format.lower()

	src_suffix = res.suffix()
	dst_suffix = res.suffix()
	dst_bitrate = res.bitrate
	dst_mimetype = res.content_type

	if client:
		prefs = store.get(ClientPrefs, (request.user.id, client))
		if not prefs:
			prefs = ClientPrefs()
			prefs.user_id = request.user.id
			prefs.client_name = client
			store.add(prefs)

		if prefs.format:
			dst_suffix = prefs.format
		if prefs.bitrate and prefs.bitrate < dst_bitrate:
			dst_bitrate = prefs.bitrate

	if maxBitRate:
		try:
			maxBitRate = int(maxBitRate)
		except:
			return request.error_formatter(0, 'Invalid bitrate value')

		if dst_bitrate > maxBitRate and maxBitRate != 0:
			dst_bitrate = maxBitRate

	if format and format != 'raw' and format != src_suffix:
		dst_suffix = format
		dst_mimetype = scanner.get_mime(dst_suffix)

	if format != 'raw' and (dst_suffix != src_suffix or dst_bitrate != res.bitrate):
		transcoder = config.get('transcoding', 'transcoder_{}_{}'.format(src_suffix, dst_suffix))
		decoder = config.get('transcoding', 'decoder_' + src_suffix) or config.get('transcoding', 'decoder')
		encoder = config.get('transcoding', 'encoder_' + dst_suffix) or config.get('transcoding', 'encoder')
		if not transcoder and (not decoder or not encoder):
			transcoder = config.get('transcoding', 'transcoder')
			if not transcoder:
				return request.error_formatter(0, 'No way to transcode from {} to {}'.format(src_suffix, dst_suffix))

		transcoder, decoder, encoder = map(lambda x: prepare_transcoding_cmdline(x, res.path, src_suffix, dst_suffix, dst_bitrate), [ transcoder, decoder, encoder ])
		try:
			if transcoder:
				dec_proc = None
				proc = subprocess.Popen(transcoder, stdout = subprocess.PIPE)
			else:
				dec_proc = subprocess.Popen(decoder, stdout = subprocess.PIPE)
				proc = subprocess.Popen(encoder, stdin = dec_proc.stdout, stdout = subprocess.PIPE)
		except:
			return request.error_formatter(0, 'Error while running the transcoding process')

		def transcode():
			try:
				while True:
					data = proc.stdout.read(8192)
					if not data:
						break
					yield data
			except:
				if dec_proc != None:
					dec_proc.terminate()
				proc.terminate()

			if dec_proc != None:
				dec_proc.wait()
			proc.wait()

		app.logger.info('Transcoding track {0.id} for user {1.id}. Source: {2} at {0.bitrate}kbps. Dest: {3} at {4}kbps'.format(res, request.user, src_suffix, dst_suffix, dst_bitrate))
		response = Response(transcode(), mimetype = dst_mimetype)
	else:
		response = send_file(res.path, mimetype = dst_mimetype)

	res.play_count = res.play_count + 1
	res.last_play = now()
	request.user.last_play = res
	request.user.last_play_date = now()
	store.commit()

	return response
Exemple #47
0
def stream_media():
	status, res = get_entity(request, Track)
	if not status:
		return res

	maxBitRate, format, timeOffset, size, estimateContentLength, client = map(request.args.get, [ 'maxBitRate', 'format', 'timeOffset', 'size', 'estimateContentLength', 'c' ])
	if format:
		format = format.lower()

	src_suffix = res.suffix()
	dst_suffix = res.suffix()
	dst_bitrate = res.bitrate
	dst_mimetype = res.content_type

	if client:
		prefs = store.get(ClientPrefs, (request.user.id, client))
		if not prefs:
			prefs = ClientPrefs()
			prefs.user_id = request.user.id
			prefs.client_name = client
			store.add(prefs)

		if prefs.format:
			dst_suffix = prefs.format
		if prefs.bitrate and prefs.bitrate < dst_bitrate:
			dst_bitrate = prefs.bitrate

	if maxBitRate:
		try:
			maxBitRate = int(maxBitRate)
		except:
			return request.error_formatter(0, 'Invalid bitrate value')

		if dst_bitrate > maxBitRate and maxBitRate != 0:
			dst_bitrate = maxBitRate

	if format and format != 'raw' and format != src_suffix:
		dst_suffix = format
		dst_mimetype = scanner.get_mime(dst_suffix)

	if format != 'raw' and (dst_suffix != src_suffix or dst_bitrate != res.bitrate):
		transcoder = config.get('transcoding', 'transcoder_{}_{}'.format(src_suffix, dst_suffix))
		decoder = config.get('transcoding', 'decoder_' + src_suffix) or config.get('transcoding', 'decoder')
		encoder = config.get('transcoding', 'encoder_' + dst_suffix) or config.get('transcoding', 'encoder')
		if not transcoder and (not decoder or not encoder):
			transcoder = config.get('transcoding', 'transcoder')
			if not transcoder:
				return request.error_formatter(0, 'No way to transcode from {} to {}'.format(src_suffix, dst_suffix))

		transcoder, decoder, encoder = map(lambda x: prepare_transcoding_cmdline(x, res.path, src_suffix, dst_suffix, dst_bitrate), [ transcoder, decoder, encoder ])
		try:
			if transcoder:
				proc = subprocess.Popen(transcoder, stdout = subprocess.PIPE)
			else:
				dec_proc = subprocess.Popen(decoder, stdout = subprocess.PIPE)
				proc = subprocess.Popen(encoder, stdin = dec_proc.stdout, stdout = subprocess.PIPE)
		except:
			return request.error_formatter(0, 'Error while running the transcoding process')

		def transcode():
			while True:
				data = proc.stdout.read(8192)
				if not data:
					break
				yield data
			proc.terminate()
			proc.wait()

		app.logger.info('Transcoding track {0.id} for user {1.id}. Source: {2} at {0.bitrate}kbps. Dest: {3} at {4}kbps'.format(res, request.user, src_suffix, dst_suffix, dst_bitrate))
		response = Response(transcode(), mimetype = dst_mimetype)
	else:
		response = send_file(res.path, mimetype = dst_mimetype)

	res.play_count = res.play_count + 1
	res.last_play = now()
	request.user.last_play = res
	request.user.last_play_date = now()
	store.commit()

	return response
Exemple #48
0
def change_mail_post(uid, user):
    mail = request.form.get('mail')
    # No validation, lol.
    user.mail = mail
    store.commit()
    return redirect(url_for('user_profile', uid = uid))
Exemple #49
0
def lastfm_unreg(uid, user):
    lfm = LastFm(app.config['LASTFM'], user, app.logger)
    lfm.unlink_account()
    store.commit()
    flash('Unlinked LastFM account')
    return redirect(url_for('user_profile', uid = uid))