Merge lp:~raoul-snyman/openlp/bug-855342 into lp:openlp

Proposed by Raoul Snyman
Status: Merged
Approved by: Tim Bentley
Approved revision: 1760
Merged at revision: 1760
Proposed branch: lp:~raoul-snyman/openlp/bug-855342
Merge into: lp:openlp
Diff against target: 143 lines (+48/-24)
1 file modified
openlp/core/ui/servicemanager.py (+48/-24)
To merge this branch: bzr merge lp:~raoul-snyman/openlp/bug-855342
Reviewer Review Type Date Requested Status
Tim Bentley Approve
Review via email: mp+76850@code.launchpad.net

Commit message

Fixed the last part of bug #855342 where when you save a file a few times, it throws an exception.

Description of the change

Fixed the last part of bug #855342 where when you save a file a few times, it throws an exception.

To post a comment you must log in.
Revision history for this message
Tim Bentley (trb143) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/core/ui/servicemanager.py'
2--- openlp/core/ui/servicemanager.py 2011-09-21 20:47:30 +0000
3+++ openlp/core/ui/servicemanager.py 2011-09-24 13:06:26 +0000
4@@ -30,6 +30,7 @@
5 import os
6 import shutil
7 import zipfile
8+from tempfile import mkstemp
9
10 log = logging.getLogger(__name__)
11
12@@ -467,15 +468,24 @@
13
14 def saveFile(self):
15 """
16- Save the current Service file.
17+ Save the current service file.
18+
19+ A temporary file is created so that we don't overwrite the existing one
20+ and leave a mangled service file should there be an error when saving.
21+ Audio files are also copied into the service manager directory, and
22+ then packaged into the zip file.
23 """
24 if not self.fileName():
25 return self.saveFileAs()
26+ temp_file, temp_file_name = mkstemp(u'.osz', u'openlp_')
27+ # We don't need the file handle.
28+ os.close(temp_file)
29+ log.debug(temp_file_name)
30 path_file_name = unicode(self.fileName())
31 path, file_name = os.path.split(path_file_name)
32 basename, extension = os.path.splitext(file_name)
33 service_file_name = '%s.osd' % basename
34- log.debug(u'ServiceManager.saveFile - %s' % path_file_name)
35+ log.debug(u'ServiceManager.saveFile - %s', path_file_name)
36 SettingsManager.set_last_dir(
37 self.mainwindow.servicemanagerSettingsSection,
38 path)
39@@ -494,7 +504,8 @@
40 if len(service_item[u'header'][u'background_audio']) > 0:
41 for i, filename in \
42 enumerate(service_item[u'header'][u'background_audio']):
43- new_file = os.path.join(u'audio', item[u'service_item']._uuid,
44+ new_file = os.path.join(u'audio',
45+ item[u'service_item']._uuid,
46 os.path.split(filename)[1])
47 audio_files.append((filename, new_file))
48 service_item[u'header'][u'background_audio'][i] = new_file
49@@ -545,30 +556,38 @@
50 success = True
51 self.mainwindow.incrementProgressBar()
52 try:
53- zip = zipfile.ZipFile(path_file_name, 'w', zipfile.ZIP_STORED,
54+ zip = zipfile.ZipFile(temp_file_name, 'w', zipfile.ZIP_STORED,
55 allow_zip_64)
56 # First we add service contents.
57 # We save ALL filenames into ZIP using UTF-8.
58 zip.writestr(service_file_name.encode(u'utf-8'), service_content)
59 # Finally add all the listed media files.
60- for path_from in write_list:
61- zip.write(path_from, path_from.encode(u'utf-8'))
62- for path_from, path_to in audio_files:
63- if path_from == path_to:
64- # If this file has already been saved, let's use set the
65- # from path to the real location of the files
66- path_from = os.path.join(self.servicePath, path_from)
67- else:
68- # If this file has not yet been saved, let's copy the file
69- # to the service manager path
70- save_file = os.path.join(self.servicePath, path_to)
71- save_path = os.path.split(save_file)[0]
72- if not os.path.exists(save_path):
73- os.makedirs(save_path)
74- shutil.copy(path_from, save_file)
75- zip.write(path_from, path_to.encode(u'utf-8'))
76+ for write_from in write_list:
77+ zip.write(write_from, write_from.encode(u'utf-8'))
78+ for audio_from, audio_to in audio_files:
79+ if audio_from.startswith(u'audio'):
80+ # When items are saved, they get new UUID's. Let's copy the
81+ # file to the new location. Unused files can be ignored,
82+ # OpenLP automatically cleans up the service manager dir on
83+ # exit.
84+ audio_from = os.path.join(self.servicePath, audio_from)
85+ save_file = os.path.join(self.servicePath, audio_to)
86+ save_path = os.path.split(save_file)[0]
87+ if not os.path.exists(save_path):
88+ os.makedirs(save_path)
89+ if not os.path.exists(save_file):
90+ shutil.copy(audio_from, save_file)
91+ zip.write(audio_from, audio_to.encode(u'utf-8'))
92 except IOError:
93- log.exception(u'Failed to save service to disk')
94+ log.exception(u'Failed to save service to disk: %s', temp_file_name)
95+ # Add this line in after the release to notify the user that saving
96+ # their file failed. Commented out due to string freeze.
97+ #Receiver.send_message(u'openlp_error_message', {
98+ # u'title': translate(u'OpenLP.ServiceManager',
99+ # u'Error Saving File'),
100+ # u'message': translate(u'OpenLP.ServiceManager',
101+ # u'There was an error saving your file.')
102+ #})
103 success = False
104 finally:
105 if zip:
106@@ -576,10 +595,13 @@
107 self.mainwindow.finishedProgressBar()
108 Receiver.send_message(u'cursor_normal')
109 if success:
110+ shutil.copy(temp_file_name, path_file_name)
111 self.mainwindow.addRecentFile(path_file_name)
112 self.setModified(False)
113- else:
114- delete_file(path_file_name)
115+ try:
116+ delete_file(temp_file_name)
117+ except:
118+ pass
119 return success
120
121 def saveFileAs(self):
122@@ -623,6 +645,7 @@
123 osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
124 if not osfile.startswith(u'audio'):
125 osfile = os.path.split(osfile)[1]
126+ log.debug(u'Extract file: %s', osfile)
127 zipinfo.filename = osfile
128 zip.extract(zipinfo, self.servicePath)
129 if osfile.endswith(u'osd'):
130@@ -1022,11 +1045,12 @@
131 """
132 Empties the servicePath of temporary files.
133 """
134+ log.debug(u'Cleaning up servicePath')
135 for file in os.listdir(self.servicePath):
136 file_path = os.path.join(self.servicePath, file)
137 delete_file(file_path)
138 if os.path.exists(os.path.join(self.servicePath, u'audio')):
139- shutil.rmtree(os.path.join(self.servicePath, u'audio'), False)
140+ shutil.rmtree(os.path.join(self.servicePath, u'audio'), True)
141
142 def onThemeComboBoxSelected(self, currentIndex):
143 """