forked from openlp/openlp
Start on refactoring file saving
This commit is contained in:
parent
6e2bc427a7
commit
4b1965520c
@ -27,8 +27,9 @@ import json
|
|||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import zipfile
|
import zipfile
|
||||||
|
from contextlib import suppress
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from tempfile import mkstemp
|
from tempfile import NamedTemporaryFile, mkstemp
|
||||||
|
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
@ -503,35 +504,9 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
|
|||||||
service.append({'openlp_core': core})
|
service.append({'openlp_core': core})
|
||||||
return service
|
return service
|
||||||
|
|
||||||
def save_file(self, field=None):
|
def get_write_file_list(self):
|
||||||
"""
|
|
||||||
Save the current service file.
|
|
||||||
|
|
||||||
A temporary file is created so that we don't overwrite the existing one and leave a mangled service file should
|
|
||||||
there be an error when saving. Audio files are also copied into the service manager directory, and then packaged
|
|
||||||
into the zip file.
|
|
||||||
"""
|
|
||||||
if not self.file_name():
|
|
||||||
return self.save_file_as()
|
|
||||||
temp_file, temp_file_name = mkstemp('.osz', 'openlp_')
|
|
||||||
# We don't need the file handle.
|
|
||||||
os.close(temp_file)
|
|
||||||
self.log_debug(temp_file_name)
|
|
||||||
path_file_name = str(self.file_name())
|
|
||||||
path, file_name = os.path.split(path_file_name)
|
|
||||||
base_name = os.path.splitext(file_name)[0]
|
|
||||||
service_file_name = '{name}.osj'.format(name=base_name)
|
|
||||||
self.log_debug('ServiceManager.save_file - {name}'.format(name=path_file_name))
|
|
||||||
Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', Path(path))
|
|
||||||
service = self.create_basic_service()
|
|
||||||
write_list = []
|
write_list = []
|
||||||
missing_list = []
|
missing_list = []
|
||||||
audio_files = []
|
|
||||||
total_size = 0
|
|
||||||
self.application.set_busy_cursor()
|
|
||||||
# Number of items + 1 to zip it
|
|
||||||
self.main_window.display_progress_bar(len(self.service_items) + 1)
|
|
||||||
# Get list of missing files, and list of files to write
|
|
||||||
for item in self.service_items:
|
for item in self.service_items:
|
||||||
if not item['service_item'].uses_file():
|
if not item['service_item'].uses_file():
|
||||||
continue
|
continue
|
||||||
@ -543,6 +518,32 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
|
|||||||
missing_list.append(path_from)
|
missing_list.append(path_from)
|
||||||
else:
|
else:
|
||||||
write_list.append(path_from)
|
write_list.append(path_from)
|
||||||
|
return write_list, missing_list
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def save_file(self):
|
||||||
|
"""
|
||||||
|
Save the current service file.
|
||||||
|
|
||||||
|
A temporary file is created so that we don't overwrite the existing one and leave a mangled service file should
|
||||||
|
there be an error when saving. Audio files are also copied into the service manager directory, and then packaged
|
||||||
|
into the zip file.
|
||||||
|
"""
|
||||||
|
file_path = self.file_name()
|
||||||
|
service_file_name = '{name}.osj'.format(name=file_path.suffix)
|
||||||
|
self.log_debug('ServiceManager.save_file - {name}'.format(name=file_path))
|
||||||
|
Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', file_path.parent)
|
||||||
|
service = self.create_basic_service()
|
||||||
|
self.application.set_busy_cursor()
|
||||||
|
# Number of items + 1 to zip it
|
||||||
|
self.main_window.display_progress_bar(len(self.service_items) + 1)
|
||||||
|
# Get list of missing files, and list of files to write
|
||||||
|
|
||||||
|
audio_files = []
|
||||||
|
|
||||||
|
write_list, missing_list = self.get_write_file_list()
|
||||||
|
|
||||||
if missing_list:
|
if missing_list:
|
||||||
self.application.set_normal_cursor()
|
self.application.set_normal_cursor()
|
||||||
title = translate('OpenLP.ServiceManager', 'Service File(s) Missing')
|
title = translate('OpenLP.ServiceManager', 'Service File(s) Missing')
|
||||||
@ -572,19 +573,18 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
|
|||||||
# Add the service item to the service.
|
# Add the service item to the service.
|
||||||
service.append({'serviceitem': service_item})
|
service.append({'serviceitem': service_item})
|
||||||
self.repaint_service_list(-1, -1)
|
self.repaint_service_list(-1, -1)
|
||||||
|
total_size = 0
|
||||||
for file_item in write_list:
|
for file_item in write_list:
|
||||||
file_size = os.path.getsize(file_item)
|
file_size = os.path.getsize(file_item)
|
||||||
total_size += file_size
|
total_size += file_size
|
||||||
self.log_debug('ServiceManager.save_file - ZIP contents size is %i bytes' % total_size)
|
self.log_debug('ServiceManager.save_file - ZIP contents size is %i bytes' % total_size)
|
||||||
service_content = json.dumps(service)
|
service_content = json.dumps(service)
|
||||||
# Usual Zip file cannot exceed 2GiB, file with Zip64 cannot be extracted using unzip in UNIX.
|
|
||||||
allow_zip_64 = (total_size > 2147483648 + len(service_content))
|
|
||||||
self.log_debug('ServiceManager.save_file - allowZip64 is {text}'.format(text=allow_zip_64))
|
|
||||||
zip_file = None
|
|
||||||
success = True
|
|
||||||
self.main_window.increment_progress_bar()
|
self.main_window.increment_progress_bar()
|
||||||
try:
|
try:
|
||||||
zip_file = zipfile.ZipFile(temp_file_name, 'w', zipfile.ZIP_STORED, allow_zip_64)
|
with NamedTemporaryFile() as temp_file, \
|
||||||
|
zipfile.ZipFile(temp_file, 'w') as zip_file:
|
||||||
# First we add service contents..
|
# First we add service contents..
|
||||||
zip_file.writestr(service_file_name, service_content)
|
zip_file.writestr(service_file_name, service_content)
|
||||||
# Finally add all the listed media files.
|
# Finally add all the listed media files.
|
||||||
@ -597,37 +597,23 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
|
|||||||
# When items are saved, they get new unique_identifier. Let's copy the file to the new location.
|
# When items are saved, they get new unique_identifier. Let's copy the file to the new location.
|
||||||
# Unused files can be ignored, OpenLP automatically cleans up the service manager dir on exit.
|
# Unused files can be ignored, OpenLP automatically cleans up the service manager dir on exit.
|
||||||
audio_from = os.path.join(self.service_path, audio_from)
|
audio_from = os.path.join(self.service_path, audio_from)
|
||||||
save_file = os.path.join(self.service_path, audio_to)
|
|
||||||
save_path = os.path.split(save_file)[0]
|
|
||||||
create_paths(Path(save_path))
|
|
||||||
if not os.path.exists(save_file):
|
|
||||||
shutil.copy(audio_from, save_file)
|
|
||||||
zip_file.write(audio_from, audio_to)
|
zip_file.write(audio_from, audio_to)
|
||||||
except OSError:
|
with suppress(FileNotFoundError):
|
||||||
self.log_exception('Failed to save service to disk: {name}'.format(name=temp_file_name))
|
file_path.unlink()
|
||||||
self.main_window.error_message(translate('OpenLP.ServiceManager', 'Error Saving File'),
|
os.link(temp_file.name, file_path)
|
||||||
translate('OpenLP.ServiceManager', 'There was an error saving your file.'))
|
except (PermissionError, OSError) as error:
|
||||||
success = False
|
self.log_exception('Failed to save service to disk: {name}'.format(name=temp_file.name))
|
||||||
finally:
|
self.main_window.error_message(
|
||||||
if zip_file:
|
translate('OpenLP.ServiceManager', 'Error Saving File'),
|
||||||
zip_file.close()
|
translate('OpenLP.ServiceManager', 'There was an error saving your file.\n\n{error}').format(error=error))
|
||||||
|
return self.save_file_as()
|
||||||
|
|
||||||
|
|
||||||
self.main_window.finished_progress_bar()
|
self.main_window.finished_progress_bar()
|
||||||
self.application.set_normal_cursor()
|
self.application.set_normal_cursor()
|
||||||
if success:
|
self.main_window.add_recent_file(file_path)
|
||||||
try:
|
|
||||||
shutil.copy(temp_file_name, path_file_name)
|
|
||||||
except (shutil.Error, PermissionError):
|
|
||||||
return self.save_file_as()
|
|
||||||
except OSError as ose:
|
|
||||||
QtWidgets.QMessageBox.critical(self, translate('OpenLP.ServiceManager', 'Error Saving File'),
|
|
||||||
translate('OpenLP.ServiceManager', 'An error occurred while writing the '
|
|
||||||
'service file: {error}').format(error=ose.strerror),
|
|
||||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
|
|
||||||
success = False
|
|
||||||
self.main_window.add_recent_file(path_file_name)
|
|
||||||
self.set_modified(False)
|
self.set_modified(False)
|
||||||
delete_file(Path(temp_file_name))
|
return True
|
||||||
return success
|
|
||||||
|
|
||||||
def save_local_file(self):
|
def save_local_file(self):
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user