comparison src/memory/memory.py @ 993:301b342c697a

core: use of the new core.log module: /!\ this is a massive refactoring and was largely automated, it probably did bring some bugs /!\
author Goffi <goffi@goffi.org>
date Sat, 19 Apr 2014 19:19:19 +0200
parents fe181994246a
children 52ec79aa5bbe
comparison
equal deleted inserted replaced
992:f51a1895275c 993:301b342c697a
22 import os.path 22 import os.path
23 import csv 23 import csv
24 from xdg import BaseDirectory 24 from xdg import BaseDirectory
25 from ConfigParser import SafeConfigParser, NoOptionError, NoSectionError 25 from ConfigParser import SafeConfigParser, NoOptionError, NoSectionError
26 from uuid import uuid4 26 from uuid import uuid4
27 from logging import debug, info, warning, error 27 from sat.core.log import getLogger
28 log = getLogger(__name__)
28 from twisted.internet import defer, reactor 29 from twisted.internet import defer, reactor
29 from twisted.words.protocols.jabber import jid 30 from twisted.words.protocols.jabber import jid
30 from sat.core import exceptions 31 from sat.core import exceptions
31 from sat.core.constants import Const as C 32 from sat.core.constants import Const as C
32 from sat.memory.sqlite import SqliteStorage 33 from sat.memory.sqlite import SqliteStorage
59 self._sessions[session_id] = (timer, session_data) if profile is None else (timer, session_data, profile) 60 self._sessions[session_id] = (timer, session_data) if profile is None else (timer, session_data, profile)
60 return session_id, session_data 61 return session_id, session_data
61 62
62 def _purgeSession(self, session_id): 63 def _purgeSession(self, session_id):
63 del self._sessions[session_id] 64 del self._sessions[session_id]
64 debug("Session [%s] purged" % session_id) 65 log.debug("Session [%s] purged" % session_id)
65 66
66 def __len__(self): 67 def __len__(self):
67 return len(self._sessions) 68 return len(self._sessions)
68 69
69 def __contains__(self, session_id): 70 def __contains__(self, session_id):
95 try: 96 try:
96 timer = self._sessions[session_id][0] 97 timer = self._sessions[session_id][0]
97 timer.cancel() 98 timer.cancel()
98 self._purgeSession(session_id) 99 self._purgeSession(session_id)
99 except KeyError: 100 except KeyError:
100 debug ("Session [%s] doesn't exists, timeout expired ?" % session_id) 101 log.debug ("Session [%s] doesn't exists, timeout expired ?" % session_id)
101 102
102 def keys(self): 103 def keys(self):
103 return self._sessions.keys() 104 return self._sessions.keys()
104 105
105 def iterkeys(self): 106 def iterkeys(self):
108 109
109 class Memory(object): 110 class Memory(object):
110 """This class manage all persistent informations""" 111 """This class manage all persistent informations"""
111 112
112 def __init__(self, host): 113 def __init__(self, host):
113 info(_("Memory manager init")) 114 log.info(_("Memory manager init"))
114 self.initialized = defer.Deferred() 115 self.initialized = defer.Deferred()
115 self.host = host 116 self.host = host
116 self._entities_cache = {} # XXX: keep presence/last resource/other data in cache 117 self._entities_cache = {} # XXX: keep presence/last resource/other data in cache
117 # /!\ an entity is not necessarily in roster 118 # /!\ an entity is not necessarily in roster
118 self.subscriptions = {} 119 self.subscriptions = {}
121 self.__fixLocalDir() 122 self.__fixLocalDir()
122 database_file = os.path.expanduser(os.path.join(self.getConfig('', 'local_dir'), C.SAVEFILE_DATABASE)) 123 database_file = os.path.expanduser(os.path.join(self.getConfig('', 'local_dir'), C.SAVEFILE_DATABASE))
123 self.storage = SqliteStorage(database_file, host.__version__) 124 self.storage = SqliteStorage(database_file, host.__version__)
124 PersistentDict.storage = self.storage 125 PersistentDict.storage = self.storage
125 self.params = Params(host, self.storage) 126 self.params = Params(host, self.storage)
126 info(_("Loading default params template")) 127 log.info(_("Loading default params template"))
127 self.params.load_default_params() 128 self.params.load_default_params()
128 d = self.storage.initialized.addCallback(lambda ignore: self.load()) 129 d = self.storage.initialized.addCallback(lambda ignore: self.load())
129 self.memory_data = PersistentDict("memory") 130 self.memory_data = PersistentDict("memory")
130 d.addCallback(lambda ignore: self.memory_data.load()) 131 d.addCallback(lambda ignore: self.memory_data.load())
131 d.chainDeferred(self.initialized) 132 d.chainDeferred(self.initialized)
134 """look for main .ini configuration file, and parse it""" 135 """look for main .ini configuration file, and parse it"""
135 config = SafeConfigParser(defaults=C.DEFAULT_CONFIG) 136 config = SafeConfigParser(defaults=C.DEFAULT_CONFIG)
136 try: 137 try:
137 config.read(C.CONFIG_FILES) 138 config.read(C.CONFIG_FILES)
138 except: 139 except:
139 error(_("Can't read main config !")) 140 log.error(_("Can't read main config !"))
140 return config 141 return config
141 142
142 # XXX: tmp update code, will be removed in the future 143 # XXX: tmp update code, will be removed in the future
143 # When you remove this, please also remove sat.core.constants.Const.DEFAULT_LOCAL_DIR 144 # When you remove this, please also remove sat.core.constants.Const.DEFAULT_LOCAL_DIR
144 # and add the default value for 'local_dir' in sat.core.constants.Const.DEFAULT_CONFIG 145 # and add the default value for 'local_dir' in sat.core.constants.Const.DEFAULT_CONFIG
146 """Retro-compatibility with the previous local_dir default value.""" 147 """Retro-compatibility with the previous local_dir default value."""
147 if self.getConfig('', 'local_dir'): 148 if self.getConfig('', 'local_dir'):
148 return # nothing to do 149 return # nothing to do
149 old_default = '~/.sat' 150 old_default = '~/.sat'
150 if os.path.isfile(os.path.expanduser(old_default) + '/' + C.SAVEFILE_DATABASE): 151 if os.path.isfile(os.path.expanduser(old_default) + '/' + C.SAVEFILE_DATABASE):
151 warning(_("A database has been found in the default local_dir for previous versions (< 0.5)")) 152 log.warning(_("A database has been found in the default local_dir for previous versions (< 0.5)"))
152 config = SafeConfigParser() 153 config = SafeConfigParser()
153 target_file = None 154 target_file = None
154 for file_ in C.CONFIG_FILES[::-1]: 155 for file_ in C.CONFIG_FILES[::-1]:
155 # we will eventually update the existing file with the highest priority, if it's a user personal file... 156 # we will eventually update the existing file with the highest priority, if it's a user personal file...
156 if os.path.isfile(file_): 157 if os.path.isfile(file_):
162 # ... otherwise we create a new config file for that user 163 # ... otherwise we create a new config file for that user
163 target_file = BaseDirectory.save_config_path('sat') + '/sat.conf' 164 target_file = BaseDirectory.save_config_path('sat') + '/sat.conf'
164 config.set('', 'local_dir', old_default) 165 config.set('', 'local_dir', old_default)
165 with open(target_file, 'wb') as configfile: 166 with open(target_file, 'wb') as configfile:
166 config.write(configfile) # for the next time that user launches sat 167 config.write(configfile) # for the next time that user launches sat
167 warning(_("Auto-update: local_dir set to %(path)s in the file %(config_file)s") % {'path': old_default, 'config_file': file_}) 168 log.warning(_("Auto-update: local_dir set to %(path)s in the file %(config_file)s") % {'path': old_default, 'config_file': file_})
168 default = old_default 169 default = old_default
169 else: # use the new default local_dir 170 else: # use the new default local_dir
170 default = C.DEFAULT_LOCAL_DIR 171 default = C.DEFAULT_LOCAL_DIR
171 self.config.set('', 'local_dir', default) # for the currently running instance 172 self.config.set('', 'local_dir', default) # for the currently running instance
172 173
198 return False 199 return False
199 filename = os.path.expanduser(filename) 200 filename = os.path.expanduser(filename)
200 if os.path.exists(filename): 201 if os.path.exists(filename):
201 try: 202 try:
202 self.params.load_xml(filename) 203 self.params.load_xml(filename)
203 debug(_("Parameters loaded from file: %s") % filename) 204 log.debug(_("Parameters loaded from file: %s") % filename)
204 return True 205 return True
205 except Exception as e: 206 except Exception as e:
206 error(_("Can't load parameters from file: %s") % e) 207 log.error(_("Can't load parameters from file: %s") % e)
207 return False 208 return False
208 209
209 def load(self): 210 def load(self):
210 """Load parameters and all memory things from db""" 211 """Load parameters and all memory things from db"""
211 #parameters data 212 #parameters data
217 return self.params.loadIndParams(profile) 218 return self.params.loadIndParams(profile)
218 219
219 def startProfileSession(self, profile): 220 def startProfileSession(self, profile):
220 """"Iniatialise session for a profile 221 """"Iniatialise session for a profile
221 @param profile: %(doc_profile)s""" 222 @param profile: %(doc_profile)s"""
222 info(_("[%s] Profile session started" % profile)) 223 log.info(_("[%s] Profile session started" % profile))
223 self._entities_cache[profile] = {} 224 self._entities_cache[profile] = {}
224 225
225 def purgeProfileSession(self, profile): 226 def purgeProfileSession(self, profile):
226 """Delete cache of data of profile 227 """Delete cache of data of profile
227 @param profile: %(doc_profile)s""" 228 @param profile: %(doc_profile)s"""
228 info(_("[%s] Profile session purge" % profile)) 229 log.info(_("[%s] Profile session purge" % profile))
229 self.params.purgeProfile(profile) 230 self.params.purgeProfile(profile)
230 try: 231 try:
231 del self._entities_cache[profile] 232 del self._entities_cache[profile]
232 except KeyError: 233 except KeyError:
233 error(_("Trying to purge roster status cache for a profile not in memory: [%s]") % profile) 234 log.error(_("Trying to purge roster status cache for a profile not in memory: [%s]") % profile)
234 235
235 def save_xml(self, filename=None): 236 def save_xml(self, filename=None):
236 """Save parameters template to xml file""" 237 """Save parameters template to xml file"""
237 if filename is None: 238 if filename is None:
238 return False 239 return False
239 #TODO: need to encrypt files (at least passwords !) and set permissions 240 #TODO: need to encrypt files (at least passwords !) and set permissions
240 filename = os.path.expanduser(filename) 241 filename = os.path.expanduser(filename)
241 try: 242 try:
242 self.params.save_xml(filename) 243 self.params.save_xml(filename)
243 debug(_("Parameters saved to file: %s") % filename) 244 log.debug(_("Parameters saved to file: %s") % filename)
244 return True 245 return True
245 except Exception as e: 246 except Exception as e:
246 error(_("Can't save parameters to file: %s") % e) 247 log.error(_("Can't save parameters to file: %s") % e)
247 return False 248 return False
248 249
249 def getProfilesList(self): 250 def getProfilesList(self):
250 return self.storage.getProfilesList() 251 return self.storage.getProfilesList()
251 252
310 entities_presence = {} 311 entities_presence = {}
311 for entity in self._entities_cache[profile]: 312 for entity in self._entities_cache[profile]:
312 if "presence" in self._entities_cache[profile][entity]: 313 if "presence" in self._entities_cache[profile][entity]:
313 entities_presence[entity] = self._entities_cache[profile][entity]["presence"] 314 entities_presence[entity] = self._entities_cache[profile][entity]["presence"]
314 315
315 debug("Memory getPresenceStatus (%s)", entities_presence) 316 log.debug("Memory getPresenceStatus (%s)", entities_presence)
316 return entities_presence 317 return entities_presence
317 318
318 def setPresenceStatus(self, entity_jid, show, priority, statuses, profile_key): 319 def setPresenceStatus(self, entity_jid, show, priority, statuses, profile_key):
319 """Change the presence status of an entity 320 """Change the presence status of an entity
320 @param entity_jid: jid.JID of the entity 321 @param entity_jid: jid.JID of the entity
391 for entity_jid in entities_data: 392 for entity_jid in entities_data:
392 entity_data = entities_data[entity_jid] 393 entity_data = entities_data[entity_jid]
393 try: 394 try:
394 del entity_data[key] 395 del entity_data[key]
395 except KeyError: 396 except KeyError:
396 debug("Key [%s] doesn't exist for [%s] in entities_cache" % (key, entity_jid.full())) 397 log.debug("Key [%s] doesn't exist for [%s] in entities_cache" % (key, entity_jid.full()))
397 398
398 def getEntityData(self, entity_jid, keys_list, profile_key): 399 def getEntityData(self, entity_jid, keys_list, profile_key):
399 """Get a list of cached values for entity 400 """Get a list of cached values for entity
400 401
401 @param entity_jid: JID of the entity 402 @param entity_jid: JID of the entity
452 453
453 for entity in to_delete: 454 for entity in to_delete:
454 try: 455 try:
455 del self._entities_cache[profile][entity] 456 del self._entities_cache[profile][entity]
456 except KeyError: 457 except KeyError:
457 debug("Can't delete entity [%s]: not in cache" % entity.full()) 458 log.debug("Can't delete entity [%s]: not in cache" % entity.full())
458 459
459 def addWaitingSub(self, type_, entity_jid, profile_key): 460 def addWaitingSub(self, type_, entity_jid, profile_key):
460 """Called when a subcription request is received""" 461 """Called when a subcription request is received"""
461 profile = self.getProfileName(profile_key) 462 profile = self.getProfileName(profile_key)
462 assert profile 463 assert profile
473 474
474 def getWaitingSub(self, profile_key): 475 def getWaitingSub(self, profile_key):
475 """Called to get a list of currently waiting subscription requests""" 476 """Called to get a list of currently waiting subscription requests"""
476 profile = self.getProfileName(profile_key) 477 profile = self.getProfileName(profile_key)
477 if not profile: 478 if not profile:
478 error(_('Asking waiting subscriptions for a non-existant profile')) 479 log.error(_('Asking waiting subscriptions for a non-existant profile'))
479 return {} 480 return {}
480 if profile not in self.subscriptions: 481 if profile not in self.subscriptions:
481 return {} 482 return {}
482 483
483 return self.subscriptions[profile] 484 return self.subscriptions[profile]