1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-12-23 01:16:18 +00:00

Better handling of config files using python ConfigParser

Closes #4
This commit is contained in:
spl0k 2013-07-15 14:37:51 +02:00
parent 1b4415f98c
commit 811bbbe81f
9 changed files with 48 additions and 39 deletions

View File

@ -31,17 +31,19 @@ or as a WSGI application (on Apache for instance). But first:
### Configuration ### Configuration
Supysonic looks for two files for its configuration: `~/.supysonic` or `/etc/supysonic` (in this order). Supysonic looks for two files for its configuration: `/etc/supysonic` and `~/.supysonic`, merging values from the two files.
Options are set using the `KEY = VALUE` syntax. String values must be quote-enclosed. Configuration files must respect a structure similar to Windows INI file, with `[section]` headers and using a `KEY = VALUE`
or `KEY: VALUE` syntax.
Available settings are: Available settings are:
* **DATABASE_URI**: a SQLAlchemy [database URI](http://docs.sqlalchemy.org/en/rel_0_8/core/engines.html#database-urls). * Section **base**:
I personnaly use SQLite (`sqlite:////var/supysonic/supysonic.db`), but it might not be the brightest * **database_uri**: required, a SQLAlchemy [database URI](http://docs.sqlalchemy.org/en/rel_0_8/core/engines.html#database-urls).
idea for large libraries. I personnaly use SQLite (`sqlite:////var/supysonic/supysonic.db`), but it might not be the brightest idea for large libraries.
* **CACHE_DIR**: path to a cache folder. Mostly used for resized cover art images. * **cache_dir**: path to a cache folder. Mostly used for resized cover art images. Defaults to `<system temp dir>/supysonic`.
* **LOG_FILE**: path and base name of a rolling log file. * **log_file**: path and base name of a rolling log file.
* **LASTFM_KEY**: Last.FM [API key](http://www.last.fm/api/accounts) to enable scrobbling * Section **lastfm**:
* **LASTFM_SECRET**: Last.FM API secret matching the key. * **api_key**: Last.FM [API key](http://www.last.fm/api/accounts) to enable scrobbling
* **secret**: Last.FM API secret matching the key.
### Running as a standalone server ### Running as a standalone server

View File

@ -72,7 +72,7 @@ def cover_art():
if size > im.size[0] and size > im.size[1]: if size > im.size[0] and size > im.size[1]:
return send_file(os.path.join(res.path, 'cover.jpg')) return send_file(os.path.join(res.path, 'cover.jpg'))
size_path = os.path.join(config.get('CACHE_DIR'), str(size)) size_path = os.path.join(config.get('base', 'cache_dir'), str(size))
path = os.path.join(size_path, str(res.id)) path = os.path.join(size_path, str(res.id))
if os.path.exists(path): if os.path.exists(path):
return send_file(path) return send_file(path)

View File

@ -1,23 +1,31 @@
# coding: utf-8 # coding: utf-8
import os import os, sys, tempfile, ConfigParser
config = ConfigParser.RawConfigParser({ 'cache_dir': os.path.join(tempfile.gettempdir(), 'supysonic') })
def check(): def check():
path = os.path.join(os.path.expanduser('~'), '.supysonic') try:
if os.path.exists(path): ret = config.read([ '/etc/supysonic', os.path.expanduser('~/.supysonic') ])
return path except (ConfigParser.MissingSectionHeaderError, ConfigParser.ParsingError), e:
path = '/etc/supysonic' print >>sys.stderr, "Error while parsing the configuration file(s):\n%s" % str(e)
if os.path.exists(path):
return path
return False return False
config_path = check() if not ret:
config_dict = {} print >>sys.stderr, "No configuration file found"
if config_path: return False
with open(config_path) as f:
for line in f: try:
spl = line.split('=') config.get('base', 'database_uri')
config_dict[spl[0].strip()] = eval(spl[1]) except:
print >>sys.stderr, "No database URI set"
return False
return True
def get(section, name):
try:
return config.get(section, name)
except:
return None
def get(name):
return config_dict.get(name)

2
db.py
View File

@ -42,7 +42,7 @@ class UUID(TypeDecorator):
def now(): def now():
return datetime.datetime.now().replace(microsecond = 0) return datetime.datetime.now().replace(microsecond = 0)
engine = create_engine(config.get('DATABASE_URI'), convert_unicode = True) engine = create_engine(config.get('base', 'database_uri'), convert_unicode = True)
session = scoped_session(sessionmaker(autocommit = False, autoflush = False, bind = engine)) session = scoped_session(sessionmaker(autocommit = False, autoflush = False, bind = engine))
Base = declarative_base() Base = declarative_base()

View File

@ -7,9 +7,9 @@ from db import session
class LastFm: class LastFm:
def __init__(self, user, logger): def __init__(self, user, logger):
self.__user = user self.__user = user
self.__api_key = config.get('LASTFM_KEY') self.__api_key = config.get('lastfm', 'api_key')
self.__api_secret = config.get('LASTFM_SECRET') self.__api_secret = config.get('lastfm', 'secret')
self.__enabled = self.__api_key is not None self.__enabled = self.__api_key is not None and self.__api_secret is not None
self.__logger = logger self.__logger = logger
def link_account(self, token): def link_account(self, token):

View File

@ -5,11 +5,10 @@ import os.path, sys
if __name__ == '__main__': if __name__ == '__main__':
if not config.check(): if not config.check():
print >>sys.stderr, "Couldn't find configuration file"
sys.exit(1) sys.exit(1)
if not os.path.exists(config.get('CACHE_DIR')): if not os.path.exists(config.get('base', 'cache_dir')):
os.makedirs(config.get('CACHE_DIR')) os.makedirs(config.get('base', 'cache_dir'))
import db import db
from web import app from web import app

4
main.wsgi Normal file → Executable file
View File

@ -7,8 +7,8 @@ import config
if not config.check(): if not config.check():
sys.exit(1) sys.exit(1)
if not os.path.exists(config.get('CACHE_DIR')): if not os.path.exists(config.get('base', 'cache_dir')):
os.makedirs(config.get('CACHE_DIR')) os.makedirs(config.get('base', 'cache_dir'))
import db import db
db.init_db() db.init_db()

View File

@ -26,7 +26,7 @@ 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_KEY')) return render_template('profile.html', user = UserManager.get(session.get('userid'))[1], api_key = config.get('lastfm', 'api_key'))
@app.route('/user/changemail', methods = [ 'GET', 'POST' ]) @app.route('/user/changemail', methods = [ 'GET', 'POST' ])
def change_mail(): def change_mail():

4
web.py
View File

@ -6,10 +6,10 @@ app = Flask(__name__)
app.secret_key = '?9huDM\\H' app.secret_key = '?9huDM\\H'
import config import config
if config.get('LOG_FILE'): if config.get('base', 'log_file'):
import logging import logging
from logging.handlers import TimedRotatingFileHandler from logging.handlers import TimedRotatingFileHandler
handler = TimedRotatingFileHandler(config.get('LOG_FILE'), when = 'midnight') handler = TimedRotatingFileHandler(config.get('base', 'log_file'), when = 'midnight')
handler.setLevel(logging.WARNING) handler.setLevel(logging.WARNING)
app.logger.addHandler(handler) app.logger.addHandler(handler)