~jhonnyc/cgmail/jonathanc-branch

« back to all changes in this revision

Viewing changes to src/XMLAccounts.py

  • Committer: Marco Ferragina
  • Date: 2007-05-06 15:51:12 UTC
  • Revision ID: marco.ferragina@gmail.com-20070506155112-874uk2m8blrknyuf
Restructured package source dir. Now is much more organized. Implemented right click menu on account window treeview

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
import xml.dom
2
 
from xml.dom import minidom
3
 
import types
4
 
import os
5
 
 
6
 
from baseaccountmanager import BaseAccountManager, CannotSaveError
7
 
 
8
 
class NotTextNodeError: pass
9
 
 
10
 
class XMLAccounts(BaseAccountManager):
11
 
        def __init__(self):
12
 
                
13
 
                self.file = os.path.expanduser("~/.config/cgmail/accounts.xml")
14
 
                if not os.path.exists(self.file):
15
 
                        print "No xml config file found! Creating a default one..."
16
 
                        try:
17
 
                                os.makedirs(os.path.expanduser("~/.config/cgmail"))
18
 
                        except OSError:
19
 
                                pass
20
 
                        self.xmldoc = self.__create_default()
21
 
                        self.__save()
22
 
                        os.chmod(self.file, 0600)
23
 
                        print "...done"
24
 
 
25
 
                try:
26
 
                        self.xmldoc = minidom.parse(self.file)
27
 
                except IOError:
28
 
                        self.xmldoc = self.__create_default()
29
 
                        self.__save()
30
 
 
31
 
                self.__dic = self.__node_to_dic(self.xmldoc)
32
 
        
33
 
        def reset(self):
34
 
                print "removing", self.file
35
 
                try:
36
 
                        os.unlink(self.file)
37
 
                except:
38
 
                        print "Warnig: can't remove", self.file
39
 
        
40
 
        def get_accounts_dicts(self):
41
 
                if self.__dic["accounts"] == '':
42
 
                        return None
43
 
                else:
44
 
                        ret = self.__dic["accounts"]["account"]
45
 
                        # we want to return always a list of dicts
46
 
                        try:
47
 
                                if type(ret) == types.DictType:
48
 
                                        list = []
49
 
                                        list.append(ret)
50
 
                                        return list
51
 
                                else:
52
 
                                        return ret
53
 
                        except:
54
 
                                print "Error in XMLAccounts.py at get_accounts_dict"
55
 
        
56
 
        def remove_account(self, id):
57
 
                """
58
 
                remove the account identified by id
59
 
                """
60
 
                #print "removing account", id
61
 
 
62
 
                nodes = self.xmldoc.firstChild
63
 
                for account in nodes.childNodes:
64
 
                        if account.nodeType != account.ELEMENT_NODE:
65
 
                                continue
66
 
                        for param in account.childNodes:
67
 
                                if param.nodeName == "id":
68
 
                                        value = self.__get_text_from_node(param)
69
 
                                        if value == id:
70
 
                                                parent = param.parentNode # account
71
 
                                                acc = parent.parentNode # accounts
72
 
                                                acc.removeChild(parent)
73
 
                                                param.unlink()
74
 
                                                
75
 
                                                self.__save()
76
 
 
77
 
                                                # reload dic
78
 
                                                self.__dic = self.__node_to_dic(self.xmldoc)
79
 
 
80
 
                                                return
81
 
        
82
 
        def add_account(self, dic, force_id = None):
83
 
                """
84
 
                Add an account to configuration. dic is a dict in form
85
 
                of key, values for accounts parameters. This method
86
 
                will add automagically an unique identifier to the new
87
 
                account
88
 
                """
89
 
                
90
 
                if force_id != None:
91
 
                        dic["id"] = force_id
92
 
                else:
93
 
                        dic["id"] = self.__get_next_id()
94
 
 
95
 
                #print "adding account", dic
96
 
 
97
 
                ac = self.xmldoc.createElement("account")
98
 
                
99
 
                for key, value in dic.iteritems():
100
 
                        node = self.xmldoc.createElement(key)
101
 
                        nodevalue = self.xmldoc.createTextNode(value)
102
 
                        node.appendChild(nodevalue)
