1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-12-22 17:06:17 +00:00

Merge branch 'master' into lyrics

Conflicts:
	api/media.py
This commit is contained in:
spl0k 2014-01-14 11:27:26 +01:00
commit faacf40008
4 changed files with 85 additions and 19 deletions

View File

@ -10,7 +10,7 @@ from xml.etree import ElementTree
import config, scanner
from web import app
from db import Track, Album, Artist, Folder, User, now, session
from db import Track, Album, Artist, Folder, User, ClientPrefs, now, session
from api import get_entity
from sqlalchemy import func
@ -29,17 +29,26 @@ 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 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 prefs.format:
dst_suffix = prefs.format
if prefs.bitrate and prefs.bitrate < dst_bitrate:
dst_bitrate = prefs.bitrate
if maxBitRate:
try:
maxBitRate = int(maxBitRate)
@ -47,15 +56,13 @@ def stream_media():
return request.error_formatter(0, 'Invalid bitrate value')
if dst_bitrate > maxBitRate and maxBitRate != 0:
do_transcoding = True
dst_bitrate = maxBitRate
if format and format != src_suffix:
do_transcoding = True
if format and format != 'raw' and format != src_suffix:
dst_suffix = format
dst_mimetype = scanner.get_mime(dst_suffix)
if do_transcoding:
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')
@ -83,6 +90,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)

8
db.py
View File

@ -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'

View File

@ -18,5 +18,34 @@
</li>
<li><a href="{{ url_for('change_password') }}">Change password</a></li>
</ul>
{% if clients.count() %}
<h2>Clients</h2>
<p>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.</p>
<form method="post">
<table>
<tr><th>Client</th><th>Format</th><th>Max bitrate</th><th>Forget</th></tr>
{% for client in clients %}
<tr>
<td>{{ client.client_name }}</td>
<td><input type="text" name="{{ client.client_name }}_format" value="{{ client.format if client.format else '' }}" /></td>
<td><select name="{{ client.client_name }}_bitrate">
<option />
<option {{ 'selected="selected"' if client.bitrate == 64 else '' }}>64</option>
<option {{ 'selected="selected"' if client.bitrate == 96 else '' }}>96</option>
<option {{ 'selected="selected"' if client.bitrate == 128 else '' }}>128</option>
<option {{ 'selected="selected"' if client.bitrate == 192 else '' }}>192</option>
<option {{ 'selected="selected"' if client.bitrate == 256 else '' }}>256</option>
<option {{ 'selected="selected"' if client.bitrate == 320 else '' }}>320</option>
</select></td>
<td><input type="checkbox" name="{{ client.client_name }}_delete" /></td>
</tr>
{% endfor %}
</table>
<input type="submit" value="Save" />
</form>
{% endif %}
{% endblock %}

25
user.py
View File

@ -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,28 @@ 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/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():