error can be locked within properties()

and simplified the componenterrors again
This commit is contained in:
tassaron 2017-07-25 22:02:47 -04:00
parent 661526b073
commit 15d70474d4
6 changed files with 46 additions and 66 deletions

View File

@ -19,7 +19,7 @@ class ComponentMetaclass(type(QtCore.QObject)):
return func(self, *args, **kwargs)
except Exception:
try:
raise ComponentInitError(self, 'initialization process')
raise ComponentError(self, 'initialization process')
except ComponentError:
return
return initializationWrapper
@ -63,7 +63,13 @@ class ComponentMetaclass(type(QtCore.QObject)):
if self._lockedProperties is not None:
return self._lockedProperties
else:
return func(self)
try:
return func(self)
except Exception:
try:
raise ComponentError(self, 'properties')
except ComponentError:
return []
return propertiesWrapper
def errorWrapper(func):
@ -396,18 +402,18 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass):
'''
class ComponentException(RuntimeError):
'''A base class for component errors'''
class ComponentError(RuntimeError):
'''Gives the MainWindow a traceback to display, and cancels the export.'''
_prevErrors = []
prevErrors = []
def __init__(self, caller, name, immediate):
def __init__(self, caller, name):
print('ComponentError by %s: %s' % (caller.name, name))
super().__init__()
if len(ComponentException._prevErrors) > 1:
ComponentException._prevErrors.pop()
ComponentException._prevErrors.insert(0, name)
if name in ComponentException._prevErrors[1:]:
if len(ComponentError.prevErrors) > 1:
ComponentError.prevErrors.pop()
ComponentError.prevErrors.insert(0, name)
if name in ComponentError.prevErrors[1:]:
# Don't create multiple windows for repeated messages
return
@ -434,28 +440,4 @@ class ComponentException(RuntimeError):
)
)
if immediate:
caller._error.emit(string, detail)
else:
caller.lockProperties(['error'])
caller.lockError((string, detail))
class ComponentError(ComponentException):
'''
Use for general Python errors caused by a component at any time.
Raising this gives the MainWindow a traceback to display and
cancels any export in progress.
'''
def __init__(self, caller, name):
ComponentException.__init__(self, caller, name, True)
class ComponentInitError(ComponentError):
'''
Use for Python errors in preFrameRender, while the export is starting.
This will end the video thread in a clean way by locking the component
into an error state so the export definitely won't begin.
'''
def __init__(self, caller, name):
ComponentException.__init__(self, caller, name, False)
caller._error.emit(string, detail)

View File

@ -154,33 +154,28 @@ class Component(Component):
return frame
def properties(self):
# TODO: Disallow selecting the same video you're exporting to
props = []
if not self.videoPath or self.badVideo \
or not os.path.exists(self.videoPath):
return ['error']
if not self.videoPath:
self.lockError("There is no video selected.")
elif self.badVideo:
self.lockError("Could not identify an audio stream in this video.")
elif not os.path.exists(self.videoPath):
self.lockError("The video selected does not exist!")
elif (os.path.realpath(self.videoPath) ==
os.path.realpath(
self.parent.window.lineEdit_outputFile.text())):
self.lockError("Input and output paths match.")
if self.useAudio:
props.append('audio')
self.testAudioStream()
if self.badAudio:
return ['error']
if not testAudioStream(self.videoPath) \
and self.error() is None:
self.lockError(
"Could not identify an audio stream in this video.")
return props
def error(self):
if self.badAudio:
return "Could not identify an audio stream in this video."
if not self.videoPath:
return "There is no video selected."
if not os.path.exists(self.videoPath):
return "The video selected does not exist!"
if self.badVideo:
return "The video selected is corrupt!"
def testAudioStream(self):
self.badAudio = testAudioStream(self.videoPath)
def audio(self):
params = {}
if self.volume != 1.0:

View File

@ -573,16 +573,16 @@ class MainWindow(QtWidgets.QMainWindow):
@QtCore.pyqtSlot(str, str)
def videoThreadError(self, msg, detail):
self.showMessage(
msg=msg,
detail=detail,
icon='Warning',
)
try:
self.stopVideo()
except AttributeError as e:
if 'videoWorker' not in str(e):
raise
self.showMessage(
msg=msg,
detail=detail,
icon='Warning',
)
def changeEncodingStatus(self, status):
self.encoding = status

BIN
src/presetmanager.pyc Normal file

Binary file not shown.

View File

@ -224,9 +224,9 @@ def testAudioStream(filename):
try:
checkOutput(audioTestCommand, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError:
return True
else:
return False
else:
return True
def getAudioDuration(filename):

View File

@ -163,24 +163,27 @@ class Worker(QtCore.QObject):
except ComponentError:
pass
if 'error' in comp.properties():
compProps = comp.properties()
if 'error' in compProps or comp.error() is not None:
self.cancel()
self.canceled = True
canceledByComponent = True
compError = comp.error() \
if type(comp.error()) is tuple else (comp.error(), '')
errMsg = (
"Component #%s encountered an error!" % compNo
"Component #%s (%s) encountered an error!" % (
str(compNo), comp.name
)
if comp.error() is None else
'Export cancelled by component #%s (%s): %s' % (
str(compNo),
str(comp),
comp.name,
compError[0]
)
)
comp._error.emit(errMsg, compError[1])
break
if 'static' in comp.properties():
if 'static' in compProps:
self.staticComponents[compNo] = \
comp.frameRender(compNo, 0).copy()