0
|
1 #!/usr/bin/python |
|
2 # -*- coding: utf-8 -*- |
|
3 |
|
4 """ |
|
5 SAT: a jabber client |
|
6 Copyright (C) 2009 Jérôme Poisson (goffi@goffi.org) |
|
7 |
|
8 This program is free software: you can redistribute it and/or modify |
|
9 it under the terms of the GNU General Public License as published by |
|
10 the Free Software Foundation, either version 3 of the License, or |
|
11 (at your option) any later version. |
|
12 |
|
13 This program is distributed in the hope that it will be useful, |
|
14 but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
16 GNU General Public License for more details. |
|
17 |
|
18 You should have received a copy of the GNU General Public License |
|
19 along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
20 """ |
|
21 |
|
22 from __future__ import with_statement |
|
23 |
|
24 import os.path |
|
25 import time |
|
26 import pickle |
|
27 from logging import debug, info, error |
|
28 |
|
29 const_SAVEFILE_PARAM=os.path.expanduser("~/.sat_param.save") |
|
30 const_SAVEFILE_HISTORY=os.path.expanduser("~/.sat_history.save") |
|
31 |
|
32 class Memory: |
|
33 """This class manage all persistent informations""" |
|
34 |
|
35 def __init__(self): |
|
36 info ("Memory manager init") |
|
37 self.contact={} |
|
38 self.presenceStatus={} |
|
39 self.params={} |
|
40 self.history={} |
|
41 self.disco={} #XXX: maybe best in a separate class |
|
42 self.features={} |
|
43 self.load() |
|
44 |
|
45 def load_default_params(self): |
|
46 """Load default value, in case of no save file or error.""" |
|
47 |
|
48 self.createParam("JabberID", "goffi@jabber.goffi.int/TestScript", "string", "Connection") |
|
49 self.createParam("Password", "toto", "password", "Connection") |
|
50 self.createParam("Server", "jabber.goffi.int", "string", "Connection") |
|
51 self.createParam("IP", "192.168.0.2", "string", "File Transfert") |
|
52 self.createParam("Port", "28915", "string", "File Transfert") |
|
53 self.createParam("Watched", "test@jabber.goffi.int", "string", "Misc") #TODO: a mettre dans un plugin |
|
54 |
|
55 def load(self): |
|
56 """Load parameters and all memory things from file/db""" |
|
57 |
|
58 #first parameters |
|
59 if os.path.exists(const_SAVEFILE_PARAM): |
|
60 try: |
|
61 with open(const_SAVEFILE_PARAM, 'r') as params_pickle: |
|
62 self.params=pickle.load(params_pickle) |
|
63 debug("params loaded") |
|
64 except: |
|
65 error ("Can't load params !") |
|
66 self.load_default_params() |
|
67 else: |
|
68 self.load_default_params() |
|
69 |
|
70 #history |
|
71 if os.path.exists(const_SAVEFILE_HISTORY): |
|
72 try: |
|
73 with open(const_SAVEFILE_HISTORY, 'r') as history_pickle: |
|
74 self.history=pickle.load(history_pickle) |
|
75 debug("history loaded") |
|
76 except: |
|
77 error ("Can't load history !") |
|
78 |
|
79 |
|
80 def save(self): |
|
81 """Save parameters and all memory things to file/db""" |
|
82 with open(const_SAVEFILE_PARAM, 'w') as params_pickle: |
|
83 pickle.dump(self.params, params_pickle) |
|
84 with open(const_SAVEFILE_HISTORY, 'w') as history_pickle: |
|
85 pickle.dump(self.history, history_pickle) |
|
86 |
|
87 def addToHistory(self, me_jid, from_jid, to_jid, type, message): |
|
88 me_short=me_jid.userhost() |
|
89 from_short=from_jid.userhost() |
|
90 to_short=to_jid.userhost() |
|
91 |
|
92 if from_jid==me_jid: |
|
93 key=to_short |
|
94 else: |
|
95 key=from_short |
|
96 |
|
97 if not self.history.has_key(me_short): |
|
98 self.history[me_short]={} |
|
99 if not self.history[me_short].has_key(key): |
|
100 self.history[me_short][key]={} |
|
101 |
|
102 self.history[me_short][key][int(time.time())] = (from_short, message) |
|
103 |
|
104 def getHistory(self, from_jid, to_jid, size): |
|
105 ret={} |
|
106 if not self.history.has_key(from_jid): |
|
107 error("source JID not found !") |
|
108 #TODO: throw an error here |
|
109 return {} |
|
110 if not self.history[from_jid].has_key(to_jid): |
|
111 error("dest JID not found !") |
|
112 #TODO: throw an error here |
|
113 return {} |
|
114 stamps=self.history[from_jid][to_jid].keys() |
|
115 stamps.sort() |
|
116 for stamp in stamps[-size:]: |
|
117 ret[stamp]=self.history[from_jid][to_jid][stamp] |
|
118 |
|
119 return ret |
|
120 |
|
121 def addContact(self, JID, attributes, groups): |
|
122 debug("Memory addContact: %s",JID) |
|
123 assert(isinstance(attributes,dict)) |
|
124 assert(isinstance(groups,list)) |
|
125 self.contact[JID]=[attributes, groups] |
|
126 |
|
127 def addPresenceStatus(self, jid, type, show, status, priority): |
|
128 self.presenceStatus[jid]=[type, show, status, priority] |
|
129 |
|
130 def getContacts(self): |
|
131 debug ("Memory getContact OK (%s)", self.contact) |
|
132 ret=[] |
|
133 for contact in self.contact: |
|
134 ret.append([contact] + [self.contact[contact][0]] + [self.contact[contact][1]]) #very ugly I know ! |
|
135 return ret |
|
136 |
|
137 def getPresenceStatus(self): |
|
138 status=[] |
|
139 for contact, contactStatus in self.presenceStatus.items(): |
|
140 status.append([contact]+contactStatus) |
|
141 debug ("Memory getPresenceStatus (%s)", status) |
|
142 return status |
|
143 |
|
144 def getParamV(self, name, namespace): |
|
145 """Helper method to get the value in the good type |
|
146 getParamV stands for GetParamValue""" |
|
147 if not self.params.has_key(namespace) or not self.params[namespace].has_key(name): |
|
148 error("Requested param %s in namespace %s doesn't exist !" , name, namespace) |
|
149 return None |
|
150 return self.params[namespace][name][0] |
|
151 |
|
152 |
|
153 def getParam(self, name, namespace): |
|
154 if self.params.has_key(namespace) and self.params[namespace].has_key(name): |
|
155 return self.params[namespace][name] |
|
156 return ["",""] |
|
157 |
|
158 def getParams(self, namespace): |
|
159 if self.params.has_key(namespace): |
|
160 ret=[] |
|
161 for name in self.params[namespace]: |
|
162 ret.append([name] + self.params[namespace][name]) |
|
163 return ret |
|
164 return [[]] |
|
165 |
|
166 def getParamsCategories(self): |
|
167 """return the namespaces availables""" |
|
168 return self.params.keys() |
|
169 |
|
170 def setParam(self, name, value, namespace): |
|
171 if not self.params.has_key(namespace) or not self.params[namespace].has_key(name): |
|
172 return #TODO: throw an error |
|
173 self.params[namespace][name][0]=value; |
|
174 |
|
175 def createParam (self, name, value, type, namespace): |
|
176 ### TODO: add desciption in params |
|
177 if not self.params.has_key(namespace): |
|
178 self.params[namespace]={} |
|
179 self.params[namespace][name]=[value,type]; |
|
180 |
|
181 def registerFeature(self, feature, callback=None): |
|
182 self.features[feature]=callback |
|
183 |