# This software and supporting documentation are distributed by
# Institut Federatif de Recherche 49
# CEA/NeuroSpin, Batiment 145,
# 91191 Gif-sur-Yvette cedex
# France
#
# This software is governed by the CeCILL license version 2 under
# French law and abiding by the rules of distribution of free software.
# You can use, modify and/or redistribute the software under the
# terms of the CeCILL license version 2 as circulated by CEA, CNRS
# and INRIA at the following URL "http://www.cecill.info".
#
# As a counterpart to the access to the source code and rights to copy,
# modify and redistribute granted by the license, users are provided only
# with a limited warranty and the software's author, the holder of the
# economic rights, and the successive licensors have only limited
# liability.
#
# In this respect, the user's attention is drawn to the risks associated
# with loading, using, modifying and/or developing or reproducing the
# software by the user in light of its specific status of free software,
# that may mean that it is complicated to manipulate, and that also
# therefore means that it is reserved for developers and experienced
# professionals having in-depth computer knowledge. Users are therefore
# encouraged to load and test the software's suitability as regards their
# requirements in conditions enabling the security of their systems and/or
# data to be ensured and, more generally, to use and operate it in the
# same conditions as regards security.
#
# The fact that you are presently reading this means that you have had
# knowledge of the CeCILL license version 2 and that you accept its terms.
from __future__ import absolute_import
import stat
import os
import cStringIO
import types
from UserDict import UserDict
#-------------------------------------------------------------------------
[docs]class VirtualDirectory(object):
'''A VirtualDirectory is a place where file- or directory-like data are stored
(local file system, ftp server, data base, etc.). A VirtualDirectory have a
name. That name is used whith a VirtualDirectoriesManager to build URL-like identifiers.'''
#-------------------------------------------------------------------------
[docs] class Item(UserDict):
'''A VirtualDirectory.Item is either a binary block of data or directory
like structure containing VirtualDirectory.Items.'''
def __init__(self, virtualDirectory=None):
self.virtualDirectory = virtualDirectory
[docs] def size(self):
'''Return the size of the binary data (in bytes) or None if the size is
unknown. The size of a VirtualDirectory.Item with children may be None
or the sum of the size of all children (and sub-children) that do not
have child.'''
return None
[docs] def reader(self):
'''Return a opened file compatible object that can be used to read binary
data. If the self.hasChildren() returns True, this method throws an
exception.'''
return cStringIO.StringIO('')
[docs] def hasChildren(self):
'''Returns True if the object has one or more children.'''
return False
[docs] def children(self):
'''Returns a generator (or a sequence) of VirtualDirectory.Item objects.'''
return ()
[docs] def fullName(self):
'''Return an identifier wich is unique in the VirtualDirectory where
the data comes from. This identifier can be stored and used later with
the VirtualDirectory's get() method in order to get a
VirtualDirectory.Item for the same data. May return None if the
identifier cannot be build. A typical value for this identifier is the
full path of a file relative to the virtual directory.'''
return None
[docs] def name(self):
'''Return the short name of the data. If not empty, this value can be
used to create a file or directory name for the data. Therefore, it does
not contain directory separator nor characters forbidden for file names.
A typical value for name() is the file name without its parent path.'''
return ''
[docs] def globalName(self):
'''Return an identifier wich is unique in the VirtualDirectoryManager where the
VirtualDirectory containing the data is registered. This identifier can be stored
and used later with the virtual directory manager's get() method in order to get a
VirtualDirectory.Item for the same data. May return an empty string if the identifier
cannot be build.'''
if self.virtualDirectory is not None and self.virtualDirectory.manager is not None:
virtualDirectory = self.virtualDirectory.name()
if virtualDirectory:
me = self.fullName()
if me is not None:
return self.virtualDirectory.manager.join(virtualDirectory, me)
return None
[docs] def parent(self):
'''Return the virtualDirectory.Item corresponding to this item's parent
directory. May return None if either the parent cannot be easily found
(e.g. in a non hierarchical storage implementation).'''
if self.virtualDirectory is not None:
return self.virtualDirectory.get(self.parentFullName())
return None
[docs] def parentFullName(self):
'''Equivalent to parent().fullName() but may be faster. May return None.'''
return None
def __str__(self):
result = self.globalName()
if result is None:
result = self.fullName()
if result is None:
result = self.name()
return result
def __init__(self, manager=None):
self.manager = manager
[docs] def get(identifier):
'''Return a VirtualDirectory.Item corresponding to a string identifier.'''
return None
[docs] def set(identifier, binHandle,
bufferSize,
startCallBack,
progressCallback,
endCallback):
'''Copy the content of a VirtualDirectory.Item coming from any VirtualDirectory into this
VirtualDirectory with the given identifer.'''
raise RuntimeError('virtual directory is read only')
[docs] def name(self):
'''Return the virtual directory name. May return an empty string if the virtual directory has
no name. This name is used when several virtual directories are registered in a
VirtualDirectoryManager.'''
return ''
def __str__(self):
return self.name()
#-------------------------------------------------------------------------
class VirtualDirectoriesManager(object):
def __init__(self):
self.__virtualDirectories = {}
def split(self, identifier):
index = identifier.find(':')
if index >= 0:
return (identifier[:index], identifier[index + 1:])
else:
return (identifier, '')
def join(self, virtualDirectoryId, binId):
return virtualDirectoryId + ':' + binId
def getVirtualDirectory(self, virtualDirectoryId):
return self.__virtualDirectories.get(virtualDirectoryId)
def registerVirtualDirectory(self, virtualDirectory):
key = virtualDirectory.name()
if key in self.__virtualDirectories:
raise RuntimeError(
'virtual directory "%s" already registered' % (key, ))
if virtualDirectory.manager is not None:
raise RuntimeError(
'virtual directory "%s" already registered in another VirtualDirectoriesManager' % (key, ))
virtualDirectory.manager = self
self.__virtualDirectories[key] = virtualDirectory
def get(self, identifier):
virtualDirectoryId, binId = self.split(identifier)
virtualDirectory = self.getVirtualDirectory(virtualDirectoryId)
if virtualDirectory is not None:
return virtualDirectory.get(binId)
return None
def set(self, identifier, binHandle,
bufferSize=32768,
startCallback=None,
progressCallback=None,
endCallback=None):
virtualDirectoryId, binId = self.split(identifier)
virtualDirectory = self.getVirtualDirectory(virtualDirectoryId)
if virtualDirectory is not None:
virtualDirectory.set(binId, binHandle,
bufferSize=bufferSize,
startCallback=startCallback,
progressCallback=progressCallback,
endCallback=endCallback)
else:
raise RuntimeError(
'No virtual directory named "%s"' % (virtualDirectory, ))