source: sasview/DataLoader/loader.py @ 1b162dfa

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 1b162dfa was 579ba85, checked in by Mathieu Doucet <doucetm@…>, 16 years ago

CanSAS format reader/writer completed/tested.

  • Property mode set to 100644
File size: 10.2 KB
RevLine 
[a916ccc]1# This program is public domain
2"""
[d22da51]3    @organization: Module loader contains class Loader which uses
4    some readers to return values contained in a file readed.
[77c1c29d]5    @ author : Paul Kienzler
6    @modifiied by gervaise alina
[a916ccc]7"""
8import imp,os,sys
9import logging
10import os.path
[d22da51]11logging.basicConfig(level=logging.ERROR,
12                    format='%(asctime)s %(levelname)s %(message)s',
[d3619421]13                    filename='test_log.txt',
[d22da51]14                    filemode='w')
15
[a916ccc]16def _findReaders(dir):
17    # List of plugin objects
18    plugins = []
19    # Go through files in plug-in directory
20    try:
21       
22        list = os.listdir(dir)
23        for item in list:
24           
25            toks = os.path.splitext(os.path.basename(item))
26            if toks[1]=='.py' and not toks[0]=='__init__':
27                name = toks[0]
28                path = [os.path.abspath(dir)]
29                file = None
30                try:
31                    (file, path, info) = imp.find_module(name, path)
32                    module = imp.load_module( name, file, item, info )
33                    if hasattr(module, "Reader"):
34                        try:
35                            plugins.append(module.Reader())
36                        except:
[94daf8a]37                            logging.error("Error accessing Reader in %s\n  %s" % (name, sys.exc_value))
[a916ccc]38                except :
[94daf8a]39                    logging.error("Error importing %s\n  %s" % (name, sys.exc_value))
[a916ccc]40                finally:
41                    if not file==None:
42                        file.close()
43    except:
44        # Should raise and catch at a higher level and display error on status bar
45        pass   
46    return plugins
[d22da51]47
48
[1b0b3ca]49class Loader(object):
[d22da51]50    """
51        Loader class extracts data from a given file.
52        This provides routines for opening files based on extension,
53        and readers built-in file extensions.
54        It uses functionalities for class Load
55        @note: For loader to operate properly each readers used should
56        contain a class name "Reader" that contains a field call ext.
57        Can be used as follow:
58        L=Loader()
59        self.assertEqual(l.__contains__('.tiff'),True)
60        #Recieves data
61        data=L.load(path)
62    """
63    #Store instance of class Load
[a916ccc]64    __load = None
[d22da51]65   
66   
[1b0b3ca]67    class Load(object):
[a916ccc]68   
69        def __init__(self):
[d22da51]70            #Dictionary containing readers and extension as keys
[a916ccc]71            self.readers = {}
[d22da51]72            #Load all readers in plugins
[579ba85]73           
74            #TODO: misuse of __setitem__
75            #TODO: this bad call is done twice: here, and in Loader.__init__
76            #self.__setitem__()
[d22da51]77           
[a916ccc]78           
[2fd516b]79        def __setitem__(self,dir=None, ext=None, reader=None):
[d22da51]80            """
81                __setitem__  sets in a dictionary(self.readers) a given reader
82                with a file extension that it can read.
83                @param ext: extension given of type string
84                @param reader:instance Reader class
[2fd516b]85                @param dir: directory name where plugins readers will be saved
[d22da51]86                @raise : ValueError will be raise if a "plugins" directory is not found
87                and the user didn't add a reader as parameter or if the user didn't
88                add a reader as a parameter and plugins directory doesn't contain
89                plugin reader.
90                if an extension is not specified and a reader does not contain a field
[d3619421]91                ext , a warning is printed in test_log.txt file.
[d22da51]92                @note: when called without parameters __setitem__ will try to load
[2fd516b]93                readers inside a "readers" directory
94                if call with a directory name will try find readers
95                from that directory "dir"
[d22da51]96            """
[2fd516b]97            if dir==None:
[d3619421]98                dir = 'readers'
[579ba85]99               
100            #TODO Probably name the new path something else...
101           
102            #TODO: The whole concept of plug-ins was missed here.
103            # First we want to always load the reader we have (in 'readers')
104            # and THEN we want to add any additional readers found in
105            # a pre-defined plug-in path (that path should be a variable).
[d3619421]106            dir=os.path.join(os.path.dirname(os.path.abspath(__file__)),dir)
[16d8e5f]107           
[8d6440f]108            if (reader==None and  ext==None) or dir:#1st load
[a916ccc]109                plugReader=None
[2fd516b]110                if os.path.isdir(dir):
111                    plugReader=_findReaders(dir)# import all module in plugins
[579ba85]112               
113                #TODO The following just doesn't make sense
114                # ../C:\Python25\lib... ????
[2fd516b]115                if os.path.isdir('../'+dir):
116                    plugReader=_findReaders('../'+dir)
[d3619421]117 
118               
[a916ccc]119                if plugReader !=None:
[d3619421]120                    list=[]
[a916ccc]121                    for preader in plugReader:# for each modules takes list of extensions
[579ba85]122                        #TODO should use hasattr rather than a try/except block
[2fd516b]123                        try:
124                            list=preader.ext
[d3619421]125                        except AttributeError,msg:
126                            logging.warning(msg)
127                            pass
128                            #raise  AttributeError," %s instance has no attribute 'ext'"\
129                            #%(preader.__class__)
130                        if list !=[]:
131                            for item in list:
132                                ext=item
133                                if ext not in self.readers:#assign extension with its reader
134                                    self.readers[ext] = []
135                                self.readers[ext].insert(0,preader)
[d22da51]136            #Reader and extension are given
[a916ccc]137            elif reader !=None and  ext !=None:
138                if ext not in self.readers:
139                    self.readers[ext] = []
140                self.readers[ext].insert(0,reader)
141            elif reader!=None:
[d22da51]142                #only reader is receive try to find a field ext
[2fd516b]143                try:
144                    list=preader.ext
145                except:
146                    raise AttributeError," Reader instance has no attribute 'ext'"
147                for item in list:
148               
149                    ext=item
150                    if ext not in self.readers:#assign extension with its reader
151                        self.readers[ext] = []
152                    self.readers[ext].insert(0,reader)
153
[a916ccc]154            else:
155                raise ValueError,"missing reader"
[d22da51]156               
[a916ccc]157           
158        def __getitem__(self, ext):
[d22da51]159            """
160                __getitem__ get a list of readers that can read a file with that extension
161                @param ext: file extension
162                @return self.readers[ext]:list of readers that can read a file
163                with that extension
164            """
[a916ccc]165            return self.readers[ext]
166           
167        def __contains__(self, ext):
[d22da51]168            """
169                @param ext:file extension
170                @return: True or False whether there is a reader file with that extension
171            """
[a916ccc]172            return ext in self.readers
173       
174       
175        def formats(self, name=True, ext=False):
176            """
177            Return a list of the registered formats.  If name=True then
178            named formats are returned.  If ext=True then extensions
179            are returned.
180            """
181            names = [a for a in self.readers.keys() if not a.startswith('.')]
182            exts = [a for a in self.readers.keys() if a.startswith('.')]
183            names.sort()
184            exts.sort()
185            ret = []
186            if name: ret += names
187            if ext: ret += exts
188            return ret
189           
190        def lookup(self, path):
191            """
192            Return the loader associated with the file type of path.
193            """       
194            file = os.path.basename(path)
195            idx = file.find('.')
196            ext = file[idx:] if idx >= 0 else ''
[d22da51]197           
[a916ccc]198            try:
199                return self.readers[ext]
200            except:
[d3619421]201                logging.warning("Unknown file type '%s'"%ext)
[3dd7cce]202                raise RuntimeError, "Unknown file type '%s'"%ext
[d22da51]203               
204       
[a916ccc]205       
206        def load(self, path, format=None):
207            """
[d22da51]208                Call reader for the file type of path.
209                @param path: path to file to load
210                @param format: extension of file to load
211                @return Data if sucessful
212                  or None is not reader was able to read that file
213                Raises ValueError if no reader is available.
214                May raise a loader-defined exception if loader fails.
[a916ccc]215            """
[1b0b3ca]216            try:
217                os.path.isfile( os.path.abspath(path)) 
218            except:
[16d8e5f]219                raise ValueError," file path unknown"
[d22da51]220           
[a916ccc]221            if format is None:
[d22da51]222                try:
223                    readers = self.lookup(path)
[4245594]224                except :
225                    raise 
[a916ccc]226            else:
227                readers = self.readers[format]
228            if readers!=None:
229                for fn in readers:
230                    try:
231                        value=fn.read(path)
232                        return value
[8176aad]233                    except:
234                        logging.error("Load Error: %s"% (sys.exc_value))
[d22da51]235            else:
236                raise ValueError,"Loader contains no reader"
237                       
238                         
[a916ccc]239    def __init__(self):
240        """ Create singleton instance """
241        # Check whether we already have an instance
[1b0b3ca]242        if Loader.__load is None:
[a916ccc]243            # Create and remember instance
[1b0b3ca]244            Loader.__load = Loader.Load()
245            Loader.__load.__setitem__()
[a916ccc]246        # Store instance reference as the only member in the handle
[1b0b3ca]247        self.__dict__['_Loader__load'] = Loader.__load
[a916ccc]248
249    def __getattr__(self, attr):
250        """ Delegate access to implementation """
251        return getattr(self.__load, attr)
252
253    def __setattr__(self, attr, value):
254        """ Delegate access to implementation """
255        return setattr(self.__load, attr, value)
Note: See TracBrowser for help on using the repository browser.