source: sasview/src/sas/sasgui/guiframe/local_perspectives/data_loader/data_loader.py @ 69400ec

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.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 69400ec was 69400ec, checked in by krzywon, 7 years ago

Ask what to do with files that start with a period when loading directory. see #849

  • Property mode set to 100644
File size: 10.1 KB
Line 
1
2"""
3plugin DataLoader responsible of loading data
4"""
5import os
6import sys
7import wx
8import logging
9
10from sas.sascalc.dataloader.loader import Loader
11from sas.sasgui.guiframe.plugin_base import PluginBase
12from sas.sasgui.guiframe.events import StatusEvent
13from sas.sasgui.guiframe.gui_style import GUIFRAME
14from sas.sasgui.guiframe.gui_manager import DEFAULT_OPEN_FOLDER
15try:
16    # Try to find a local config
17    import imp
18    path = os.getcwd()
19    if(os.path.isfile("%s/%s.py" % (path, 'local_config'))) or \
20        (os.path.isfile("%s/%s.pyc" % (path, 'local_config'))):
21        fObj, path, descr = imp.find_module('local_config', [path])
22        config = imp.load_module('local_config', fObj, path, descr)
23    else:
24        # Try simply importing local_config
25        import local_config as config
26except:
27    # Didn't find local config, load the default
28    import sas.sasgui.guiframe.config as config
29
30if config is None:
31    import sas.sasgui.guiframe.config as config
32
33
34extension_list = []
35if config.APPLICATION_STATE_EXTENSION is not None:
36    extension_list.append(config.APPLICATION_STATE_EXTENSION)
37EXTENSIONS = config.PLUGIN_STATE_EXTENSIONS + extension_list
38PLUGINS_WLIST = config.PLUGINS_WLIST
39APPLICATION_WLIST = config.APPLICATION_WLIST
40
41class Plugin(PluginBase):
42
43    def __init__(self):
44        PluginBase.__init__(self, name="DataLoader")
45        # Default location
46        self._default_save_location = DEFAULT_OPEN_FOLDER
47        self.loader = Loader()
48        self._data_menu = None
49
50    def populate_file_menu(self):
51        """
52        get a menu item and append it under file menu of the application
53        add load file menu item and load folder item
54        """
55        # menu for data files
56        menu_list = []
57        data_file_hint = "load one or more data in the application"
58        menu_list = [('&Load Data File(s)', data_file_hint, self.load_data)]
59        gui_style = self.parent.get_style()
60        style = gui_style & GUIFRAME.MULTIPLE_APPLICATIONS
61        style1 = gui_style & GUIFRAME.DATALOADER_ON
62        if style == GUIFRAME.MULTIPLE_APPLICATIONS:
63            # menu for data from folder
64            data_folder_hint = "load multiple data in the application"
65            menu_list.append(('&Load Data Folder', data_folder_hint,
66                              self._load_folder))
67        return menu_list
68
69    def load_data(self, event):
70        """
71        Load data
72        """
73        path = None
74        self._default_save_location = self.parent._default_save_location
75        if self._default_save_location == None:
76            self._default_save_location = os.getcwd()
77
78        cards = self.loader.get_wildcards()
79        temp = [APPLICATION_WLIST] + PLUGINS_WLIST
80        for item in temp:
81            if item in cards:
82                cards.remove(item)
83        wlist = '|'.join(cards)
84        style = wx.OPEN | wx.FD_MULTIPLE
85        dlg = wx.FileDialog(self.parent,
86                            "Choose a file",
87                            self._default_save_location, "",
88                            wlist,
89                            style=style)
90        if dlg.ShowModal() == wx.ID_OK:
91            file_list = dlg.GetPaths()
92            if len(file_list) >= 0 and not file_list[0] is None:
93                self._default_save_location = os.path.dirname(file_list[0])
94                path = self._default_save_location
95        dlg.Destroy()
96
97        if path is None or not file_list or file_list[0] is None:
98            return
99        self.parent._default_save_location = self._default_save_location
100        self.get_data(file_list)
101
102
103    def can_load_data(self):
104        """
105        if return True, then call handler to laod data
106        """
107        return True
108
109
110    def _load_folder(self, event):
111        """
112        Load entire folder
113        """
114        path = None
115        self._default_save_location = self.parent._default_save_location
116        if self._default_save_location == None:
117            self._default_save_location = os.getcwd()
118        dlg = wx.DirDialog(self.parent, "Choose a directory",
119                           self._default_save_location,
120                           style=wx.DD_DEFAULT_STYLE)
121        if dlg.ShowModal() == wx.ID_OK:
122            path = dlg.GetPath()
123            self._default_save_location = path
124        dlg.Destroy()
125        if path is not None:
126            self._default_save_location = os.path.dirname(path)
127        else:
128            return
129        file_list = self.get_file_path(path)
130        self.get_data(file_list)
131        self.parent._default_save_location = self._default_save_location
132
133    def load_error(self, error=None):
134        """
135        Pop up an error message.
136
137        :param error: details error message to be displayed
138        """
139        if error is not None or str(error).strip() != "":
140            dial = wx.MessageDialog(self.parent, str(error), 'Error Loading File',
141                                    wx.OK | wx.ICON_EXCLAMATION)
142            dial.ShowModal()
143
144    def get_file_path(self, path):
145        """
146        Receive a list containing folder then return a list of file
147        """
148        if os.path.isdir(path):
149            return [os.path.join(os.path.abspath(path), filename) for filename in os.listdir(path)]
150
151    def _process_data_and_errors(self, item, p_file, output, message):
152        """
153        Check to see if data set loaded with any errors. If so, append to
154            error message to be sure user knows the issue.
155        """
156        data_error = False
157        if hasattr(item, 'errors'):
158            for error_data in item.errors:
159                data_error = True
160                message += "\tError: {0}\n".format(error_data)
161        else:
162            logging.error("Loader returned an invalid object:\n %s" % str(item))
163            data_error = True
164
165        data = self.parent.create_gui_data(item, p_file)
166        output[data.id] = data
167        return output, message, data_error
168
169    def get_data(self, path, format=None):
170        """
171        """
172        file_errors = {}
173        output = {}
174        exception_occurred = False
175
176        for p_file in path:
177            basename = os.path.basename(p_file)
178            # Skip files that start with a period
179            if basename.startswith("."):
180                msg = "The folder included a potential hidden file - %s." \
181                      % basename
182                msg += " Do you wish to load this file as data?"
183                msg_box = wx.MessageDialog(None, msg, 'Warning',
184                                           wx.OK | wx.CANCEL)
185                if msg_box.ShowModal() == wx.ID_CANCEL:
186                    continue
187            _, extension = os.path.splitext(basename)
188            if extension.lower() in EXTENSIONS:
189                log_msg = "Data Loader cannot "
190                log_msg += "load: {}\n".format(str(p_file))
191                log_msg += "Please try to open that file from \"open project\""
192                log_msg += "or \"open analysis\" menu."
193                logging.info(log_msg)
194                file_errors[basename] = [log_msg]
195                continue
196
197            try:
198                message = "Loading {}...\n".format(p_file)
199                self.load_update(output=output, message=message, info="info")
200                temp = self.loader.load(p_file, format)
201                if not isinstance(temp, list):
202                    temp = [temp]
203                for item in temp:
204                    error_message = ""
205                    output, error_message, data_error = \
206                        self._process_data_and_errors(item,
207                                                      p_file,
208                                                      output,
209                                                      error_message)
210                    if data_error:
211                        if basename in file_errors.keys():
212                            file_errors[basename] += [error_message]
213                        else:
214                            file_errors[basename] = [error_message]
215                        self.load_update(output=output,
216                            message=error_message, info="warning")
217
218                self.load_update(output=output,
219                message="Loaded {}\n".format(p_file),
220                info="info")
221
222            except:
223                logging.error(sys.exc_value)
224
225                error_message = "The Data file you selected could not be loaded.\n"
226                error_message += "Make sure the content of your file"
227                error_message += " is properly formatted.\n"
228                error_message += "When contacting the SasView team, mention the"
229                error_message += " following:\n"
230                error_message += "Error: " + str(sys.exc_info()[1])
231                file_errors[basename] = [error_message]
232                self.load_update(output=output, message=error_message, info="warning")
233
234        if len(file_errors) > 0:
235            error_message = ""
236            for filename, error_array in file_errors.iteritems():
237                error_message += "The following errors occured whilst "
238                error_message += "loading {}:\n".format(filename)
239                for message in error_array:
240                    error_message += message + "\n"
241                error_message += "\n"
242            self.load_update(output=output, message=error_message, info="error")
243
244        self.load_complete(output=output, message="Loading data complete!",
245            info="info")
246
247    def load_update(self, output=None, message="", info="warning"):
248        """
249        print update on the status bar
250        """
251        if message != "":
252            wx.PostEvent(self.parent, StatusEvent(status=message, info=info,
253                                                  type="progress"))
254    def load_complete(self, output, message="", error_message="", path=None,
255                      info="warning"):
256        """
257         post message to  status bar and return list of data
258        """
259        wx.PostEvent(self.parent, StatusEvent(status=message,
260                                              info=info,
261                                              type="stop"))
262        # if error_message != "":
263        #    self.load_error(error_message)
264        self.parent.add_data(data_list=output)
Note: See TracBrowser for help on using the repository browser.