~ubuntu-branches/ubuntu/saucy/wicd/saucy

« back to all changes in this revision

Viewing changes to .pc/31-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