mirror of
https://github.com/spl0k/supysonic.git
synced 2024-11-10 04:02:17 +00:00
Merge branch 'master' into lyrics
Conflicts: api/media.py
This commit is contained in:
commit
faacf40008
42
api/media.py
42
api/media.py
@ -10,7 +10,7 @@ from xml.etree import ElementTree
|
|||||||
|
|
||||||
import config, scanner
|
import config, scanner
|
||||||
from web import app
|
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 api import get_entity
|
||||||
|
|
||||||
from sqlalchemy import func
|
from sqlalchemy import func
|
||||||
@ -29,33 +29,40 @@ def stream_media():
|
|||||||
if not status:
|
if not status:
|
||||||
return res
|
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:
|
if format:
|
||||||
format = format.lower()
|
format = format.lower()
|
||||||
|
|
||||||
do_transcoding = False
|
|
||||||
src_suffix = res.suffix()
|
src_suffix = res.suffix()
|
||||||
dst_suffix = res.suffix()
|
dst_suffix = res.suffix()
|
||||||
dst_bitrate = res.bitrate
|
dst_bitrate = res.bitrate
|
||||||
dst_mimetype = res.content_type
|
dst_mimetype = res.content_type
|
||||||
|
|
||||||
if format != 'raw': # That's from API 1.9.0 but whatever
|
if client:
|
||||||
if maxBitRate:
|
prefs = ClientPrefs.query.get((request.user.id, client))
|
||||||
try:
|
if not prefs:
|
||||||
maxBitRate = int(maxBitRate)
|
prefs = ClientPrefs(user_id = request.user.id, client_name = client)
|
||||||
except:
|
session.add(prefs)
|
||||||
return request.error_formatter(0, 'Invalid bitrate value')
|
|
||||||
|
|
||||||
if dst_bitrate > maxBitRate and maxBitRate != 0:
|
if prefs.format:
|
||||||
do_transcoding = True
|
dst_suffix = prefs.format
|
||||||
dst_bitrate = maxBitRate
|
if prefs.bitrate and prefs.bitrate < dst_bitrate:
|
||||||
|
dst_bitrate = prefs.bitrate
|
||||||
|
|
||||||
if format and format != src_suffix:
|
if maxBitRate:
|
||||||
do_transcoding = True
|
try:
|
||||||
dst_suffix = format
|
maxBitRate = int(maxBitRate)
|
||||||
dst_mimetype = scanner.get_mime(dst_suffix)
|
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))
|
transcoder = config.get('transcoding', 'transcoder_{}_{}'.format(src_suffix, dst_suffix))
|
||||||
decoder = config.get('transcoding', 'decoder_' + src_suffix) or config.get('transcoding', 'decoder')
|
decoder = config.get('transcoding', 'decoder_' + src_suffix) or config.get('transcoding', 'decoder')
|
||||||
encoder = config.get('transcoding', 'encoder_' + dst_suffix) or config.get('transcoding', 'encoder')
|
encoder = config.get('transcoding', 'encoder_' + dst_suffix) or config.get('transcoding', 'encoder')
|
||||||
@ -83,6 +90,7 @@ def stream_media():
|
|||||||
proc.terminate()
|
proc.terminate()
|
||||||
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)
|
response = Response(transcode(), mimetype = dst_mimetype)
|
||||||
else:
|
else:
|
||||||
response = send_file(res.path, mimetype = dst_mimetype)
|
response = send_file(res.path, mimetype = dst_mimetype)
|
||||||
|
8
db.py
8
db.py
@ -97,6 +97,14 @@ class User(Base):
|
|||||||
'shareRole': False
|
'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):
|
class Folder(Base):
|
||||||
__tablename__ = 'folder'
|
__tablename__ = 'folder'
|
||||||
|
|
||||||
|
@ -18,5 +18,34 @@
|
|||||||
</li>
|
</li>
|
||||||
<li><a href="{{ url_for('change_password') }}">Change password</a></li>
|
<li><a href="{{ url_for('change_password') }}">Change password</a></li>
|
||||||
</ul>
|
</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 %}
|
{% endblock %}
|
||||||
|
|
||||||
|
25
user.py
25
user.py
@ -4,7 +4,7 @@ from flask import request, session, flash, render_template, redirect, url_for, m
|
|||||||
|
|
||||||
from web import app
|
from web import app
|
||||||
from managers.user import UserManager
|
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 uuid, csv
|
||||||
import config
|
import config
|
||||||
from lastfm import LastFm
|
from lastfm import LastFm
|
||||||
@ -23,7 +23,28 @@ def user_index():
|
|||||||
|
|
||||||
@app.route('/user/me')
|
@app.route('/user/me')
|
||||||
def user_profile():
|
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' ])
|
@app.route('/user/changemail', methods = [ 'GET', 'POST' ])
|
||||||
def change_mail():
|
def change_mail():
|
||||||
|
Loading…
Reference in New Issue
Block a user