~ubuntu-branches/ubuntu/wily/wicd/wily

« back to all changes in this revision

Viewing changes to .pc/33-deepcopy_python27_fixes.patch/wicd/configmanager.py

  • Committer: Bazaar Package Importer
  • Author(s): David Paleino
  • Date: 2011-02-12 00:16:58 UTC
  • mfrom: (8.2.12 sid)
  • Revision ID: james.westby@ubuntu.com-20110212001658-a7yd2p5vepbr7xyp
Tags: 1.7.0+ds1-6
* debian/patches/:
  - 26-support_etc-network_scripts.patch refreshed, /etc/network/
    scripts should now be properly supported (Closes: #579497)
  - 31-dont_crash_on_notification_exceptions.patch added
    (Closes: #569755, #587303)
  - 32-prefer_gksu.patch added (Closes: #575403)
  - 33-deepcopy_python27_fixes.patch backported from Ubuntu,
    thanks to Matthieu Baerts (LP: #602825)
  - 34-dont_save_useless_config.patch added: don't save link quality,
    signal strength and bitrates in the configuration files.
    (Closes: #612918)
  - 35-restrict_netmode_characters.patch added, don't crash
    if the network mode is not what we expect. Thanks to Julien
    Blache for the patch (Closes: #550957)
* debian/control:
  - removed depedency on python-iniparse from wicd-daemon
  - removed Build-Depends on quilt
  - fixed typo in long description, thanks to Martin Eberhard Schauer
    (Closes: #611567)
  - bump Standards-Version to 3.9.1, no changes needed
  - use Breaks+Replaces instead of Conflicts+Replaces
* debian/rules:
  - don't use "--with quilt" anymore
* debian/po/pt_BR.po added: debconf translation for Brazilian
  Portuguese, thanks to Adriano Rafael Gomes (Closes: #594266)
* debian/wicd-daemon.config: don't ask if all users are already
  in the netdev group (Closes: #588078)
* debian/wicd-cli.8: explain -w/--save and -m/--name (Closes: #583586)
* debian/wicd-daemon.wicd.init, export $PATH, makes the daemon work
  in a clean environment. Thanks to Peter Palfrader (Closes: #604810)
* debian/wicd-curses.postrm: redirect stderr (Closes: #605338)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
 
 
3
""" configmanager -- Wicd configuration file manager
 
4
 
 
5
Wrapper around ConfigParser for wicd, though it should be
 
6
reusable for other purposes as well.
 
7
 
 
8
"""
 
9
 
 
10
#
 
11
#   Copyright (C) 2008-2009 Adam Blackburn
 
12
#   Copyright (C) 2008-2009 Dan O'Reilly
 
13
#
 
14
#   This program is free software; you can redistribute it and/or modify
 
15
#   it under the terms of the GNU General Public License Version 2 as
 
16
#   published by the Free Software Foundation.
 
17
#
 
18
#   This program is distributed in the hope that it will be useful,
 
19
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
20
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
21
#   GNU General Public License for more details.
 
22
#
 
23
#   You should have received a copy of the GNU General Public License
 
24
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
25
#
 
26
 
 
27
import os, copy
 
28
 
 
29
from ConfigParser import RawConfigParser, ParsingError
 
30
 
 
31
from wicd.misc import Noneify, to_unicode
 
32
 
 
33
from dbus import Int32
 
34
 
 
35
class ConfigManager(RawConfigParser):
 
36
    """ A class that can be used to manage a given configuration file. """
 
37
    def __init__(self, path, debug=False, mark_whitespace="`'`"):
 
38
        RawConfigParser.__init__(self)
 
39
        self.config_file = path
 
40
        self.debug = debug
 
41
        self.mrk_ws = mark_whitespace
 
42
        try:
 
43
            self.read(path)
 
44
        except ParsingError, e:
 
45
            self.write()
 
46
            try:
 
47
                self.read(path)
 
48
            except ParsingError, p:
 
49
                import sys
 
50
                print "Could not start wicd: %s" % p.message
 
51
                sys.exit(1)
 
52
 
 
53
    def __repr__(self):
 
54
        return self.config_file
 
55
    
 
56
    def __str__(self):
 
57
        return self.config_file
 
58
    
 
59
    def get_config(self):
 
60
        """ Returns the path to the loaded config file. """
 
61
        return self.config_file
 
62
        
 
63
    def set_option(self, section, option, value, write=False):
 
64
        """ Wrapper around ConfigParser.set
 
65
 
 
66
        Adds the option to write the config file change right away.
 
67
        Also forces all the values being written to type str, and
 
68
        adds the section the option should be written to if it
 
69
        doesn't exist already.
 
70
        
 
71
        """
 
72
        if not self.has_section(section):
 
73
            self.add_section(section)
 
74
        if isinstance(value, basestring):
 
75
            value = to_unicode(value)
 
76
            if value.startswith(' ') or value.endswith(' '):
 
77
                value = "%(ws)s%(value)s%(ws)s" % {"value" : value,
 
78
                                                   "ws" : self.mrk_ws}
 
79
        RawConfigParser.set(self, section, str(option), value)
 
80
        if write:
 
81
            self.write()
 
82
 
 
83
    def set(self, *args, **kargs):
 
84
        """ Calls the set_option method. """
 
85
        self.set_option(*args, **kargs)
 
86
        
 
87
    def get_option(self, section, option, default="__None__"):
 
88
        """ Wrapper around ConfigParser.get. 
 
89
        
 
90
        Automatically adds any missing sections, adds the ability
 
91
        to write a default value, and if one is provided prints if
 
92
        the default or a previously saved value is returned.
 
93
        
 
94
        """
 
95
        if not self.has_section(section):
 
96
            if default != "__None__":
 
97
                self.add_section(section)
 
98
            else:
 
99
                return None
 
100
    
 
101
        if self.has_option(section, option):
 
102
            ret = RawConfigParser.get(self, section, option)
 
103
            if (isinstance(ret, basestring) and ret.startswith(self.mrk_ws) 
 
104
                and ret.endswith(self.mrk_ws)):
 
105
                ret = ret[3:-3]
 
106
            if default:
 
107
                if self.debug:
 
108
                    print ''.join(['found ', option, ' in configuration ', 
 
109
                                   str(ret)])
 
110
        else:
 
111
            if default != "__None__":
 
112
                print 'did not find %s in configuration, setting default %s' % (option, str(default))
 
113
                self.set(section, option, str(default), write=True)
 
114
                ret = default
 
115
            else:
 
116
                ret = None
 
117
        
 
118
        # Try to intelligently handle the type of the return value.
 
119
        try:
 
120
            if not ret.startswith('0') or len(ret) == 1:
 
121
                ret = int(ret)
 
122
        except (ValueError, TypeError, AttributeError):
 
123
            ret = Noneify(ret)
 
124
        # This is a workaround for a python-dbus issue on 64-bit systems.
 
125
        if isinstance(ret, (int, long)):
 
126
            try:
 
127
                Int32(ret)
 
128
            except OverflowError:
 
129
                ret = str(ret)
 
130
        return to_unicode(ret)
 
131
    
 
132
    def get(self, *args, **kargs):
 
133
        """ Calls the get_option method """
 
134
        return self.get_option(*args, **kargs)
 
135
    
 
136
    def _write_one(self):
 
137
        """ Writes the loaded config file to disk. """
 
138
        for section in self.sections():
 
139
            if not section:
 
140
                self.remove_section(section)
 
141
        configfile = open(self.config_file, 'w')
 
142
        RawConfigParser.write(self, configfile)
 
143
        configfile.close()
 
144
        
 
145
    def remove_section(self, section):
 
146
        """ Wrapper around the ConfigParser.remove_section() method.
 
147
        
 
148
        This method only calls the ConfigParser.remove_section() method
 
149
        if the section actually exists.
 
150
        
 
151
        """
 
152
        if self.has_section(section):
 
153
            RawConfigParser.remove_section(self, section)
 
154
            
 
155
    def reload(self):
 
156
        """ Re-reads the config file, in case it was edited out-of-band. """
 
157
        self.read(self.config_file)
 
158
 
 
159
    def read(self, path):
 
160
        """ Reads the config file specified by 'path' then reads all the
 
161
        files in the directory obtained by adding '.d' to 'path'. The files
 
162
        in the '.d' directory are read in normal sorted order and section
 
163
        entries in these files override entries in the main file.
 
164
        """
 
165
        RawConfigParser.read(self, path)
 
166
 
 
167
        path_d = path + ".d"
 
168
        files = []
 
169
 
 
170
        if os.path.exists(path_d):
 
171
            files = [ os.path.join(path_d, f) for f in os.listdir(path_d) ]
 
172
            files.sort()
 
173
 
 
174
        for fname in files:
 
175
            p = RawConfigParser()
 
176
            p.read(fname)
 
177
            for section_name in p.sections():
 
178
                # New files override old, so remove first to avoid DuplicateSectionError.
 
179
                self.remove_section(section_name)
 
180
                self.add_section(section_name)
 
181
                for (name, value) in p.items(section_name):
 
182
                    self.set(section_name, name, value)
 
183
                # Store the filename this section was read from.
 
184
                self.set(section_name, '_filename_', fname)
 
185
 
 
186
 
 
187
    def _copy_section(self, name):
 
188
        # Yes, deepcopy sucks, but it is robust to changes in both
 
189
        # this class and RawConfigParser.
 
190
        p = copy.deepcopy(self)
 
191
        for sname in p.sections():
 
192
            if sname != name:
 
193
                p.remove_section(sname)
 
194
        p.config_file = p.get_option(name, '_filename_', p.config_file)
 
195
        p.remove_option(name, '_filename_')
 
196
        return p
 
197
 
 
198
    def write(self):
 
199
        """ Writes the loaded config file to disk. """
 
200
        # Really don't like this deepcopy.
 
201
        p = copy.deepcopy(self)
 
202
        for sname in p.sections():
 
203
            fname = p.get_option(sname, '_filename_')
 
204
            if fname and fname != self.config_file:
 
205
                section = self._copy_section(sname)
 
206
                p.remove_section(sname)
 
207
                section._write_one()
 
208
 
 
209
        for sname in p.sections():
 
210
            p.remove_option(sname, '_filename_')
 
211
        p._write_one()
 
212