root/branch/PacketManipulator/PM/Manager/PreferenceManager.py @ 3933

Revision 3933, 6.9 kB (checked in by nopper, 4 years ago)

Forget to remove qnames

RevLine 
[3361]1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# Copyright (C) 2008 Adriano Monteiro Marques
4#
5# Author: Francesco Piccinno <stack.box@gmail.com>
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
[3499]21"""
22This module contains various class to load and store preferences to
23XML file using SAX parser provided by python
24"""
25
[3685]26import os
[3361]27import sys
[3509]28import os.path
[3361]29
30from xml.sax import handler, make_parser
31from xml.sax.saxutils import XMLGenerator
[3931]32from xml.sax.xmlreader import AttributesImpl
[3361]33
[3562]34from PM.Core.Logger import log
[3685]35from PM.Core.Const import PM_HOME, PM_PLUGINS_DIR, PLUGINS_DIR
[3498]36from PM.Core.Atoms import Singleton
[3361]37
38TYPES = {
[3364]39    str        : 'str',
[3361]40    bool       : 'bool',
41    dict       : 'dict',
42    float      : 'float',
43    int        : 'int',
44    list       : 'list',
45    tuple      : 'tuple'
46}
47
48class Option(object):
49    def __init__(self, value, default=None):
50        self.type = 'str'
51        self.converter = str
52        self.cbs = []
53
54        for k, v in TYPES.items():
55            if isinstance(value, k):
56                self.type = v
57                self.converter = k
58                break
59
[3394]60        self._value = self.converter(value)
61
[3361]62    def connect(self, callback, call=True):
63        self.cbs.append(callback)
64
65        if call:
66            callback(self.value)
67
68    def disconnect(self, callback):
69        if callback in self.cbs:
70            self.cbs.remove(callback)
71
72    def get_value(self):
[3394]73        assert isinstance(self._value, self.converter)
[3361]74        return self._value
75
76    def set_value(self, val):
77        # Check type?
78        if not isinstance(val, self.converter):
79            val = self.converter(val)
80
81        for cb in self.cbs:
82            # Lock if a callback returns True
83            if cb(val):
[3562]84                log.debug("Ignoring change")
[3361]85                return
86
[3562]87        log.debug("%s = %s" % (self, val))
[3361]88        self._value = val
89
90    def __repr__(self):
91        return "(%s)" % self._value
92
93    value = property(get_value, set_value)
94
95class PreferenceLoader(handler.ContentHandler):
96    def __init__(self, outfile):
97        self.outfile = outfile
98        self.options = {}
99
100    def startElement(self, name, attrs):
101        if name in ('bool', 'int', 'float', \
102                    'str', 'list', 'tuple'):
103
104            opt_name = None
105            opt_value = None
106
107            for attr in attrs.keys():
108                if attr == 'id':
109                    opt_name = attrs.get(attr)
110                if attr == 'value':
111                    opt_value = attrs.get(attr)
[3394]112           
113            try:
114                if name == 'bool':
115                    if opt_value.lower() == 'true' or opt_value == '1':
116                        opt_value = True
117                    else:
118                        opt_value = False
119                elif name == 'int':
120                    opt_value = int(opt_value)
121                elif name == 'float':
122                    opt_value = float(opt_value)
123                elif name == 'list':
124                    opt_value = opt_value.split(",")
125                    opt_value = filter(None, opt_value)
126                elif name == 'tuple':
127                    opt_value = opt_value.split(",")
128                    opt_value = filter(None, opt_value)
129                    opt_value = tuple(opt_value)
130            except:
131                return
[3361]132
133            if opt_name != None and opt_value != None:
134                self.options[opt_name] = Option(opt_value)
135
136class PreferenceWriter:
[3931]137    def startElement(self, names, attrs):
[3681]138        self.depth_idx += 1
139        self.writer.characters('  ' * self.depth_idx)
[3931]140        self.writer.startElement(names, attrs)
[3681]141
[3931]142    def endElement(self, name):
143        self.writer.endElement(name)
[3681]144        self.writer.characters('\n')
145        self.depth_idx -= 1
146
[3361]147    def __init__(self, fname, options):
148        output = open(fname, 'w')
[3681]149        self.depth_idx = -1
[3361]150        self.writer = XMLGenerator(output, 'utf-8')
151        self.writer.startDocument()
152
[3931]153        self.startElement('PacketManipulator', {}),
[3681]154        self.writer.characters('\n')
[3361]155
[3681]156        items = options.items()
157        items.sort()
158
159        for key, option in items:
160
[3361]161            attr_vals = {
[3933]162                'id' : key,
163                'value' : str(option.value)
[3361]164            }
165
[3931]166            attrs = AttributesImpl(attr_vals)
[3361]167
[3931]168            self.startElement(str(option.type), attrs)
169            self.endElement(str(option.type))
[3361]170
[3931]171        self.endElement('PacketManipulator')
[3361]172        self.writer.endDocument()
173        output.close()
174
175class Prefs(Singleton):
176    options = {
177        'gui.docking' : True,
[3760]178        'gui.expander.standard' : False,
[3364]179        'gui.maintab.sniffview.font' : 'Monospace 10',
[3585]180        'gui.maintab.sniffview.usecolors' : True,
[3361]181        'gui.maintab.hexview.font' : 'Monospace 10',
182        'gui.maintab.hexview.bpl' : 16,
[3585]183        'gui.maintab.sequenceview.font' : 'Monospace 10',
184        'gui.maintab.sequenceview.usecolors' : True,
[3694]185        'gui.maintab.autostop' : False,
186        'gui.maintab.askforsave' : True,
[3447]187
188        'gui.statustab.font' : 'Monospace 10',
[3394]189       
190        'gui.views.protocol_selector_tab' : True,
191        'gui.views.property_tab' : True,
[3404]192        'gui.views.status_tab' : True,
[3415]193        'gui.views.operations_tab' : True,
[3394]194        'gui.views.vte_tab' : False,
195        'gui.views.hack_tab' : False,
196        'gui.views.console_tab' : False,
[3361]197
[3393]198        'backend.system' : 'scapy',
[3685]199        'backend.scapy.interface' : '',
200
201        'plugins.paths' : os.pathsep.join((PM_PLUGINS_DIR, PLUGINS_DIR)),
202        'plugins.enabled' : ''
[3361]203    }
204
205    def __init__(self):
[3750]206        need_save = True
[3509]207        self.fname = os.path.join(PM_HOME, 'pm-prefs.xml')
[3361]208       
209        try:
210            opts = self.load_options()
211            self.options.update(self.load_options())
212        except Exception:
[3750]213            need_save = True
[3361]214
215        diff_dict = {}
216        for name, opt in self.options.items():
217            if not isinstance(opt, Option):
218                diff_dict[name] = Option(opt)
219
220        self.options.update(diff_dict)
221
[3750]222        if need_save:
223            self.write_options()
224
[3361]225    def load_options(self):
226        handler = PreferenceLoader(sys.stdout)
227        parser = make_parser()
228        parser.setContentHandler(handler)
229        parser.parse(self.fname)
230
231        return handler.options
232
233    def write_options(self):
234        writer = PreferenceWriter(self.fname, self.options)
235
236    def __getitem__(self, x):
237        return self.options[x]
Note: See TracBrowser for help on using the browser.