Finally merge the save lite method in to the 'standard' save method'

This commit is contained in:
Phill Ridout 2018-01-06 09:55:19 +00:00
parent a1ea35c4e7
commit e1400dc227
3 changed files with 75 additions and 172 deletions

View File

@ -427,13 +427,8 @@ class ServiceItem(RegistryProperties):
self.has_original_files = True self.has_original_files = True
if 'background_audio' in header: if 'background_audio' in header:
self.background_audio = [] self.background_audio = []
for filename in header['background_audio']: for file_path in header['background_audio']:
# Give them real file paths. self.background_audio.append(file_path)
filepath = str(filename)
if path:
# Windows can handle both forward and backward slashes, so we use ntpath to get the basename
filepath = os.path.join(path, ntpath.basename(str(filename)))
self.background_audio.append(filepath)
self.theme_overwritten = header.get('theme_overwritten', False) self.theme_overwritten = header.get('theme_overwritten', False)
if self.service_item_type == ServiceItemType.Text: if self.service_item_type == ServiceItemType.Text:
for slide in service_item['serviceitem']['data']: for slide in service_item['serviceitem']['data']:

View File

@ -1382,4 +1382,4 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
if not isinstance(filename, str): if not isinstance(filename, str):
filename = str(filename, sys.getfilesystemencoding()) filename = str(filename, sys.getfilesystemencoding())
if filename.endswith(('.osz', '.oszl')): if filename.endswith(('.osz', '.oszl')):
self.service_manager_contents.load_file(filename) self.service_manager_contents.load_file(Path(filename))

View File

