Merged Anton Batenev's report of Nicolas Alvarez' unicode-in-be-new bug
[be.git] / libbe / storage / util / config.py
1 # Copyright (C) 2005-2010 Aaron Bentley and Panometrics, Inc.
2 #                         Gianluca Montecchi <gian@grys.it>
3 #                         W. Trevor King <wking@drexel.edu>
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
19 """Create, save, and load the per-user config file at :func:`path`.
20 """
21
22 import ConfigParser
23 import codecs
24 import os.path
25
26 import libbe
27 import libbe.util.encoding
28 if libbe.TESTING == True:
29     import doctest
30
31
32 default_encoding = libbe.util.encoding.get_filesystem_encoding()
33 """Default filesystem encoding.
34
35 Initialized with :func:`libbe.util.encoding.get_filesystem_encoding`.
36 """
37
38 def path():
39     """Return the path to the per-user config file.
40     """
41     return os.path.expanduser("~/.bugs_everywhere")
42
43 def set_val(name, value, section="DEFAULT", encoding=None):
44     """Set a value in the per-user config file.
45
46     Parameters
47     ----------
48     name : str
49       The name of the value to set.
50     value : str or None
51       The new value to set (or None to delete the value).
52     section : str
53       The section to store the name/value in.
54     encoding : str
55       The config file's encoding, defaults to :data:`default_encoding`.
56     """
57     if encoding == None:
58         encoding = default_encoding
59     config = ConfigParser.ConfigParser()
60     if os.path.exists(path()) == False: # touch file or config
61         open(path(), 'w').close()       # read chokes on missing file
62     f = codecs.open(path(), 'r', encoding)
63     config.readfp(f, path())
64     f.close()
65     if value is not None:
66         config.set(section, name, value)
67     else:
68         config.remove_option(section, name)
69     f = codecs.open(path(), 'w', encoding)
70     config.write(f)
71     f.close()
72
73 def get_val(name, section="DEFAULT", default=None, encoding=None):
74     """Get a value from the per-user config file
75
76     Parameters
77     ----------
78     name : str
79       The name of the value to set.
80     section : str
81       The section to store the name/value in.
82     default :
83       The value to return if `name` is not set.
84     encoding : str
85       The config file's encoding, defaults to :data:`default_encoding`.
86
87     Examples
88     --------
89
90     >>> get_val("junk") is None
91     True
92     >>> set_val("junk", "random")
93     >>> get_val("junk")
94     u'random'
95     >>> set_val("junk", None)
96     >>> get_val("junk") is None
97     True
98     """
99     if os.path.exists(path()):
100         if encoding == None:
101             encoding = default_encoding
102         config = ConfigParser.ConfigParser()
103         f = codecs.open(path(), 'r', encoding)
104         config.readfp(f, path())
105         f.close()
106         try:
107             return config.get(section, name)
108         except ConfigParser.NoOptionError:
109             return default
110     else:
111         return default
112
113 if libbe.TESTING == True:
114     suite = doctest.DocTestSuite()