103
 
                        ac.appendChild(node)
104
 
 
105
 
                self.xmldoc.firstChild.appendChild(ac)
106
 
                self.__save()
107
 
 
108
 
                # reload dic
109
 
                self.__dic = self.__node_to_dic(self.xmldoc)
110
 
 
111
 
                return dic["id"]
112
 
        
113
 
        def __get_next_id(self):
114
 
                """
115
 
                get an unique id for accounts
116
 
                """
117
 
 
118
 
                if self.__dic["accounts"] == '':
119
 
                        # there are no accounts
120
 
                        return "1"
121
 
 
122
 
                accounts = self.__dic["accounts"].values()[0]
123
 
                if type(accounts) == types.DictType:
124
 
                        # there is only one account
125
 
                        return str(int(accounts["id"]) + 1)
126
 
 
127
 
                # more than one account
128
 
                max = 0
129
 
                for account in accounts:
130
 
                        if int(account["id"]) > max:
131
 
                                max = int(account["id"])
132
 
                return str(max + 1)
133
 
        
134
 
        def __save(self):
135
 
                """
136
 
                store the xml file
137
 
                """
138
 
                try:
139
 
                        xfile = open(self.file, "w")
140
 
                        #self.xmldoc.writexml(xfile, '', '\t', '\n')
141
 
                        self.xmldoc.writexml(xfile, '', '', '')
142
 
                        xfile.close()
143
 
                except Exception:
144
 
                        raise CannotSaveError()
145
 
        
146
 
        def __create_default(self):
147
 
                """
148
 
                Create the dafault config file if there isn't one
149
 
                """
150
 
                domImp = xml.dom.getDOMImplementation()
151
 
                doc = domImp.createDocument("", "accounts", None)
152
 
                return doc
153
 
                
154
 
        def __get_text_from_node(self, node):
155
 
                """
156
 
                scans through all children of node and gathers the
157
 
                text. if node has non-text child-nodes, then
158
 
                NotTextNodeError is raised.
159
 
                """
160
 
                t = ""
161
 
                for n in node.childNodes:
162
 
                        if n.nodeType == n.TEXT_NODE:
163
 
                                t += n.nodeValue
164
 
                        else:
165
 
                                raise NotTextNodeError
166
 
                return t.strip("\n\t")
167
 
 
168
 
 
169
 
        def __node_to_dic(self, node):
170
 
                """
171
 
                nodeToDic() scans through the children of node and makes a
172
 
                dictionary from the content.
173
 
                """
174
 
                dic = {}
175
 
                multlist = {} # holds temporary lists where there are multiple children
176
 
                multiple = False
177
 
                for n in node.childNodes:
178
 
                        if n.nodeType != n.ELEMENT_NODE:
179
 
                                continue
180
 
 
181
 
                        # find out if there are multiple records
182
 
                        if len(node.getElementsByTagName(n.nodeName)) > 1:
183
 
                                multiple = True
184
 
                                # and set up the list to hold the values
185
 
                                if not multlist.has_key(n.nodeName):
186
 
                                        multlist[n.nodeName] = []
187
 
 
188
 
                        try:
189
 
                                #text node
190
 
                                text = self.__get_text_from_node(n)
191
 
                        except NotTextNodeError:
192
 
                                if multiple:
193
 
                                # append to our list
194
 
                                        multlist[n.nodeName].append(self.__node_to_dic(n))
195
 
                                        dic.update({n.nodeName:multlist[n.nodeName]})
196
 
                                        continue
197
 
                                else:
198
 
                                # 'normal' node
199
 
                                        dic.update({n.nodeName:self.__node_to_dic(n)})
200
 
                                        continue
201
 
 
202
 
                        # text node
203
 
                        if multiple:
204
 
                                multlist[n.nodeName].append(text)
205
 
                                dic.update({n.nodeName:multlist[n.nodeName]})
206
 
                        else:
207
 
                                dic.update({n.nodeName:text})
208
 
                return dic
209
 
                
210
 
                
211
 
if __name__ == "__main__":
212
 
        x = XMLConfig()
213
 
        x.add_account({"username": "redgun", "password": "test", "server": "pop.libero.it"})