Package Gnumed :: Package timelinelib :: Package db :: Module utils
[frames] | no frames]

Source Code for Module Gnumed.timelinelib.db.utils

 1  # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018  Rickard Lindberg, Roger Lindberg 
 2  # 
 3  # This file is part of Timeline. 
 4  # 
 5  # Timeline is free software: you can redistribute it and/or modify 
 6  # it under the terms of the GNU General Public License as published by 
 7  # the Free Software Foundation, either version 3 of the License, or 
 8  # (at your option) any later version. 
 9  # 
10  # Timeline is distributed in the hope that it will be useful, 
11  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
13  # GNU General Public License for more details. 
14  # 
15  # You should have received a copy of the GNU General Public License 
16  # along with Timeline.  If not, see <http://www.gnu.org/licenses/>. 
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  from timelinelib.general.encodings import to_unicode 
25   
26   
27 -def safe_write(path, encoding, write_fn):
28 """ 29 Write to path in such a way that the contents of path is only modified 30 correctly or not modified at all. 31 32 In some extremely rare cases the contents of path might be incorrect, but 33 in those cases the correct content is always present in another dbfile. 34 """ 35 def raise_error(specific_msg, cause_exception): 36 err_general = _("Unable to save timeline data to '%s'. File left unmodified.") % path 37 err_template = "%s\n\n%%s\n\n%%s" % err_general 38 raise TimelineIOError(err_template % (to_unicode(specific_msg), to_unicode(cause_exception)))
39 tmp_path = create_non_exising_path(path, "tmp") 40 backup_path = create_non_exising_path(path, "bak") 41 # Write data to tmp dbfile 42 try: 43 if encoding is None: 44 dbfile = open(tmp_path, "wb") 45 else: 46 dbfile = codecs.open(tmp_path, "w", encoding) 47 try: 48 try: 49 write_fn(dbfile) 50 except Exception as e: 51 raise_error(_("Unable to write timeline data."), e) 52 finally: 53 dbfile.close() 54 except IOError as e: 55 raise_error(_("Unable to write to temporary dbfile '%s'.") % tmp_path, e) 56 # Copy original to backup (if original exists) 57 if os.path.exists(path): 58 try: 59 os.rename(path, backup_path) 60 except Exception as e: # Can this only be a OSError? 61 raise_error(_("Unable to take backup to '%s'.") % backup_path, e) 62 # Copy tmp to original 63 try: 64 os.rename(tmp_path, path) 65 except Exception as e: # Can this only be a OSError? 66 raise_error(_("Unable to rename temporary dbfile '%s' to original.") % tmp_path, e) 67 # Delete backup (if backup was created) 68 if os.path.exists(backup_path): 69 try: 70 os.remove(backup_path) 71 except Exception as e: # Can this only be a OSError? 72 raise_error(_("Unable to delete backup dbfile '%s'.") % backup_path, e) 73 74
75 -def create_non_exising_path(base, suffix):
76 i = 1 77 while True: 78 new_path = "%s.%s%i" % (base, suffix, i) 79 if os.path.exists(new_path): 80 i += 1 81 else: 82 return new_path
83 84
85 -def safe_locking(controller, edit_function, exception_handler=None):
86 if controller.ok_to_edit(): 87 try: 88 register_unlock_function(controller.edit_ends) 89 edit_function() 90 except Exception as e: 91 if exception_handler is not None: 92 controller.edit_ends() 93 exception_handler(e) 94 else: 95 raise 96 finally: 97 controller.edit_ends()
98