configurationengine/source/cone/storage/filestorage.py
changeset 3 e7e0ae78773e
parent 0 2e8eeb919028
child 5 d2c80f5cab53
equal deleted inserted replaced
2:87cfa131b535 3:e7e0ae78773e
    24     try:    
    24     try:    
    25         from elementtree import ElementTree
    25         from elementtree import ElementTree
    26     except ImportError:
    26     except ImportError:
    27         try:
    27         try:
    28             from xml.etree import cElementTree as ElementTree
    28             from xml.etree import cElementTree as ElementTree
    29         except ImpotError:
    29         except ImportError:
    30             from xml.etree import ElementTree
    30             from xml.etree import ElementTree
    31             
    31             
    32 from cone.public import exceptions  
    32 from cone.public import exceptions  
    33 from cone.public import api, utils
    33 from cone.public import api, utils, parsecontext
    34 #from cone.storage.configurationpersistence import ConfigurationReader, ConfigurationWriter
    34 #from cone.storage.configurationpersistence import ConfigurationReader, ConfigurationWriter
    35 from cone.storage import metadata, common
    35 from cone.storage import metadata, common, zipstorage
    36 from cone.confml import persistentconfml
    36 from cone.confml import persistentconfml
    37 debug = 0
    37 debug = 0
    38 
    38 
    39 class FileStorage(common.StorageBase):
    39 class FileStorage(common.StorageBase):
    40     """
    40     """
    41     A file system based implementation for Storage.
    41     A file system based implementation for Storage.
    42     @param path : path to the storage folder
    42     @param path : path to the storage folder
    43     @param mode: the mode for the folder. Default is a=append that expects the folder to exist.
    43     @param mode: the mode for the folder. Default is a=append that expects the folder to exist.
    44     """
    44     """
    45     
    45     
    46     def __init__(self,path,mode="r", **kwargs):
    46     def __init__(self, path, mode="r", **kwargs):
    47         super(FileStorage, self).__init__(path)
    47         super(FileStorage, self).__init__(path, mode)
    48         self.logger = logging.getLogger('cone')
    48         logging.getLogger('cone').debug("FileStorage path %s" % self.get_path())
    49         self.logger.debug("FileStorage path %s" % self.get_path())
       
    50         self.persistentmodule = persistentconfml
    49         self.persistentmodule = persistentconfml
    51         self.mode = mode
       
    52         if mode.find("a")!=-1 or mode.find("r")!=-1:
    50         if mode.find("a")!=-1 or mode.find("r")!=-1:
    53             # check that the given folder exists and is a folder    
    51             # check that the given folder exists and is a folder    
    54             if not os.path.isdir(self.get_path()):
    52             if not os.path.isdir(self.get_path()):
    55                 raise exceptions.StorageException("The given data folder for storage does not exist! %s" % self.get_path())
    53                 raise exceptions.StorageException("The given data folder for storage does not exist! %s" % self.get_path())
    56         elif mode.find("w")!=-1:
    54         elif mode.find("w")!=-1:
   149         entry = entry.replace("\\","/")
   147         entry = entry.replace("\\","/")
   150         entry = utils.resourceref.remove_begin_slash(entry)
   148         entry = utils.resourceref.remove_begin_slash(entry)
   151         return entry
   149         return entry
   152 
   150 
   153 
   151 
   154     def list_resources(self,path,recurse=False,empty_folders=False):
   152     def list_resources(self, path, **kwargs):
   155         """
   153         """
   156         Get an array of files in a folder
   154         Get an array of files in a folder
   157         """
   155         """
   158         
   156         
   159         retarray = []
   157         retarray = []
   160         path = utils.resourceref.remove_begin_slash(path)
   158         path = utils.resourceref.remove_begin_slash(path)
   161         fullpath = utils.resourceref.join_refs([self.get_path(),self.get_current_path(),path])
   159         fullpath = utils.resourceref.join_refs([self.get_path(),self.get_current_path(),path])
   162         joined = os.path.join(self.get_path(), self.get_current_path())
   160         joined = os.path.join(self.get_path(), self.get_current_path())
   163         current_root = os.path.normpath(os.path.abspath(joined))
   161         current_root = os.path.normpath(os.path.abspath(joined))
   164         # return always unix type file paths
   162         # return always unix type file paths
   165         if recurse:    
   163         if kwargs.get('recurse', False):    
   166             # Walk through all files in the layer
   164             # Walk through all files in the layer
   167             for root, dirs, files in os.walk(fullpath):
   165             for root, dirs, files in os.walk(fullpath):
       
   166                 # ensure that the directories and files are returned
       
   167                 # with alphabetical sorting in all platforms (e.g linux)
       
   168                 dirs.sort()
       
   169                 files.sort()
   168                 for name in files:
   170                 for name in files:
   169                     entry = os.path.join(root, name)
   171                     entry = os.path.join(root, name)
   170                     entry = os.path.normpath(os.path.abspath(entry))
   172                     entry = os.path.normpath(os.path.abspath(entry))
   171                     if os.path.isfile(entry):
   173                     if os.path.isfile(entry):
   172                         retarray.append(self.fix_entry(entry,current_root))
   174                         retarray.append(self.fix_entry(entry,current_root))
   173                         
   175                         
   174                 if empty_folders: 
   176                 if kwargs.get('empty_folders', False): 
   175                     for name in dirs:
   177                     for name in dirs:
   176                         entry = os.path.join(root, name)
   178                         entry = os.path.join(root, name)
   177                         entry = os.path.normpath(os.path.abspath(entry))
   179                         entry = os.path.normpath(os.path.abspath(entry))
   178                         if  os.path.isdir(entry)  and  len(os.listdir(entry)) ==0:
   180                         if  os.path.isdir(entry)  and  len(os.listdir(entry)) ==0:
   179                             retarray.append(self.fix_entry(entry,current_root))
   181                             retarray.append(self.fix_entry(entry,current_root))
   180                         
   182                         
   181         else:
   183         else:
   182             filelist = os.listdir(fullpath)
   184             filelist = sorted(os.listdir(fullpath))
   183             for name in filelist:
   185             for name in filelist:
   184                 entry = os.path.join(path, name)
   186                 entry = os.path.join(path, name)
   185                 entry = os.path.normpath(entry)
   187                 entry = os.path.normpath(entry)
   186                 entry = entry.replace("\\","/")               
   188                 entry = entry.replace("\\","/")               
   187                 entry = utils.resourceref.remove_begin_slash(entry)
   189                 entry = utils.resourceref.remove_begin_slash(entry)
   189                 fileentry = os.path.join(current_root,entry)
   191                 fileentry = os.path.join(current_root,entry)
   190                 if os.path.isfile(fileentry):
   192                 if os.path.isfile(fileentry):
   191                     if debug: print "list_resources adding %s" % entry
   193                     if debug: print "list_resources adding %s" % entry
   192                     retarray.append(entry)
   194                     retarray.append(entry)
   193                     
   195                     
   194                 if os.path.isdir(fileentry) and empty_folders:
   196                 if os.path.isdir(fileentry) and kwargs.get('empty_folders', False):
   195                     if debug: print "list_resources adding %s" % entry
   197                     if debug: print "list_resources adding %s" % entry
   196                     retarray.append(entry)
   198                     retarray.append(entry)
   197         return retarray
   199         return retarray
   198 
   200 
   199     def import_resources(self,paths,storage):
   201     def import_resources(self,paths,storage):
   215         for path in paths:
   217         for path in paths:
   216             if not self.is_resource(path) and empty_folders==False:
   218             if not self.is_resource(path) and empty_folders==False:
   217                 logging.getLogger('cone').warning("The given path is not a Resource in this storage %s! Ignoring from export!" % path)
   219                 logging.getLogger('cone').warning("The given path is not a Resource in this storage %s! Ignoring from export!" % path)
   218                 continue
   220                 continue
   219             if self.is_resource(path):
   221             if self.is_resource(path):
   220                 wres = storage.open_resource(path,'wb')
   222                 # Optimization for direct file to ZIP export.
   221                 res  = self.open_resource(path,"rb")
   223                 # There's no need to juggle the data through ConE code
   222                 wres.write(res.read())
   224                 # when we can just write the file directly into the ZIP
   223                 wres.close()
   225                 if isinstance(storage, zipstorage.ZipStorage):
   224                 res.close()
   226                     source_abspath = os.path.join(self.rootpath, path)
       
   227                     logging.getLogger("cone").debug("Exporting directly from file to ZIP: %r -> %r" % (source_abspath, path))
       
   228                     storage.zipfile.write(source_abspath, path)
       
   229                 else:
       
   230                     wres = storage.open_resource(path,'wb')
       
   231                     res  = self.open_resource(path,"rb")
       
   232                     wres.write(res.read())
       
   233                     wres.close()
       
   234                     res.close()
   225                 
   235                 
   226                 
   236                 
   227             if  self.is_folder(path) and  empty_folders:
   237             if  self.is_folder(path) and  empty_folders:
   228                 storage.create_folder(path)
   238                 storage.create_folder(path)
   229     
   239     
   233     def create_folder(self,path):
   243     def create_folder(self,path):
   234         """
   244         """
   235         Create a folder entry to a path
   245         Create a folder entry to a path
   236         @param path : path to the folder
   246         @param path : path to the folder
   237         """
   247         """
   238         
   248         path = utils.resourceref.remove_begin_slash(path)
   239         path = utils.resourceref.join_refs([self.get_path(), self.get_current_path(), path])
   249         path = utils.resourceref.join_refs([self.get_path(), self.get_current_path(), path])
   240         if not os.path.exists(path):
   250         if not os.path.exists(path):
   241             os.makedirs(path)
   251             os.makedirs(path)
   242 
   252 
   243     def delete_folder(self,path):
   253     def delete_folder(self,path):
   287         if not utils.resourceref.get_ext(path) == "confml":
   297         if not utils.resourceref.get_ext(path) == "confml":
   288             raise exceptions.StorageException("Cannot load reference type %s" % utils.resourceref.get_ext(path))
   298             raise exceptions.StorageException("Cannot load reference type %s" % utils.resourceref.get_ext(path))
   289         if self.is_resource(path):
   299         if self.is_resource(path):
   290             res = self.open_resource(path,"r")
   300             res = self.open_resource(path,"r")
   291             # read the resource with persistentmodule
   301             # read the resource with persistentmodule
       
   302             parsecontext.get_confml_context().current_file = path
   292             try:
   303             try:
   293                 obj = self.persistentmodule.loads(res.read())
   304                 obj = self.persistentmodule.loads(res.read())
   294                 #obj.set_path(path)
   305                 #obj.set_path(path)
   295                 res.close()
   306                 res.close()
   296                 return obj
   307                 return obj
   297             except exceptions.ParseError,e:
   308             except exceptions.ParseError,e:
   298                 logging.getLogger('cone').error("Resource %s parsing failed with exception: %s" % (path,e))
   309                 parsecontext.get_confml_context().handle_exception(e)
       
   310                 #logging.getLogger('cone').error("Resource %s parsing failed with exception: %s" % (path,e))
   299                 # returning an empty config in case of xml parsing failure.
   311                 # returning an empty config in case of xml parsing failure.
   300                 return api.Configuration(path)
   312                 return api.Configuration(path)
   301         else:
   313         else:
   302             raise exceptions.NotResource("No such %s resource!" % path)
   314             raise exceptions.NotResource("No such %s resource!" % path)
   303 
   315 
   343         orig_pos = self.handle.tell()
   355         orig_pos = self.handle.tell()
   344         self.handle.seek(0, os.SEEK_SET)
   356         self.handle.seek(0, os.SEEK_SET)
   345         data = self.handle.read()
   357         data = self.handle.read()
   346         self.handle.seek(orig_pos, os.SEEK_SET)
   358         self.handle.seek(orig_pos, os.SEEK_SET)
   347         if self.content_info == None:
   359         if self.content_info == None:
   348             self.content_info = utils.make_content_info(self, data)
   360             self.content_info = api.make_content_info(self, data)
   349         
   361         
   350         return self.content_info
   362         return self.content_info