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

Revision 3509, 6.3 kB (checked in by nopper, 5 years ago)

preference file is now stored under ~/.PacketManipulator

Line 
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
21"""
22This module contains various class to load and store preferences to
23XML file using SAX parser provided by python
24"""
25
26import sys
27import os.path
28
29from xml.sax import handler, make_parser
30from xml.sax.saxutils import XMLGenerator
31from xml.sax.xmlreader import AttributesNSImpl
32
33from PM.Core.Const import PM_HOME
34from PM.Core.Atoms import Singleton
35
36TYPES = {
37    str        : 'str',
38    bool       : 'bool',
39    dict       : 'dict',
40    float      : 'float',
41    int        : 'int',
42    list       : 'list',
43    tuple      : 'tuple'
44}
45
46class Option(object):
47    def __init__(self, value, default=None):
48        self.type = 'str'
49        self.converter = str
50        self.cbs = []
51
52        for k, v in TYPES.items():
53            if isinstance(value, k):
54                self.type = v
55                self.converter = k
56                break
57
58        self._value = self.converter(value)
59
60    def connect(self, callback, call=True):
61        self.cbs.append(callback)
62
63        if call:
64            callback(self.value)
65
66    def disconnect(self, callback):
67        if callback in self.cbs:
68            self.cbs.remove(callback)
69
70    def get_value(self):
71        assert isinstance(self._value, self.converter)
72        return self._value
73
74    def set_value(self, val):
75        # Check type?
76        if not isinstance(val, self.converter):
77            val = self.converter(val)
78
79        for cb in self.cbs:
80            # Lock if a callback returns True
81            if cb(val):
82                print "set_value(): Ignoring change"
83                return
84
85        print "set_value(): %s = %s" % (self, val)
86        self._value = val
87
88    def __repr__(self):
89        return "(%s)" % self._value
90
91    value = property(get_value, set_value)
92
93class PreferenceLoader(handler.ContentHandler):
94    def __init__(self, outfile):
95        self.outfile = outfile
96        self.options = {}
97
98    def startElement(self, name, attrs):
99        if name in ('bool', 'int', 'float', \
100                    'str', 'list', 'tuple'):
101
102            opt_name = None
103            opt_value = None
104
105            for attr in attrs.keys():
106                if attr == 'id':
107                    opt_name = attrs.get(attr)
108                if attr == 'value':
109                    opt_value = attrs.get(attr)
110           
111            try:
112                if name == 'bool':
113                    if opt_value.lower() == 'true' or opt_value == '1':
114                        opt_value = True
115                    else:
116                        opt_value = False
117                elif name == 'int':
118                    opt_value = int(opt_value)
119                elif name == 'float':
120                    opt_value = float(opt_value)
121                elif name == 'list':
122                    opt_value = opt_value.split(",")
123                    opt_value = filter(None, opt_value)
124                elif name == 'tuple':
125                    opt_value = opt_value.split(",")
126                    opt_value = filter(None, opt_value)
127                    opt_value = tuple(opt_value)
128            except:
129                return
130
131            if opt_name != None and opt_value != None:
132                self.options[opt_name] = Option(opt_value)
133
134class PreferenceWriter:
135    def __init__(self, fname, options):
136        output = open(fname, 'w')
137        self.writer = XMLGenerator(output, 'utf-8')
138        self.writer.startDocument()
139        self.writer.startElementNS((None, 'PacketManipulator'), 'PacketManipulator', {})
140
141        for key, option in options.items():
142
143            attr_vals = {
144                (None, u'id') : key,
145                (None, u'value') : str(option.value)
146            }
147
148            attr_qnames = {
149                (None, u'id') : u'id',
150                (None, u'value') : u'value'
151            }
152
153            attrs = AttributesNSImpl(attr_vals, attr_qnames)
154            self.writer.startElementNS((None, str(option.type)), str(option.type), attrs)
155            self.writer.endElementNS((None, str(option.type)), str(option.type))
156
157        self.writer.endElementNS((None, 'PacketManipulator'), 'PacketManipulator')
158        self.writer.endDocument()
159        output.close()
160
161class Prefs(Singleton):
162    options = {
163        'gui.docking' : True,
164        'gui.maintab.sniffview.font' : 'Monospace 10',
165        'gui.maintab.sniffview.usecolors' : False,
166        'gui.maintab.hexview.font' : 'Monospace 10',
167        'gui.maintab.hexview.bpl' : 16,
168
169        'gui.statustab.font' : 'Monospace 10',
170       
171        'gui.views.protocol_selector_tab' : True,
172        'gui.views.property_tab' : True,
173        'gui.views.status_tab' : True,
174        'gui.views.operations_tab' : True,
175        'gui.views.vte_tab' : False,
176        'gui.views.hack_tab' : False,
177        'gui.views.console_tab' : False,
178
179        'backend.system' : 'scapy',
180        'backend.scapy.interface' : ''
181    }
182
183    def __init__(self):
184        self.fname = os.path.join(PM_HOME, 'pm-prefs.xml')
185       
186        try:
187            opts = self.load_options()
188            self.options.update(self.load_options())
189        except Exception:
190            pass
191
192        diff_dict = {}
193        for name, opt in self.options.items():
194            if not isinstance(opt, Option):
195                diff_dict[name] = Option(opt)
196
197        self.options.update(diff_dict)
198
199    def load_options(self):
200        handler = PreferenceLoader(sys.stdout)
201        parser = make_parser()
202        parser.setContentHandler(handler)
203        parser.parse(self.fname)
204
205        return handler.options
206
207    def write_options(self):
208        writer = PreferenceWriter(self.fname, self.options)
209
210    def __getitem__(self, x):
211        return self.options[x]
Note: See TracBrowser for help on using the browser.