1 # -*- coding: utf-8 -*-
2 # Copyright (c) 2009, 2010, 2011, 2013, 2014 Jack Kaliko <kaliko@azylum.org>
4 # This file is part of sima
6 # sima is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # sima is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with sima. If not, see <http://www.gnu.org/licenses/>.
22 Deal with configuration and data files.
23 Parse configuration file and set defaults for missing options.
31 from configparser import Error
32 from os import (makedirs, environ, stat, chmod)
33 from os.path import (join, isdir, isfile)
34 from stat import (S_IMODE, ST_MODE, S_IRWXO, S_IRWXG)
40 CONF_FILE = 'sima.cfg'
49 'internal': "Crop, Lastfm, RandomFallBack",
52 'history_duration': 8,
68 'queue_mode': "track", #TODO control values
70 'single_album': "false",
76 'queue_mode': "track", #TODO control values
78 'single_album': "false",
85 'flavour': "sensible", # in pure, sensible
92 class ConfMan(object): # CONFIG MANAGER CLASS
94 Configuration manager.
95 Default configuration is stored in DEFAULT_CONF dictionnary.
96 First init_config() run to get config from file.
97 Then control_conf() is run and retrieve configuration from defaults if not
99 These settings are then updated with command line options with
100 supersedes_config_with_cmd_line_options().
102 Order of priority for the origin of an option is then (lowest to highest):
104 * Env. Var for MPD host, port and password
105 * configuration file (overrides previous)
106 * command line options (overrides previous)
109 def __init__(self, options=None):
110 self.log = logging.getLogger('sima')
111 # options settings priority:
112 # defauts < env. var. < conf. file < command line
113 self.conf_file = options.get('conf_file')
114 self.config = configparser.ConfigParser(inline_comment_prefixes='#')
115 self.config.read_dict(DEFAULT_CONF)
116 # update DEFAULT_CONF with env. var.
118 self.startopt = options
122 self.supersedes_config_with_cmd_line_options()
124 self.config['sima']['db_file'] = join(self.config['sima']['var_dir'], 'sima.db')
126 def control_mod(self):
128 Controls conf file permissions.
130 mode = S_IMODE(stat(self.conf_file)[ST_MODE])
131 self.log.debug('file permission is: %o' % mode)
132 if mode & S_IRWXO or mode & S_IRWXG:
133 self.log.warning('File is readable by "other" and/or' +
134 ' "group" (actual permission %o octal).' %
136 self.log.warning('Consider setting permissions' +
139 def supersedes_config_with_cmd_line_options(self):
140 """Updates defaults settings with command line options"""
141 for sec in self.config.sections():
142 for opt in self.config.options(sec):
143 if opt in list(self.startopt.keys()):
144 self.config.set(sec, opt, str(self.startopt.get(opt)))
147 """Use MPD en.var. to set defaults"""
148 mpd_host, mpd_port, passwd = utils.get_mpd_environ()
150 self.log.info('Env. variable MPD_HOST set to "%s"' % mpd_host)
151 self.config['MPD'].update(host=mpd_host)
153 self.log.info('Env. variable MPD_HOST contains password.')
154 self.config['MPD'].update(password=passwd)
156 self.log.info('Env. variable MPD_PORT set to "%s".' % mpd_port)
157 self.config['MPD'].update(port=mpd_port)
159 def init_config(self):
161 Use XDG directory standard if exists
162 else use "HOME/(.config|.local/share)/sima/"
163 http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
166 homedir = environ.get('HOME')
168 if environ.get('XDG_DATA_HOME'):
169 data_dir = join(environ.get('XDG_DATA_HOME'), DIRNAME)
170 elif homedir and isdir(homedir) and homedir not in ['/']:
171 data_dir = join(homedir, '.local', 'share', DIRNAME)
173 self.log.error('Can\'t find a suitable location for data folder (XDG_DATA_HOME)')
174 self.log.error('Please use "--var_dir" to set a proper location')
177 if not isdir(data_dir):
179 chmod(data_dir, 0o700)
181 if self.startopt.get('conf_file'):
182 # No need to handle conf file location
184 elif environ.get('XDG_CONFIG_HOME'):
185 conf_dir = join(environ.get('XDG_CONFIG_HOME'), DIRNAME)
186 elif homedir and isdir(homedir) and homedir not in ['/']:
187 conf_dir = join(homedir, '.config', DIRNAME)
188 # Create conf_dir if necessary
189 if not isdir(conf_dir):
191 chmod(conf_dir, 0o700)
192 self.conf_file = join(conf_dir, CONF_FILE)
194 self.log.error('Can\'t find a suitable location for config folder (XDG_CONFIG_HOME)')
195 self.log.error('Please use "--config" to locate the conf file')
199 self.config['sima']['var_dir'] = join(data_dir)
201 # If no conf file present, uses defaults
202 if not isfile(self.conf_file):
205 self.log.info('Loading configuration from: %s' % self.conf_file)
209 self.config.read(self.conf_file)
215 # vim: ai ts=4 sw=4 sts=4 expandtab