1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import codecs
20 import os.path
21
22 from timelinelib.canvas.data.exceptions import TimelineIOError
23 from timelinelib.wxgui.utils import register_unlock_function
24
25
27 """
28 Write to path in such a way that the contents of path is only modified
29 correctly or not modified at all.
30
31 In some extremely rare cases the contents of path might be incorrect, but
32 in those cases the correct content is always present in another dbfile.
33 """
34 def raise_error(specific_msg, cause_exception):
35 err_general = _("Unable to save timeline data to '%s'. File left unmodified.") % path
36 err_template = "%s\n\n%%s\n\n%%s" % err_general
37 raise TimelineIOError(err_template % (specific_msg, cause_exception))
38 tmp_path = create_non_exising_path(path, "tmp")
39 backup_path = create_non_exising_path(path, "bak")
40
41 try:
42 if encoding is None:
43 dbfile = open(tmp_path, "w")
44 else:
45 dbfile = codecs.open(tmp_path, "w", encoding)
46 try:
47 try:
48 write_fn(dbfile)
49 except Exception as e:
50 raise_error(_("Unable to write timeline data."), e)
51 finally:
52 dbfile.close()
53 except IOError as e:
54 raise_error(_("Unable to write to temporary dbfile '%s'.") % tmp_path, e)
55
56 if os.path.exists(path):
57 try:
58 os.rename(path, backup_path)
59 except Exception as e:
60 raise_error(_("Unable to take backup to '%s'.") % backup_path, e)
61
62 try:
63 os.rename(tmp_path, path)
64 except Exception as e:
65 raise_error(_("Unable to rename temporary dbfile '%s' to original.") % tmp_path, e)
66
67 if os.path.exists(backup_path):
68 try:
69 os.remove(backup_path)
70 except Exception as e:
71 raise_error(_("Unable to delete backup dbfile '%s'.") % backup_path, e)
72
73
75 i = 1
76 while True:
77 new_path = "%s.%s%i" % (base, suffix, i)
78 if os.path.exists(new_path):
79 i += 1
80 else:
81 return new_path
82
83
84 -def safe_locking(controller, edit_function, exception_handler=None):
97