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

Merge branch 'master' into db-setup

This commit is contained in:
spl0k 2018-09-15 16:04:43 +02:00
commit 5a065c75ae
8 changed files with 83 additions and 14 deletions

View File

@ -152,8 +152,7 @@ example of what it looks like:
<Directory /path/to/supysonic/cgi-bin> <Directory /path/to/supysonic/cgi-bin>
WSGIApplicationGroup %{GLOBAL} WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On WSGIPassAuthorization On
Order deny,allow Require all granted
Allow from all
</Directory> </Directory>
You might also need to run _Apache_ using the system default locale, as the one You might also need to run _Apache_ using the system default locale, as the one

View File

@ -37,7 +37,7 @@ setup(
author_email=project.AUTHOR_EMAIL, author_email=project.AUTHOR_EMAIL,
url=project.URL, url=project.URL,
license=project.LICENSE, license=project.LICENSE,
packages=find_packages(), packages=find_packages(exclude=['tests*']),
install_requires = reqs, install_requires = reqs,
extras_require = extras, extras_require = extras,
scripts=['bin/supysonic-cli', 'bin/supysonic-watcher'], scripts=['bin/supysonic-cli', 'bin/supysonic-watcher'],

View File

@ -18,7 +18,6 @@ import tempfile
class DefaultConfig(object): class DefaultConfig(object):
DEBUG = False DEBUG = False
SECRET_KEY = os.urandom(128)
tempdir = os.path.join(tempfile.gettempdir(), 'supysonic') tempdir = os.path.join(tempfile.gettempdir(), 'supysonic')
BASE = { BASE = {

View File

@ -93,10 +93,18 @@
<h2>Clients</h2> <h2>Clients</h2>
</div> </div>
<p>Here's a list of clients you used to stream music. If you want to use <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 transcoding or downsampling with one of them (for instance using a low bitrate
bitrate on mobile connections to reduce used bandwidth), but the client on mobile connections to reduce used bandwidth), but the client doesn't provide
doesn't provide options to do so, you can set default values here. They'll options to do so, you can set default values here. They'll only be used if no
only be used if no transcoding/downsampling is requested by the client.</p> transcoding/downsampling is requested by the client.<br/>
The first field is used to specify the format all files will be converted to. It
means if you enter <em>mp3</em>, all media will be served as mp3, wether the
original file is a mp3, ogg, FLAC or whatever. The bitrate option specify the
maximum streaming bitrate. If a file has a higher bitrate it will be transcoded
to match this value. Note that either the format or bitrate field can be left
out, for instance you can only enter a bitrate so files will be streamed using
their original format, only transcoded if their bitrate exceed the selected
one.</p>
<form method="post"> <form method="post">
<table id="clients" class="table table-striped"> <table id="clients" class="table table-striped">
<thead> <thead>
@ -106,7 +114,9 @@ only be used if no transcoding/downsampling is requested by the client.</p>
{% for client in clients %} {% for client in clients %}
<tr> <tr>
<td><label>{{ client.client_name }}</label></td> <td><label>{{ client.client_name }}</label></td>
<td><input type="text" class="form-control" name="{{ client.client_name }}_format" value="{{ client.format if client.format else '' }}" /></td> <td><input type="text" class="form-control" name="{{ client.client_name }}_format"
value="{{ client.format if client.format else '' }}"
pattern="[a-z0-9]{0,8}" title="Up to 8 letters and numbers" /></td>
<td><select class="form-control" name="{{ client.client_name }}_bitrate"> <td><select class="form-control" name="{{ client.client_name }}_bitrate">
<option /> <option />
<option {{ 'selected="selected"' if client.bitrate == 64 else '' }}>64</option> <option {{ 'selected="selected"' if client.bitrate == 64 else '' }}>64</option>

View File

@ -8,10 +8,11 @@
# #
# Distributed under terms of the GNU AGPLv3 license. # Distributed under terms of the GNU AGPLv3 license.
import io
import mimetypes import mimetypes
from flask import Flask from flask import Flask
from os import makedirs, path from os import makedirs, path, urandom
from pony.orm import db_session from pony.orm import db_session
from .config import IniConfig from .config import IniConfig
@ -24,13 +25,13 @@ def create_application(config = None):
app = Flask(__name__) app = Flask(__name__)
app.config.from_object('supysonic.config.DefaultConfig') app.config.from_object('supysonic.config.DefaultConfig')
if not config: if not config: # pragma: nocover
config = IniConfig.from_common_locations() config = IniConfig.from_common_locations()
app.config.from_object(config) app.config.from_object(config)
# Set loglevel # Set loglevel
logfile = app.config['WEBAPP']['log_file'] logfile = app.config['WEBAPP']['log_file']
if logfile: if logfile: # pragma: nocover
import logging import logging
from logging.handlers import TimedRotatingFileHandler from logging.handlers import TimedRotatingFileHandler
handler = TimedRotatingFileHandler(logfile, when = 'midnight') handler = TimedRotatingFileHandler(logfile, when = 'midnight')
@ -59,7 +60,18 @@ def create_application(config = None):
# Test for the cache directory # Test for the cache directory
cache_path = app.config['WEBAPP']['cache_dir'] cache_path = app.config['WEBAPP']['cache_dir']
if not path.exists(cache_path): if not path.exists(cache_path):
makedirs(cache_path) makedirs(cache_path) # pragma: nocover
# Read or create secret key
secret_path = path.join(cache_path, 'secret')
if path.exists(secret_path):
with io.open(secret_path, 'rb') as f:
app.secret_key = f.read()
else:
secret = urandom(128)
with io.open(secret_path, 'wb') as f:
f.write(secret)
app.secret_key = secret
# Import app sections # Import app sections
if app.config['WEBAPP']['mount_webui']: if app.config['WEBAPP']['mount_webui']:

View File

@ -14,6 +14,7 @@ from .test_config import ConfigTestCase
from .test_db import DbTestCase from .test_db import DbTestCase
from .test_lastfm import LastFmTestCase from .test_lastfm import LastFmTestCase
from .test_scanner import ScannerTestCase from .test_scanner import ScannerTestCase
from .test_secret import SecretTestCase
from .test_watcher import suite as watcher_suite from .test_watcher import suite as watcher_suite
def suite(): def suite():
@ -25,6 +26,7 @@ def suite():
suite.addTest(watcher_suite()) suite.addTest(watcher_suite())
suite.addTest(unittest.makeSuite(CLITestCase)) suite.addTest(unittest.makeSuite(CLITestCase))
suite.addTest(unittest.makeSuite(LastFmTestCase)) suite.addTest(unittest.makeSuite(LastFmTestCase))
suite.addTest(unittest.makeSuite(SecretTestCase))
return suite return suite

48
tests/base/test_secret.py Normal file
View File

@ -0,0 +1,48 @@
#!/usr/bin/env python
# coding: utf-8
#
# This file is part of Supysonic.
# Supysonic is a Python implementation of the Subsonic server API.
#
# Copyright (C) 2018 Alban 'spl0k' Féron
#
# Distributed under terms of the GNU AGPLv3 license.
import os
import unittest
import shutil
import tempfile
from supysonic.db import init_database, release_database
from supysonic.web import create_application
from ..testbase import TestConfig
class SecretTestCase(unittest.TestCase):
def setUp(self):
self.__dbfile = tempfile.mkstemp()[1]
self.__dir = tempfile.mkdtemp()
self.config = TestConfig(False, False)
self.config.BASE['database_uri'] = 'sqlite:///' + self.__dbfile
self.config.WEBAPP['cache_dir'] = self.__dir
init_database(self.config.BASE['database_uri'], True)
release_database()
def tearDown(self):
shutil.rmtree(self.__dir)
os.remove(self.__dbfile)
def test_key(self):
app1 = create_application(self.config)
release_database()
app2 = create_application(self.config)
release_database()
self.assertEqual(app1.secret_key, app2.secret_key)
if __name__ == '__main__':
unittest.main()

View File

@ -8,7 +8,6 @@
# Distributed under terms of the GNU AGPLv3 license. # Distributed under terms of the GNU AGPLv3 license.
import inspect import inspect
import io
import os import os
import shutil import shutil
import unittest import unittest