コード例 #1
0
ファイル: user.py プロジェクト: hhm0/supysonic
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'))
コード例 #2
0
ファイル: annotation.py プロジェクト: andrenam/supysonic
def try_star(ent, starred_ent, eid):
    """ Stars an entity

    :param ent: entity class, Folder, Artist, Album or Track
    :param starred_ent: class used for the db representation of the starring of ent
    :param eid: id of the entity to star
    :return error dict, if any. None otherwise
    """

    try:
        uid = uuid.UUID(eid)
    except:
        return { 'code': 0, 'message': 'Invalid {} id {}'.format(ent.__name__, eid) }

    if store.get(starred_ent, (request.user.id, uid)):
        return { 'code': 0, 'message': '{} {} already starred'.format(ent.__name__, eid) }

    e = store.get(ent, uid)
    if not e:
        return { 'code': 70, 'message': 'Unknown {} id {}'.format(ent.__name__, eid) }

    starred = starred_ent()
    starred.user_id = request.user.id
    starred.starred_id = uid
    store.add(starred)

    return None
コード例 #3
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'))
コード例 #4
0
ファイル: chat.py プロジェクト: sanderd/supysonic
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({})
コード例 #5
0
ファイル: chat.py プロジェクト: glogiotatidis/supysonic
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({})
コード例 #6
0
ファイル: __init__.py プロジェクト: hhm0/supysonic
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
コード例 #7
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
コード例 #8
0
ファイル: __init__.py プロジェクト: andrenam/supysonic
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
コード例 #9
0
ファイル: annotation.py プロジェクト: hhm0/supysonic
	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
コード例 #10
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({})
コード例 #11
0
ファイル: annotation.py プロジェクト: sanderd/supysonic
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({})
コード例 #12
0
ファイル: annotation.py プロジェクト: sanderd/supysonic
    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
コード例 #13
0
ファイル: playlists.py プロジェクト: andrenam/supysonic
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({})
コード例 #14
0
ファイル: annotation.py プロジェクト: hhm0/supysonic
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({})
コード例 #15
0
ファイル: playlist.py プロジェクト: davidbrenner/supysonic
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 '''
コード例 #16
0
def try_star(ent, starred_ent, eid):
    """ Stars an entity

    :param ent: entity class, Folder, Artist, Album or Track
    :param starred_ent: class used for the db representation of the starring of ent
    :param eid: id of the entity to star
    :return error dict, if any. None otherwise
    """

    try:
        uid = uuid.UUID(eid)
    except:
        return {
            'code': 0,
            'message': 'Invalid {} id {}'.format(ent.__name__, eid)
        }

    if store.get(starred_ent, (request.user.id, uid)):
        return {
            'code': 0,
            'message': '{} {} already starred'.format(ent.__name__, eid)
        }

    e = store.get(ent, uid)
    if not e:
        return {
            'code': 70,
            'message': 'Unknown {} id {}'.format(ent.__name__, eid)
        }

    starred = starred_ent()
    starred.user_id = request.user.id
    starred.starred_id = uid
    store.add(starred)

    return None
コード例 #17
0
ファイル: media.py プロジェクト: sanderd/supysonic
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
コード例 #18
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