comparison tools/memory.py @ 47:9aa2d9dd4045

memory methods improvement - new method to save private data (mainly useful for plugins) - contacts/presence management refactored - new independant methods to manage subscription
author Goffi <goffi@goffi.org>
date Wed, 06 Jan 2010 23:49:55 +1100
parents d24629c631fc
children a5b5fb5fc9fd
comparison
equal deleted inserted replaced
46:18f6c9e60507 47:9aa2d9dd4045
26 import pickle 26 import pickle
27 from xml.dom import minidom 27 from xml.dom import minidom
28 from logging import debug, info, error 28 from logging import debug, info, error
29 import pdb 29 import pdb
30 from twisted.internet import defer 30 from twisted.internet import defer
31 from twisted.words.protocols.jabber import jid
31 32
32 SAVEFILE_PARAM="/param" 33 SAVEFILE_PARAM="/param"
33 SAVEFILE_HISTORY="/history" 34 SAVEFILE_HISTORY="/history"
35 SAVEFILE_PRIVATE="/private" #file used to store misc values (mainly for plugins)
34 36
35 class Param(): 37 class Param():
36 """This class manage parameter with xml""" 38 """This class manage parameter with xml"""
37 ### TODO: add desciption in params 39 ### TODO: add desciption in params
38 40
66 def __init__(self, host): 68 def __init__(self, host):
67 debug("Parameters init") 69 debug("Parameters init")
68 self.host = host 70 self.host = host
69 host.set_const('savefile_param', SAVEFILE_PARAM) 71 host.set_const('savefile_param', SAVEFILE_PARAM)
70 host.set_const('savefile_history', SAVEFILE_HISTORY) 72 host.set_const('savefile_history', SAVEFILE_HISTORY)
73 host.set_const('savefile_private', SAVEFILE_PRIVATE)
71 host.registerGeneralCB("registerNewAccount", host.registerNewAccountCB) 74 host.registerGeneralCB("registerNewAccount", host.registerNewAccountCB)
72 75
73 def __get_unique_node(self, parent, tag, name): 76 def __get_unique_node(self, parent, tag, name):
74 """return node with given tag, create a new one if the node doesn't exist 77 """return node with given tag, create a new one if the node doesn't exist
75 @param parent: parent of nodes to check (e.g. documentElement) 78 @param parent: parent of nodes to check (e.g. documentElement)
181 """This class manage all persistent informations""" 184 """This class manage all persistent informations"""
182 185
183 def __init__(self, host): 186 def __init__(self, host):
184 info ("Memory manager init") 187 info ("Memory manager init")
185 self.host = host 188 self.host = host
186 self.contact={} 189 self.contacts={}
187 self.presenceStatus={} 190 self.presenceStatus={}
191 self.subscriptions={}
188 self.params=Param(host) 192 self.params=Param(host)
189 self.history={} 193 self.history={} #used to store chat history (key: short jid)
194 self.private={} #used to store private value
190 self.disco={} #XXX: maybe best in a separate class 195 self.disco={} #XXX: maybe best in a separate class
191 self.features={} 196 self.features={}
192 self.load() 197 self.load()
193 198
194 def load(self): 199 def load(self):
195 """Load parameters and all memory things from file/db""" 200 """Load parameters and all memory things from file/db"""
196 param_file = os.path.expanduser(self.host.get_const('local_dir')+ 201 param_file = os.path.expanduser(self.host.get_const('local_dir')+
197 self.host.get_const('savefile_param')) 202 self.host.get_const('savefile_param'))
198 history_file = os.path.expanduser(self.host.get_const('local_dir')+ 203 history_file = os.path.expanduser(self.host.get_const('local_dir')+
199 self.host.get_const('savefile_history')) 204 self.host.get_const('savefile_history'))
205 private_file = os.path.expanduser(self.host.get_const('local_dir')+
206 self.host.get_const('savefile_private'))
200 207
201 #parameters 208 #parameters
202 if os.path.exists(param_file): 209 if os.path.exists(param_file):
203 try: 210 try:
204 self.params.load(param_file) 211 self.params.load(param_file)
217 self.history=pickle.load(history_pickle) 224 self.history=pickle.load(history_pickle)
218 debug("history loaded") 225 debug("history loaded")
219 except: 226 except:
220 error ("Can't load history !") 227 error ("Can't load history !")
221 228
229 #private
230 if os.path.exists(private_file):
231 try:
232 with open(private_file, 'r') as private_pickle:
233 self.private=pickle.load(private_pickle)
234 debug("private values loaded")
235 except:
236 error ("Can't load private values !")
222 237
223 def save(self): 238 def save(self):
224 """Save parameters and all memory things to file/db""" 239 """Save parameters and all memory things to file/db"""
225 #TODO: need to encrypt files (at least passwords !) and set permissions 240 #TODO: need to encrypt files (at least passwords !) and set permissions
226 param_file = os.path.expanduser(self.host.get_const('local_dir')+ 241 param_file = os.path.expanduser(self.host.get_const('local_dir')+
227 self.host.get_const('savefile_param')) 242 self.host.get_const('savefile_param'))
228 history_file = os.path.expanduser(self.host.get_const('local_dir')+ 243 history_file = os.path.expanduser(self.host.get_const('local_dir')+
229 self.host.get_const('savefile_history')) 244 self.host.get_const('savefile_history'))
245 private_file = os.path.expanduser(self.host.get_const('local_dir')+
246 self.host.get_const('savefile_private'))
230 247
231 self.params.save(param_file) 248 self.params.save(param_file)
232 debug("params saved") 249 debug("params saved")
233 with open(history_file, 'w') as history_pickle: 250 with open(history_file, 'w') as history_pickle:
234 pickle.dump(self.history, history_pickle) 251 pickle.dump(self.history, history_pickle)
235 debug("history saved") 252 debug("history saved")
253 with open(private_file, 'w') as private_pickle:
254 pickle.dump(self.private, private_pickle)
255 debug("private values saved")
236 256
237 def addToHistory(self, me_jid, from_jid, to_jid, type, message): 257 def addToHistory(self, me_jid, from_jid, to_jid, type, message):
238 me_short=me_jid.userhost() 258 me_short=me_jid.userhost()
239 from_short=from_jid.userhost() 259 from_short=from_jid.userhost()
240 to_short=to_jid.userhost() 260 to_short=to_jid.userhost()
266 for stamp in stamps[-size:]: 286 for stamp in stamps[-size:]:
267 ret[stamp]=self.history[from_jid][to_jid][stamp] 287 ret[stamp]=self.history[from_jid][to_jid][stamp]
268 288
269 return ret 289 return ret
270 290
271 def addContact(self, JID, attributes, groups): 291 def setPrivate(self, key, value):
272 debug("Memory addContact: %s",JID) 292 """Save a misc private value (mainly useful for plugins)"""
293 self.private[key] = value
294
295 def getPrivate(self, key):
296 """return a private value
297 @param key: name of wanted value
298 @return: value or None if value don't exist"""
299 if self.private.has_key(key):
300 return self.private[key]
301 return None
302
303
304 def addContact(self, contact_jid, attributes, groups):
305 debug("Memory addContact: %s",contact_jid.userhost())
273 assert(isinstance(attributes,dict)) 306 assert(isinstance(attributes,dict))
274 assert(isinstance(groups,set)) 307 assert(isinstance(groups,set))
275 self.contact[JID]=[attributes, groups] 308 self.contacts[contact_jid.userhost()]=[attributes, groups]
276 309
277 def addPresenceStatus(self, jid, type, show, status, priority): 310 def delContact(self, contact_jid):
278 self.presenceStatus[jid]=[type, show, status, priority] 311 debug("Memory delContact: %s",contact_jid.userhost())
279 312 if self.contacts.has_key(contact_jid.userhost()):
313 del self.contacts[contact_jid.userhost()]
314
315 def getContact(self, contact_jid):
316 if self.contacts.has_key(contact_jid.userhost()):
317 self.contacts[contact_jid.userhost()]
318 else:
319 return None
320
280 def getContacts(self): 321 def getContacts(self):
281 debug ("Memory getContact OK (%s)", self.contact) 322 debug ("Memory getContact OK (%s)", self.contacts)
282 ret=[] 323 ret=[]
283 for contact in self.contact: 324 for contact in self.contacts:
284 ret.append([contact] + [self.contact[contact][0]] + [self.contact[contact][1]]) #very ugly I know ! 325 attr, groups = self.contacts[contact]
326 ret.append([contact, attr, groups ])
285 return ret 327 return ret
328
329 def addPresenceStatus(self, contact_jid, show, priority, statuses):
330 if not self.presenceStatus.has_key(contact_jid.userhost()):
331 self.presenceStatus[contact_jid.userhost()] = {}
332 resource = jid.parse(contact_jid.full())[2] or ''
333 self.presenceStatus[contact_jid.userhost()][resource] = (show, priority, statuses)
334
335 def addWaitingSub(self, type, contact_jid):
336 """Called when a subcription request is received"""
337 self.subscriptions[contact_jid] = type
338
339 def delWaitingSub(self, contact_jid):
340 """Called when a subcription request is finished"""
341 if self.subscriptions.has_key(contact_jid):
342 del self.subscriptions[contact_jid]
343
344 def getWaitingSub(self):
345 """Called to get a list of currently waiting subscription requests"""
346 return self.subscriptions
286 347
287 def getPresenceStatus(self): 348 def getPresenceStatus(self):
288 status=[] 349 debug ("Memory getPresenceStatus (%s)", self.presenceStatus)
289 for contact, contactStatus in self.presenceStatus.items(): 350 return self.presenceStatus
290 status.append([contact]+contactStatus)
291 debug ("Memory getPresenceStatus (%s)", status)
292 return status
293 351
294 def getParamA(self, name, category, attr="value"): 352 def getParamA(self, name, category, attr="value"):
295 return self.params.getParamA(name, category, attr) 353 return self.params.getParamA(name, category, attr)
296 354
297 def getParams(self): 355 def getParams(self):