nutools/lib/pyulib/src/ulib/tasks/multiple.py

136 lines
4.2 KiB
Python

# -*- coding: utf-8 -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
import ulib.base.i_need_py23
__all__ = ('MultipleStore',)
from ulib.base.base import isseq
from ulib.base.uio import _s, _u
from consts import *
from store import AbstractStore
class MultipleStore(AbstractStore):
_stores = None
_cstores = None
_last_lsid = 0
def __init__(self, stores=None):
AbstractStore.__init__(self)
if stores is None: stores = ()
elif not isseq(stores): stores = (stores,)
self._stores = []
for store in stores:
self.add_store(store)
def add_store(self, store):
if store.get_sid() is None:
store.set_lsid(self._last_lsid)
self._last_lsid = self._last_lsid + 1
self._stores.append(store)
self._cstores = None # pour qu'il soit reconstruit
def get_name(self):
u"""Retourner le nom de ce store.
Il s'agit des noms de tous les stores gérés par ce store, séparés par
des caractères '+'.
@rtype: unicode
"""
return u"+".join([store.name for store in self.get_stores()])
name = property(get_name)
_wstore = None
def get_wstore(self):
u"""Retourner le store destination, c'est à dire celui dans lequel on
ajoute les tâches par défaut. Par défaut, il s'agit du premier store
de la liste.
@raise IndexError: s'il n'y a aucun stores
"""
if self._wstore is not None:
return self._wstore
else:
if self._stores: return self._stores[0]
raise IndexError("Unable to find destination store")
def set_wstore(self, name=None):
u"""Choisir le store destination.
@param name: Nom du store à sélectionner, ou None pour prendre le
premier de la liste.
@return: self
"""
if name is None:
self._wstore = None
else:
for store in self.get_stores():
if store.get_name() == name:
self._wstore = store
break
else:
raise ValueError("Invalid store: %s" % name)
def get_stores(self, force=False):
u"""Retourner la liste des stores gérés par ce store. Si c'est un store
simple, la liste de contient qu'un élément.
@param force: forcer la reconstruction de la liste. par défaut,
utiliser une valeur mise en cache.
@rtype: tuple
"""
if force or self._cstores is None:
stores = []
for store in self._stores:
stores.extend(store.get_stores())
self._cstores = tuple(stores)
return self._cstores
def get_store_by_sid(self, sid=None):
u"""Obtenir le store dont on donne le sid, ou None si le sid n'existe
pas. Si sid==None, retourner le store par défaut.
@rtype: AbstractStore
"""
if sid is None: return self.get_store()
sid = _u(sid)
for store in self.get_stores():
if _u(store.sid) == sid: return store
return None
def get_tasks(self):
tasks = []
for store in self.get_stores():
tasks.extend(store.tasks)
return tasks
tasks = property(get_tasks)
def remove(self, task):
for store in self.get_stores():
if store.remove(task): return True
return False
def load(self, infdn=None, force=False, force_reload=False, **ignored):
if infdn is not None:
raise ValueError("infdn is not supported for this store")
for store in self.get_stores():
if force_reload or store.should_reload():
store.load(force=force)
def should_reload(self):
for store in self.get_stores():
if store.should_reload(): return True
return False
def revert(self):
for store in self.get_stores(): store.revert()
def save(self, outfdn=None, force=False):
if outfdn is not None:
raise ValueError("outfdn is not supported for this store")
saved = False
for store in self.get_stores():
if store.save(force=force):
saved = True
return saved