From 4cd1aace76e4599e7d69d04c3d2b11dac38d43ae Mon Sep 17 00:00:00 2001 From: spl0k Date: Sat, 7 Dec 2013 18:46:30 +0100 Subject: [PATCH 1/3] Introducing client prefs Allow setting default transcoding values for specific clients --- api/media.py | 42 +++++++++++++++++++++++++----------------- db.py | 8 ++++++++ 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/api/media.py b/api/media.py index 2c2d43d..3877b41 100755 --- a/api/media.py +++ b/api/media.py @@ -7,7 +7,7 @@ import subprocess import config, scanner from web import app -from db import Track, Folder, User, now, session +from db import Track, Folder, User, ClientPrefs, now, session from api import get_entity def prepare_transcoding_cmdline(base_cmdline, input_file, input_format, output_format, output_bitrate): @@ -24,33 +24,40 @@ def stream_media(): if not status: return res - maxBitRate, format, timeOffset, size, estimateContentLength = map(request.args.get, [ 'maxBitRate', 'format', 'timeOffset', 'size', 'estimateContentLength' ]) + maxBitRate, format, timeOffset, size, estimateContentLength, client = map(request.args.get, [ 'maxBitRate', 'format', 'timeOffset', 'size', 'estimateContentLength', 'c' ]) if format: format = format.lower() - do_transcoding = False src_suffix = res.suffix() dst_suffix = res.suffix() dst_bitrate = res.bitrate dst_mimetype = res.content_type - if format != 'raw': # That's from API 1.9.0 but whatever - if maxBitRate: - try: - maxBitRate = int(maxBitRate) - except: - return request.error_formatter(0, 'Invalid bitrate value') + if client: + prefs = ClientPrefs.query.get((request.user.id, client)) + if not prefs: + prefs = ClientPrefs(user_id = request.user.id, client_name = client) + session.add(prefs) - if dst_bitrate > maxBitRate and maxBitRate != 0: - do_transcoding = True - dst_bitrate = maxBitRate + if prefs.format: + dst_suffix = prefs.format + if prefs.bitrate and prefs.bitrate < dst_bitrate: + dst_bitrate = prefs.bitrate - if format and format != src_suffix: - do_transcoding = True - dst_suffix = format - dst_mimetype = scanner.get_mime(dst_suffix) + if maxBitRate: + try: + maxBitRate = int(maxBitRate) + except: + return request.error_formatter(0, 'Invalid bitrate value') - if do_transcoding: + 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') @@ -78,6 +85,7 @@ def stream_media(): 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) diff --git a/db.py b/db.py index 4c932e3..13bd479 100755 --- a/db.py +++ b/db.py @@ -97,6 +97,14 @@ class User(Base): 'shareRole': False } +class ClientPrefs(Base): + __tablename__ = 'client_prefs' + + user_id = Column(UUID, ForeignKey('user.id'), primary_key = True) + client_name = Column(String(32), nullable = False, primary_key = True) + format = Column(String(8), nullable = True) + bitrate = Column(Integer, nullable = True) + class Folder(Base): __tablename__ = 'folder' From 7947b55297b295155e3afdc52a3f349ad330aa0e Mon Sep 17 00:00:00 2001 From: spl0k Date: Sat, 7 Dec 2013 19:19:33 +0100 Subject: [PATCH 2/3] Web UI update with client prefs. Saving don't do anything for now --- templates/profile.html | 26 ++++++++++++++++++++++++++ user.py | 5 +++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/templates/profile.html b/templates/profile.html index ba2281f..2bed2f3 100755 --- a/templates/profile.html +++ b/templates/profile.html @@ -18,5 +18,31 @@
  • Change password
  • + +{% if clients %} +

    Known streaming clients

    +
    + + + {% for client in clients %} + + + + + + + {% endfor %} +
    ClientFormatMax bitrateForget
    {{ client.client_name }}
    + +
    +{% endif %} {% endblock %} diff --git a/user.py b/user.py index 15634f3..8b38919 100755 --- a/user.py +++ b/user.py @@ -4,7 +4,7 @@ from flask import request, session, flash, render_template, redirect, url_for, m from web import app from managers.user import UserManager -from db import User, session as db_sess +from db import User, ClientPrefs, session as db_sess import uuid, csv import config from lastfm import LastFm @@ -23,7 +23,8 @@ def user_index(): @app.route('/user/me') def user_profile(): - return render_template('profile.html', user = UserManager.get(session.get('userid'))[1], api_key = config.get('lastfm', 'api_key')) + prefs = ClientPrefs.query.filter(ClientPrefs.user_id == uuid.UUID(session.get('userid'))) + return render_template('profile.html', user = UserManager.get(session.get('userid'))[1], api_key = config.get('lastfm', 'api_key'), clients = prefs) @app.route('/user/changemail', methods = [ 'GET', 'POST' ]) def change_mail(): From 4beb2d677489e7ad3101ef17c72d3a0907402229 Mon Sep 17 00:00:00 2001 From: spl0k Date: Sun, 8 Dec 2013 16:20:43 +0100 Subject: [PATCH 3/3] Handle client prefs changes --- templates/profile.html | 7 +++++-- user.py | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/templates/profile.html b/templates/profile.html index 2bed2f3..9477138 100755 --- a/templates/profile.html +++ b/templates/profile.html @@ -19,8 +19,11 @@
  • Change password
  • -{% if clients %} -

    Known streaming clients

    +{% if clients.count() %} +

    Clients

    +

    Here's a list of clients you used to stream music. If you want to use transcoding or downsampling with one of them (for instance using a low bitrate on + mobile connections to reduce used bandwidth), but the client doesn't provide options to do so, you can set default values here. They'll only be used if no + transcoding/downsampling is requested by the client.

    diff --git a/user.py b/user.py index 8b38919..4edbcb5 100755 --- a/user.py +++ b/user.py @@ -26,6 +26,26 @@ def user_profile(): prefs = ClientPrefs.query.filter(ClientPrefs.user_id == uuid.UUID(session.get('userid'))) return render_template('profile.html', user = UserManager.get(session.get('userid'))[1], api_key = config.get('lastfm', 'api_key'), clients = prefs) +@app.route('/user/me', methods = [ 'POST' ]) +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 = ClientPrefs.query.get((uuid.UUID(session.get('userid')), client)) + if 'delete' in opts and opts['delete'] in [ 'on', 'true', 'checked', 'selected', '1' ]: + db_sess.delete(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 + + db_sess.commit() + flash('Clients preferences updated.') + return user_profile() + @app.route('/user/changemail', methods = [ 'GET', 'POST' ]) def change_mail(): user = UserManager.get(session.get('userid'))[1]
    ClientFormatMax bitrateForget