28
28
"""
29
29
30
30
import os
31
- import platform
32
31
import shutil
33
32
import sys
34
33
import webbrowser
50
49
QLineEdit , QSlider , QLabel , QComboBox , QTextEdit
51
50
)
52
51
53
- from classes import info , ui_util , settings , qt_types , updates
52
+ from classes import exceptions , info , settings , qt_types , ui_util , updates
54
53
from classes .app import get_app
55
54
from classes .conversion import zoomToSeconds , secondsToZoom
56
55
from classes .exporters .edl import export_edl
57
56
from classes .exporters .final_cut_pro import export_xml
58
57
from classes .importers .edl import import_edl
59
58
from classes .importers .final_cut_pro import import_xml
60
59
from classes .logger import log
61
- from classes .metrics import (
62
- track_metric_session , track_metric_screen ,
63
- track_metric_error , track_exception_stacktrace ,
64
- )
60
+ from classes .metrics import track_metric_session , track_metric_screen
65
61
from classes .query import Clip , Transition , Marker , Track
66
62
from classes .thumbnail import httpThumbnailServerThread
67
63
from classes .time_parts import secondsToTimecode
@@ -214,101 +210,26 @@ def recover_backup(self):
214
210
def create_lock_file (self ):
215
211
"""Create a lock file"""
216
212
lock_path = os .path .join (info .USER_PATH , ".lock" )
217
- lock_value = str (uuid4 ())
218
-
219
213
# Check if it already exists
220
214
if os .path .exists (lock_path ):
221
- # Walk the libopenshot log (if found), and try and find last line before this launch
222
- log_path = os .path .join (info .USER_PATH , "libopenshot.log" )
223
- last_log_line = ""
224
- last_stack_trace = ""
225
- found_stack = False
226
- log_start_counter = 0
227
- if os .path .exists (log_path ):
228
- with open (log_path , "rb" ) as f :
229
- # Read from bottom up
230
- for raw_line in reversed (self .tail_file (f , 500 )):
231
- line = str (raw_line , 'utf-8' )
232
- # Detect stack trace
233
- if "End of Stack Trace" in line :
234
- found_stack = True
235
- continue
236
- if "Unhandled Exception: Stack Trace" in line :
237
- found_stack = False
238
- continue
239
- if "libopenshot logging:" in line :
240
- log_start_counter += 1
241
- if log_start_counter > 1 :
242
- # Found the previous log start, too old now
243
- break
244
-
245
- if found_stack :
246
- # Append line to beginning of stacktrace
247
- last_stack_trace = line + last_stack_trace
248
-
249
- # Ignore certain useless lines
250
- line .strip ()
251
- if all (["---" not in line ,
252
- "libopenshot logging:" not in line ,
253
- not last_log_line ,
254
- ]):
255
- last_log_line = line
256
-
257
- # Split last stack trace (if any)
258
- if last_stack_trace :
259
- # Get top line of stack trace (for metrics)
260
- last_log_line = last_stack_trace .split ("\n " )[0 ].strip ()
261
-
262
- # Send stacktrace for debugging (if send metrics is enabled)
263
- track_exception_stacktrace (last_stack_trace , "libopenshot" )
264
-
265
- # Clear / normalize log line (so we can roll them up in the analytics)
266
- if last_log_line :
267
- # Format last log line based on OS (since each OS can be formatted differently)
268
- if platform .system () == "Darwin" :
269
- last_log_line = "mac-%s" % last_log_line [58 :].strip ()
270
- elif platform .system () == "Windows" :
271
- last_log_line = "windows-%s" % last_log_line
272
- elif platform .system () == "Linux" :
273
- last_log_line = "linux-%s" % last_log_line .replace ("/usr/local/lib/" , "" )
274
-
275
- # Remove '()' from line, and split. Trying to grab the beginning of the log line.
276
- last_log_line = last_log_line .replace ("()" , "" )
277
- log_parts = last_log_line .split ("(" )
278
- if len (log_parts ) == 2 :
279
- last_log_line = "-%s" % log_parts [0 ].replace (
280
- "logger_libopenshot:INFO " , "" ).strip ()[:64 ]
281
- elif len (log_parts ) >= 3 :
282
- last_log_line = "-%s (%s" % (log_parts [0 ].replace (
283
- "logger_libopenshot:INFO " , "" ).strip ()[:64 ], log_parts [1 ])
284
- else :
285
- last_log_line = ""
286
-
287
- # Throw exception (with last libopenshot line... if found)
288
- log .error (
289
- "Unhandled crash detected... will attempt to recover backup project: %s"
290
- % info .BACKUP_FILE )
291
- track_metric_error ("unhandled-crash%s" % last_log_line , True )
292
-
293
- # Remove file
215
+ exceptions .libopenshot_crash_recovery ()
216
+ log .error ("Unhandled crash detected. Preserving cache." )
294
217
self .destroy_lock_file ()
295
-
296
218
else :
297
219
# Normal startup, clear thumbnails
298
220
self .clear_all_thumbnails ()
299
221
300
222
# Write lock file (try a few times if failure)
223
+ lock_value = str (uuid4 ())
301
224
for attempt in range (5 ):
302
225
try :
303
226
# Create lock file
304
227
with open (lock_path , 'w' ) as f :
305
228
f .write (lock_value )
306
- log .debug ("Wrote value {} to lock file {}" .format (
307
- lock_value , lock_path ))
229
+ log .debug ("Wrote value %s to lock file %s" , lock_value , lock_path )
308
230
break
309
231
except OSError :
310
- log .debug ('Failed to write lock file (attempt: {})' .format (
311
- attempt ), exc_info = 1 )
232
+ log .debug ("Failed to write lock file (attempt: %d)" , attempt , exc_info = 1 )
312
233
sleep (0.25 )
313
234
314
235
def destroy_lock_file (self ):
@@ -327,25 +248,6 @@ def destroy_lock_file(self):
327
248
log .debug ('Failed to destroy lock file (attempt: %s)' % attempt , exc_info = 1 )
328
249
sleep (0.25 )
329
250
330
- def tail_file (self , f , n , offset = None ):
331
- """Read the end of a file (n number of lines)"""
332
- avg_line_length = 90
333
- to_read = n + (offset or 0 )
334
-
335
- while True :
336
- try :
337
- # Seek to byte position
338
- f .seek (- (avg_line_length * to_read ), 2 )
339
- except IOError :
340
- # Byte position not found
341
- f .seek (0 )
342
- pos = f .tell ()
343
- lines = f .read ().splitlines ()
344
- if len (lines ) >= to_read or pos == 0 :
345
- # Return the lines
346
- return lines [- to_read :offset and - offset or None ]
347
- avg_line_length *= 2
348
-
349
251
def actionNew_trigger (self ):
350
252
351
253
app = get_app ()
@@ -413,14 +315,9 @@ def actionTitle_trigger(self):
413
315
from windows .title_editor import TitleEditor
414
316
win = TitleEditor ()
415
317
# Run the dialog event loop - blocking interaction on this window during that time
416
- result = win .exec_ ()
417
- if result == QDialog .Accepted :
418
- log .info ('title editor add confirmed' )
419
- else :
420
- log .info ('title editor add cancelled' )
318
+ win .exec_ ()
421
319
422
320
def actionEditTitle_trigger (self ):
423
-
424
321
# Loop through selected files (set 1 selected file if more than 1)
425
322
for f in self .selected_files ():
426
323
if f .data .get ("path" ).endswith (".svg" ):
@@ -433,7 +330,7 @@ def actionEditTitle_trigger(self):
433
330
434
331
# show dialog for editing title
435
332
from windows .title_editor import TitleEditor
436
- win = TitleEditor (file_path )
333
+ win = TitleEditor (edit_file_path = file_path )
437
334
# Run the dialog event loop - blocking interaction on this window during that time
438
335
win .exec_ ()
439
336
@@ -467,7 +364,7 @@ def actionDuplicateTitle_trigger(self):
467
364
468
365
# show dialog for editing title
469
366
from windows .title_editor import TitleEditor
470
- win = TitleEditor (file_path , duplicate = True )
367
+ win = TitleEditor (edit_file_path = file_path , duplicate = True )
471
368
# Run the dialog event loop - blocking interaction on this window during that time
472
369
return win .exec_ ()
473
370
0 commit comments