comparison sat/tools/config.py @ 2562:26edcf3a30eb

core, setup: huge cleaning: - moved directories from src and frontends/src to sat and sat_frontends, which is the recommanded naming convention - move twisted directory to root - removed all hacks from setup.py, and added missing dependencies, it is now clean - use https URL for website in setup.py - removed "Environment :: X11 Applications :: GTK", as wix is deprecated and removed - renamed sat.sh to sat and fixed its installation - added python_requires to specify Python version needed - replaced glib2reactor which use deprecated code by gtk3reactor sat can now be installed directly from virtualenv without using --system-site-packages anymore \o/
author Goffi <goffi@goffi.org>
date Mon, 02 Apr 2018 19:44:50 +0200
parents src/tools/config.py@0046283a285d
children 56f94936df1e
comparison
equal deleted inserted replaced
2561:bd30dc3ffe5a 2562:26edcf3a30eb
1 #!/usr/bin/env python2
2 # -*- coding: utf-8 -*-
3
4 # SAT: a jabber client
5 # Copyright (C) 2009-2018 Jérôme Poisson (goffi@goffi.org)
6 # Copyright (C) 2013-2016 Adrien Cossa (souliane@mailoo.org)
7
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU Affero General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU Affero General Public License for more details.
17
18 # You should have received a copy of the GNU Affero General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21 """ Configuration related useful methods """
22
23 from sat.core.log import getLogger
24 log = getLogger(__name__)
25
26 from sat.core.constants import Const as C
27 from sat.core.i18n import _
28 from sat.core import exceptions
29
30 from ConfigParser import SafeConfigParser, DEFAULTSECT, NoOptionError, NoSectionError
31 from xdg import BaseDirectory
32 import os
33 import csv
34 import json
35
36
37 def fixConfigOption(section, option, value, silent=True):
38 """Force a configuration option value, writing it in the first found user
39 config file, eventually creating a new user config file if none is found.
40
41 @param section (str): the config section
42 @param option (str): the config option
43 @param value (str): the new value
44 @param silent (boolean): toggle logging output (must be True when called from sat.sh)
45 """
46 config = SafeConfigParser()
47 target_file = None
48 for file_ in C.CONFIG_FILES[::-1]:
49 # we will eventually update the existing file with the highest priority, if it's a user personal file...
50 if not silent:
51 log.debug(_(u"Testing file %s") % file_)
52 if os.path.isfile(file_):
53 if file_.startswith(os.path.expanduser('~')):
54 config.read([file_])
55 target_file = file_
56 break
57 if not target_file:
58 # ... otherwise we create a new config file for that user
59 target_file = BaseDirectory.save_config_path('sat') + '/sat.conf'
60 if section and section.upper() != DEFAULTSECT and not config.has_section(section):
61 config.add_section(section)
62 config.set(section, option, value)
63 with open(target_file, 'wb') as configfile:
64 config.write(configfile) # for the next time that user launches sat
65 if not silent:
66 if option in ('passphrase',): # list here the options storing a password
67 value = '******'
68 log.warning(_(u"Config auto-update: %(option)s set to %(value)s in the file %(config_file)s") %
69 {'option': option, 'value': value, 'config_file': target_file})
70
71 def parseMainConf():
72 """look for main .ini configuration file, and parse it"""
73 config = SafeConfigParser(defaults=C.DEFAULT_CONFIG)
74 try:
75 config.read(C.CONFIG_FILES)
76 except:
77 log.error(_("Can't read main config !"))
78 return config
79
80 def getConfig(config, section, name, default=None):
81 """Get a configuration option
82
83 @param config (SafeConfigParser): the configuration instance
84 @param section (str): section of the config file (None or '' for DEFAULT)
85 @param name (str): name of the option
86 @param default: value to use if not found, or Exception to raise an exception
87 @return (unicode, list, dict): parsed value
88 @raise: NoOptionError if option is not present and default is Exception
89 NoSectionError if section doesn't exists and default is Exception
90 exceptions.ParsingError error while parsing value
91 """
92 if not section:
93 section = DEFAULTSECT
94
95 try:
96 value = config.get(section, name).decode('utf-8')
97 except (NoOptionError, NoSectionError) as e:
98 if default is Exception:
99 raise e
100 return default
101
102 if name.endswith('_path') or name.endswith('_dir'):
103 value = os.path.expanduser(value)
104 # thx to Brian (http://stackoverflow.com/questions/186857/splitting-a-semicolon-separated-string-to-a-dictionary-in-python/186873#186873)
105 elif name.endswith('_list'):
106 value = csv.reader([value], delimiter=',', quotechar='"', skipinitialspace=True).next()
107 elif name.endswith('_dict'):
108 try:
109 value = json.loads(value)
110 except ValueError as e:
111 raise exceptions.ParsingError(u"Error while parsing data: {}".format(e))
112 if not isinstance(value, dict):
113 raise exceptions.ParsingError(u"{name} value is not a dict: {value}".format(name=name, value=value))
114 elif name.endswith('_json'):
115 try:
116 value = json.loads(value)
117 except ValueError as e:
118 raise exceptions.ParsingError(u"Error while parsing data: {}".format(e))
119 return value