Fitting file import improvements:
- Blank files don't cause crash - If error happens during processing, notify user
This commit is contained in:
@@ -786,7 +786,7 @@ class MainFrame(wx.Frame):
|
||||
else:
|
||||
self.progressDialog.Update(info)
|
||||
|
||||
def fileImportCallback(self, info, fits=None):
|
||||
def fileImportCallback(self, action, data=None):
|
||||
"""
|
||||
While importing fits from file, the logic calls back to this function to
|
||||
update progress bar to show activity. XML files can contain multiple
|
||||
@@ -794,18 +794,28 @@ class MainFrame(wx.Frame):
|
||||
a single ship. When iterating through the files, we update the message
|
||||
when we start a new file, and then Pulse the progress bar with every fit
|
||||
that is processed.
|
||||
|
||||
action : a flag that lets us know how to deal with :data
|
||||
None: Pulse the progress bar
|
||||
1: Replace message with data
|
||||
other: Close dialog and handle based on :action (-1 open fits, -2 display error)
|
||||
"""
|
||||
|
||||
if info == -1:
|
||||
self.closeProgressDialog()
|
||||
self._openAfterImport(fits)
|
||||
elif info != self.progressDialog.message and info is not None:
|
||||
# New message, overwrite cached message and update
|
||||
self.progressDialog.message = info
|
||||
self.progressDialog.Pulse(info)
|
||||
else:
|
||||
# Simply Pulse() if we don't have anything else to do
|
||||
if action is None:
|
||||
self.progressDialog.Pulse()
|
||||
elif action == 1 and data != self.progressDialog.message:
|
||||
self.progressDialog.message = data
|
||||
self.progressDialog.Pulse(data)
|
||||
else:
|
||||
self.closeProgressDialog()
|
||||
if action == -1:
|
||||
self._openAfterImport(data)
|
||||
elif action == -2:
|
||||
dlg = wx.MessageDialog(self,
|
||||
"The following error was generated\n\n%s\n\nBe aware that already processed fits were not saved"%data,
|
||||
"Import Error", wx.OK | wx.ICON_ERROR)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
return
|
||||
|
||||
def _openAfterImport(self, fits):
|
||||
if len(fits) > 0:
|
||||
|
||||
@@ -24,6 +24,8 @@ import logging
|
||||
import wx
|
||||
from codecs import open
|
||||
|
||||
import xml.parsers.expat
|
||||
|
||||
import eos.db
|
||||
import eos.types
|
||||
|
||||
@@ -65,10 +67,13 @@ class FitImportThread(threading.Thread):
|
||||
|
||||
def run(self):
|
||||
sFit = Fit.getInstance()
|
||||
fits = sFit.importFitFromFiles(self.paths, self.callback)
|
||||
success, result = sFit.importFitFromFiles(self.paths, self.callback)
|
||||
|
||||
# Send done signal to GUI
|
||||
wx.CallAfter(self.callback, -1, fits)
|
||||
if not success: # there was an error during processing
|
||||
logger.error("Error while processing file import: %s", result)
|
||||
wx.CallAfter(self.callback, -2, result)
|
||||
else: # Send done signal to GUI
|
||||
wx.CallAfter(self.callback, -1, result)
|
||||
|
||||
|
||||
class Fit(object):
|
||||
@@ -849,37 +854,48 @@ class Fit(object):
|
||||
fits = []
|
||||
for path in paths:
|
||||
if callback: # Pulse
|
||||
wx.CallAfter(callback, "Processing file:\n%s"%path)
|
||||
wx.CallAfter(callback, 1, "Processing file:\n%s"%path)
|
||||
|
||||
file = open(path, "r")
|
||||
srcString = file.read()
|
||||
|
||||
if len(srcString) == 0: # ignore blank files
|
||||
continue
|
||||
|
||||
codec_found = None
|
||||
# If file had ANSI encoding, decode it to unicode using detection
|
||||
# of BOM header or if there is no header try default
|
||||
# codepage then fallback to utf-16, cp1252
|
||||
|
||||
if isinstance(srcString, str):
|
||||
encoding_map = (('\xef\xbb\xbf', 'utf-8'),('\xff\xfe\0\0', 'utf-32'),('\0\0\xfe\xff', 'UTF-32BE'),('\xff\xfe', 'utf-16'),('\xfe\xff', 'UTF-16BE'))
|
||||
encoding_map = (
|
||||
('\xef\xbb\xbf', 'utf-8'),
|
||||
('\xff\xfe\0\0', 'utf-32'),
|
||||
('\0\0\xfe\xff', 'UTF-32BE'),
|
||||
('\xff\xfe', 'utf-16'),
|
||||
('\xfe\xff', 'UTF-16BE'))
|
||||
|
||||
for bom, encoding in encoding_map:
|
||||
if srcString.startswith(bom):
|
||||
codec_found = encoding
|
||||
savebom = bom
|
||||
|
||||
if codec_found is None:
|
||||
logger.warn("Unicode BOM not found in file %s.", path)
|
||||
logger.info("Unicode BOM not found in file %s.", path)
|
||||
attempt_codecs = (defcodepage, "utf-8", "utf-16", "cp1252")
|
||||
|
||||
for page in attempt_codecs:
|
||||
try:
|
||||
logger.warn("Attempting to decode file %s using %s page.", path, page)
|
||||
logger.info("Attempting to decode file %s using %s page.", path, page)
|
||||
srcString = unicode(srcString, page)
|
||||
codec_found = page
|
||||
logger.warn("File %s decoded using %s page.", path, page)
|
||||
logger.info("File %s decoded using %s page.", path, page)
|
||||
except UnicodeDecodeError:
|
||||
logger.warn("Error unicode decoding %s from page %s, trying next codec", path, page)
|
||||
logger.info("Error unicode decoding %s from page %s, trying next codec", path, page)
|
||||
else:
|
||||
break
|
||||
else:
|
||||
logger.debug("Unicode BOM detected in %s, using %s page.", path, codec_found)
|
||||
logger.info("Unicode BOM detected in %s, using %s page.", path, codec_found)
|
||||
srcString = unicode(srcString[len(savebom):], codec_found)
|
||||
|
||||
else:
|
||||
@@ -889,8 +905,17 @@ class Fit(object):
|
||||
else:
|
||||
codec_found = "utf-8"
|
||||
|
||||
_, fitsImport = Port.importAuto(srcString, path, callback=callback, encoding=codec_found)
|
||||
fits += fitsImport
|
||||
if codec_found is None:
|
||||
return False, "Proper codec could not be established for %s" % path
|
||||
|
||||
try:
|
||||
_, fitsImport = Port.importAuto(srcString, path, callback=callback, encoding=codec_found)
|
||||
fits += fitsImport
|
||||
except xml.parsers.expat.ExpatError, e:
|
||||
return False, "Malformed XML in %s"%path
|
||||
except Exception, e:
|
||||
logger.exception("Unknown exception processing: %s", path)
|
||||
return False, "Unknown Error while processing %s"%path
|
||||
|
||||
IDs = []
|
||||
numFits = len(fits)
|
||||
@@ -903,12 +928,12 @@ class Fit(object):
|
||||
IDs.append(fit.ID)
|
||||
if callback: # Pulse
|
||||
wx.CallAfter(
|
||||
callback,
|
||||
callback, 1,
|
||||
"Processing complete, saving fits to database\n(%d/%d)" %
|
||||
(i+1, numFits)
|
||||
)
|
||||
|
||||
return fits
|
||||
return True, fits
|
||||
|
||||
def importFitFromBuffer(self, bufferStr, activeFit=None):
|
||||
_, fits = Port.importAuto(bufferStr, activeFit=activeFit)
|
||||
|
||||
Reference in New Issue
Block a user