@ -43,6 +43,7 @@ from openlp.core.common.path import Path, create_paths, str_to_path
from openlp.core.common.registry import Registry, RegistryBase from openlp.core.common.registry import Registry, RegistryBase
from openlp.core.common.settings import Settings from openlp.core.common.settings import Settings
from openlp.core.lib import ServiceItem, ItemCapabilities, PluginStatus, build_icon from openlp.core.lib import ServiceItem, ItemCapabilities, PluginStatus, build_icon
from openlp.core.lib.exceptions import ValidationError
from openlp.core.lib.ui import critical_error_message_box, create_widget_action, find_and_set_in_combo_box from openlp.core.lib.ui import critical_error_message_box, create_widget_action, find_and_set_in_combo_box
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
from openlp.core.widgets.dialogs import FileDialog from openlp.core.widgets.dialogs import FileDialog
@ -451,7 +452,7 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
else: else:
file_path = str_to_path(load_file) file_path = str_to_path(load_file)
Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', file_path.parent) Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', file_path.parent)
self.load_file(str(file_path)) self.load_file(file_path)
def save_modified_service(self): def save_modified_service(self):
""" """
@ -477,7 +478,7 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
elif result == QtWidgets.QMessageBox.Save: elif result == QtWidgets.QMessageBox.Save:
self.decide_save_method() self.decide_save_method()
sender = self.sender() sender = self.sender()
self.load_file(sender.data()) self.load_file(Path(sender.data()))
def new_file(self): def new_file(self):
""" """
@ -509,8 +510,7 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
write_list = [] write_list = []
missing_list = [] missing_list = []
for item in self.service_items: for item in self.service_items:
if not item['service_item'].uses_file(): if item['service_item'].uses_file():
continue
for frame in item['service_item'].get_frames(): for frame in item['service_item'].get_frames():
path_from = item['service_item'].get_frame_path(frame=frame) path_from = item['service_item'].get_frame_path(frame=frame)
if path_from in write_list or path_from in missing_list: if path_from in write_list or path_from in missing_list:
@ -519,6 +519,10 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
missing_list.append(Path(path_from)) missing_list.append(Path(path_from))
else: else:
write_list.append(Path(path_from)) write_list.append(Path(path_from))
for audio_path in item['service_item'].background_audio:
if audio_path in write_list:
continue
write_list.append(audio_path)
return write_list, missing_list return write_list, missing_list
def save_file(self): def save_file(self):
@ -531,15 +535,14 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
""" """
file_path = self.file_name() file_path = self.file_name()
self.log_debug('ServiceManager.save_file - {name}'.format(name=file_path)) self.log_debug('ServiceManager.save_file - {name}'.format(name=file_path))
service_file_name = '{name}.osj'.format(name=file_path.suffix)
self.application.set_busy_cursor() self.application.set_busy_cursor()
service = self.create_basic_service() service = self.create_basic_service()
write_list = []
missing_list = []
# Get list of missing files, and list of files to write if not self._save_lite:
write_list, missing_list = self.get_write_file_list() write_list, missing_list = self.get_write_file_list()
if missing_list: if missing_list:
@ -550,20 +553,19 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
'These files will be removed if you continue to save.' 'These files will be removed if you continue to save.'
).format(name='\n\t'.join(missing_list)) ).format(name='\n\t'.join(missing_list))
answer = QtWidgets.QMessageBox.critical(self, title, message, answer = QtWidgets.QMessageBox.critical(self, title, message,
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.StandardButtons(
QtWidgets.QMessageBox.Cancel)) QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel))
if answer == QtWidgets.QMessageBox.Cancel: if answer == QtWidgets.QMessageBox.Cancel:
return False return False
# Check if item contains a missing file. # Check if item contains a missing file.
for item in list(self.service_items): for item in list(self.service_items):
self.main_window.increment_progress_bar() if not self._save_lite:
item['service_item'].remove_invalid_frames(missing_list) item['service_item'].remove_invalid_frames(missing_list)
if item['service_item'].missing_frames(): if item['service_item'].missing_frames():
self.service_items.remove(item) self.service_items.remove(item)
continue continue
service_item = item['service_item'].get_service_repr(self._save_lite) service_item = item['service_item'].get_service_repr(self._save_lite)
for audio_path in service_item['header']['background_audio']:
write_list.append(audio_path)
# 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)
@ -582,7 +584,7 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
with NamedTemporaryFile() as temp_file, \ with NamedTemporaryFile() as temp_file, \
zipfile.ZipFile(temp_file, 'w') as zip_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_data.osj', service_content)
# Finally add all the listed media files. # Finally add all the listed media files.
for write_from in write_list: for write_from in write_list:
zip_file.write(write_from, write_from) zip_file.write(write_from, write_from)
@ -604,61 +606,6 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
self.set_modified(False) self.set_modified(False)
return True return True
def save_local_file(self):
"""
Save the current service file but leave all the file references alone to point to the current machine.
This format is not transportable as it will not contain any files.
"""
if not self.file_name():
return self.save_file_as()
temp_file, temp_file_name = mkstemp('.oszl', '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()
self.application.set_busy_cursor()
# Number of items + 1 to zip it
self.main_window.display_progress_bar(len(self.service_items) + 1)
for item in self.service_items:
self.main_window.increment_progress_bar()
service_item = item['service_item'].get_service_repr(self._save_lite)
# TODO: check for file item on save.
service.append({'serviceitem': service_item})
self.main_window.increment_progress_bar()
service_content = json.dumps(service)
zip_file = None
success = True
self.main_window.increment_progress_bar()
try:
zip_file = zipfile.ZipFile(temp_file_name, 'w', zipfile.ZIP_STORED, True)
# First we add service contents.
zip_file.writestr(service_file_name, service_content)
except OSError:
self.log_exception('Failed to save service to disk: {name}'.format(name=temp_file_name))
self.main_window.error_message(translate('OpenLP.ServiceManager', 'Error Saving File'),
translate('OpenLP.ServiceManager', 'There was an error saving your file.'))
success = False
finally:
if zip_file:
zip_file.close()
self.main_window.finished_progress_bar()
self.application.set_normal_cursor()
if success:
try:
shutil.copy(temp_file_name, path_file_name)
except (shutil.Error, PermissionError):
return self.save_file_as()
self.main_window.add_recent_file(path_file_name)
self.set_modified(False)
delete_file(Path(temp_file_name))
return success
def save_file_as(self, field=None): def save_file_as(self, field=None):
""" """
Get a file name and then call :func:`ServiceManager.save_file` to save the file. Get a file name and then call :func:`ServiceManager.save_file` to save the file.
@ -718,87 +665,47 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
""" """
if not self.file_name(): if not self.file_name():
return self.save_file_as() return self.save_file_as()
if self._save_lite:
return self.save_local_file()
else:
return self.save_file() return self.save_file()
def load_file(self, file_name): def load_file(self, file_path):
""" """
Load an existing service file Load an existing service file
:param file_name: :param file_path:
""" """
if not file_name: if not file_path.exists():
return False return False
file_name = str(file_name) service_data = None
if not os.path.exists(file_name):
return False
zip_file = None
file_to = None
self.application.set_busy_cursor() self.application.set_busy_cursor()
try: try:
zip_file = zipfile.ZipFile(file_name) with zipfile.ZipFile(str(file_path)) as zip_file:
for zip_info in zip_file.infolist(): for zip_info in zip_file.infolist():
try: self.log_debug('Extract file: {name}'.format(name=zip_info.filename))
ucs_file = zip_info.filename # The json file has been called 'service_data.osj' since OpenLP 3.0
except UnicodeDecodeError: if zip_info.filename == 'service_data.osj' or zip_info.filename.endswith('osj'):
self.log_exception('file_name "{name}" is not valid UTF-8'.format(name=zip_info.file_name)) with zip_file.open(zip_info, 'r') as json_file:
critical_error_message_box(message=translate('OpenLP.ServiceManager', service_data = json_file.read()
'File is not a valid service.\n The content encoding is not UTF-8.'))
continue
os_file = ucs_file.replace('/', os.path.sep)
os_file = os.path.basename(os_file)
self.log_debug('Extract file: {name}'.format(name=os_file))
zip_info.filename = os_file
zip_file.extract(zip_info, self.service_path)
if os_file.endswith('osj') or os_file.endswith('osd'):
p_file = os.path.join(self.service_path, os_file)
if 'p_file' in locals():
file_to = open(p_file, 'r')
if p_file.endswith('osj'):
items = json.load(file_to, cls=OpenLPJsonDecoder)
else: else:
critical_error_message_box(message=translate('OpenLP.ServiceManager', zip_info.filename = os.path.basename(zip_info.filename)
'The service file you are trying to open is in an old ' zip_file.extract(zip_info, str(self.service_path))
'format.\n Please save it using OpenLP 2.0.2 or ' if service_data:
'greater.')) items = json.loads(service_data, cls=OpenLPJsonDecoder)
return
file_to.close()
self.new_file() self.new_file()
self.set_file_name(str_to_path(file_name))
self.main_window.display_progress_bar(len(items))
self.process_service_items(items) self.process_service_items(items)
delete_file(Path(p_file)) self.set_file_name(file_path)
self.main_window.add_recent_file(file_name) self.main_window.display_progress_bar(len(items))
self.main_window.add_recent_file(file_path)
self.set_modified(False) self.set_modified(False)
Settings().setValue('servicemanager/last file', Path(file_name)) Settings().setValue('servicemanager/last file', file_path)
else: else:
critical_error_message_box(message=translate('OpenLP.ServiceManager', 'File is not a valid service.')) raise ValidationError(msg='No service data found')
self.log_error('File contains no service data') except (NameError, OSError, ValidationError, zipfile.BadZipFile) as e:
except (OSError, NameError): self.log_exception('Problem loading service file {name}'.format(name=file_path))
self.log_exception('Problem loading service file {name}'.format(name=file_name)) critical_error_message_box(
critical_error_message_box(message=translate('OpenLP.ServiceManager', message=translate('OpenLP.ServiceManager',
'File could not be opened because it is corrupt.')) 'The service file {file_path} could not be loaded because it is either corrupt, or '
except zipfile.BadZipFile: 'not a valid OpenLP 2 or OpenLP 3 service file.'.format(file_path=file_path)))
if os.path.getsize(file_name) == 0:
self.log_exception('Service file is zero sized: {name}'.format(name=file_name))
QtWidgets.QMessageBox.information(self, translate('OpenLP.ServiceManager', 'Empty File'),
translate('OpenLP.ServiceManager',
'This service file does not contain '
'any data.'))
else:
self.log_exception('Service file is cannot be extracted as zip: {name}'.format(name=file_name))
QtWidgets.QMessageBox.information(self, translate('OpenLP.ServiceManager', 'Corrupt File'),
translate('OpenLP.ServiceManager',
'This file is either corrupt or it is not an OpenLP 2 '
'service file.'))
self.application.set_normal_cursor() self.application.set_normal_cursor()
return return
finally:
if file_to:
file_to.close()
if zip_file:
zip_file.close()
self.main_window.finished_progress_bar() self.main_window.finished_progress_bar()
self.application.set_normal_cursor() self.application.set_normal_cursor()
self.repaint_service_list(-1, -1) self.repaint_service_list(-1, -1)
@ -813,7 +720,8 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
self.main_window.increment_progress_bar() self.main_window.increment_progress_bar()
service_item = ServiceItem() service_item = ServiceItem()
if 'openlp_core' in item: if 'openlp_core' in item:
item = item.get('openlp_core') item = item['openlp_core']
self._save_lite = item.get('lite-service', False)
theme = item.get('service-theme', None) theme = item.get('service-theme', None)
if theme: if theme:
find_and_set_in_combo_box(self.theme_combo_box, theme, set_missing=False) find_and_set_in_combo_box(self.theme_combo_box, theme, set_missing=False)
@ -836,9 +744,9 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
Load the last service item from the service manager when the service was last closed. Can be blank if there was Load the last service item from the service manager when the service was last closed. Can be blank if there was
no service present. no service present.
""" """
file_name = str_to_path(Settings().value('servicemanager/last file')) file_path = Settings().value('servicemanager/last file')
if file_name: if file_path:
self.load_file(file_name) self.load_file(file_path)
def context_menu(self, point): def context_menu(self, point):
""" """