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
if 'background_audio' in header:
self.background_audio = []
for filename in header['background_audio']:
# Give them real file paths.
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)
for file_path in header['background_audio']:
self.background_audio.append(file_path)
self.theme_overwritten = header.get('theme_overwritten', False)
if self.service_item_type == ServiceItemType.Text:
for slide in service_item['serviceitem']['data']:
@ -538,7 +533,7 @@ class ServiceItem(RegistryProperties):
Confirms if the ServiceItem uses a file
"""
return self.service_item_type == ServiceItemType.Image or \
(self.service_item_type == ServiceItemType.Command and not self.is_capable(ItemCapabilities.IsOptical))
(self.service_item_type == ServiceItemType.Command and not self.is_capable(ItemCapabilities.IsOptical))
def is_text(self):
"""

View File

@ -1382,4 +1382,4 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
if not isinstance(filename, str):
filename = str(filename, sys.getfilesystemencoding())
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.settings import Settings
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.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
from openlp.core.widgets.dialogs import FileDialog
@ -451,7 +452,7 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
else:
file_path = str_to_path(load_file)
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):
"""
@ -477,7 +478,7 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
elif result == QtWidgets.QMessageBox.Save:
self.decide_save_method()
sender = self.sender()
self.load_file(sender.data())
self.load_file(Path(sender.data()))
def new_file(self):
"""
@ -509,16 +510,19 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
write_list = []
missing_list = []
for item in self.service_items:
if not item['service_item'].uses_file():
continue
for frame in item['service_item'].get_frames():
path_from = item['service_item'].get_frame_path(frame=frame)
if path_from in write_list or path_from in missing_list:
if item['service_item'].uses_file():
for frame in item['service_item'].get_frames():
path_from = item['service_item'].get_frame_path(frame=frame)
if path_from in write_list or path_from in missing_list:
continue
if not os.path.exists(path_from):
missing_list.append(Path(path_from))
else:
write_list.append(Path(path_from))
for audio_path in item['service_item'].background_audio:
if audio_path in write_list:
continue
if not os.path.exists(path_from):
missing_list.append(Path(path_from))
else:
write_list.append(Path(path_from))
write_list.append(audio_path)
return write_list, missing_list
def save_file(self):
@ -531,39 +535,37 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
"""
file_path = self.file_name()
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()
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:
self.application.set_normal_cursor()
title = translate('OpenLP.ServiceManager', 'Service File(s) Missing')
message = translate('OpenLP.ServiceManager',
'The following file(s) in the service are missing: {name}\n\n'
'These files will be removed if you continue to save.'
).format(name='\n\t'.join(missing_list))
answer = QtWidgets.QMessageBox.critical(self, title, message,
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok |
QtWidgets.QMessageBox.Cancel))
if answer == QtWidgets.QMessageBox.Cancel:
return False
if missing_list:
self.application.set_normal_cursor()
title = translate('OpenLP.ServiceManager', 'Service File(s) Missing')
message = translate('OpenLP.ServiceManager',
'The following file(s) in the service are missing: {name}\n\n'
'These files will be removed if you continue to save.'
).format(name='\n\t'.join(missing_list))
answer = QtWidgets.QMessageBox.critical(self, title, message,
QtWidgets.QMessageBox.StandardButtons(
QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel))
if answer == QtWidgets.QMessageBox.Cancel:
return False
# Check if item contains a missing file.
for item in list(self.service_items):
self.main_window.increment_progress_bar()
item['service_item'].remove_invalid_frames(missing_list)
if item['service_item'].missing_frames():
self.service_items.remove(item)
continue
if not self._save_lite:
item['service_item'].remove_invalid_frames(missing_list)
if item['service_item'].missing_frames():
self.service_items.remove(item)
continue
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.
service.append({'serviceitem': service_item})
self.repaint_service_list(-1, -1)
@ -582,7 +584,7 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
with NamedTemporaryFile() as temp_file, \
zipfile.ZipFile(temp_file, 'w') as zip_file:
# 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.
for write_from in write_list:
zip_file.write(write_from, write_from)
@ -604,61 +606,6 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
self.set_modified(False)
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):
"""
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():
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
:param file_name:
:param file_path:
"""
if not file_name:
if not file_path.exists():
return False
file_name = str(file_name)
if not os.path.exists(file_name):
return False
zip_file = None
file_to = None
service_data = None
self.application.set_busy_cursor()
try:
zip_file = zipfile.ZipFile(file_name)
for zip_info in zip_file.infolist():
try:
ucs_file = zip_info.filename
except UnicodeDecodeError:
self.log_exception('file_name "{name}" is not valid UTF-8'.format(name=zip_info.file_name))
critical_error_message_box(message=translate('OpenLP.ServiceManager',
'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:
critical_error_message_box(message=translate('OpenLP.ServiceManager',
'The service file you are trying to open is in an old '
'format.\n Please save it using OpenLP 2.0.2 or '
'greater.'))
return
file_to.close()
with zipfile.ZipFile(str(file_path)) as zip_file:
for zip_info in zip_file.infolist():
self.log_debug('Extract file: {name}'.format(name=zip_info.filename))
# The json file has been called 'service_data.osj' since OpenLP 3.0
if zip_info.filename == 'service_data.osj' or zip_info.filename.endswith('osj'):
with zip_file.open(zip_info, 'r') as json_file:
service_data = json_file.read()
else:
zip_info.filename = os.path.basename(zip_info.filename)
zip_file.extract(zip_info, str(self.service_path))
if service_data:
items = json.loads(service_data, cls=OpenLPJsonDecoder)
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)
delete_file(Path(p_file))
self.main_window.add_recent_file(file_name)
self.set_file_name(file_path)
self.main_window.display_progress_bar(len(items))
self.main_window.add_recent_file(file_path)
self.set_modified(False)
Settings().setValue('servicemanager/last file', Path(file_name))
Settings().setValue('servicemanager/last file', file_path)
else:
critical_error_message_box(message=translate('OpenLP.ServiceManager', 'File is not a valid service.'))
self.log_error('File contains no service data')
except (OSError, NameError):
self.log_exception('Problem loading service file {name}'.format(name=file_name))
critical_error_message_box(message=translate('OpenLP.ServiceManager',
'File could not be opened because it is corrupt.'))
except zipfile.BadZipFile:
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.'))
raise ValidationError(msg='No service data found')
except (NameError, OSError, ValidationError, zipfile.BadZipFile) as e:
self.log_exception('Problem loading service file {name}'.format(name=file_path))
critical_error_message_box(
message=translate('OpenLP.ServiceManager',
'The service file {file_path} could not be loaded because it is either corrupt, or '
'not a valid OpenLP 2 or OpenLP 3 service file.'.format(file_path=file_path)))
self.application.set_normal_cursor()
return
finally:
if file_to:
file_to.close()
if zip_file:
zip_file.close()
self.main_window.finished_progress_bar()
self.application.set_normal_cursor()
self.repaint_service_list(-1, -1)
@ -813,7 +720,8 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
self.main_window.increment_progress_bar()
service_item = ServiceItem()
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)
if theme:
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
no service present.
"""
file_name = str_to_path(Settings().value('servicemanager/last file'))
if file_name:
self.load_file(file_name)
file_path = Settings().value('servicemanager/last file')
if file_path:
self.load_file(file_path)
def context_menu(self, point):
"""