forked from openlp/openlp
Fixes #1414585 Thumbnail of images isn't shown in stage view and remote control
and #1414585 2.1.2 Traceback on Presentations for MAC bzr-revno: 2494
This commit is contained in:
commit
cfa8e4f2df
@ -314,6 +314,16 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
return True
|
return True
|
||||||
return return_value
|
return return_value
|
||||||
|
|
||||||
|
def generate_thumbnail_path(self, image):
|
||||||
|
"""
|
||||||
|
Generate a path to the thumbnail
|
||||||
|
|
||||||
|
:param image: An instance of ImageFileNames
|
||||||
|
:return: A path to the thumbnail of type str
|
||||||
|
"""
|
||||||
|
ext = os.path.splitext(image.filename)[1].lower()
|
||||||
|
return os.path.join(self.service_path, '{}{}'.format(str(image.id), ext))
|
||||||
|
|
||||||
def load_full_list(self, images, initial_load=False, open_group=None):
|
def load_full_list(self, images, initial_load=False, open_group=None):
|
||||||
"""
|
"""
|
||||||
Replace the list of images and groups in the interface.
|
Replace the list of images and groups in the interface.
|
||||||
@ -335,27 +345,26 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
# Sort the images by its filename considering language specific.
|
# Sort the images by its filename considering language specific.
|
||||||
# characters.
|
# characters.
|
||||||
images.sort(key=lambda image_object: get_locale_key(os.path.split(str(image_object.filename))[1]))
|
images.sort(key=lambda image_object: get_locale_key(os.path.split(str(image_object.filename))[1]))
|
||||||
for imageFile in images:
|
for image_file in images:
|
||||||
log.debug('Loading image: %s', imageFile.filename)
|
log.debug('Loading image: %s', image_file.filename)
|
||||||
filename = os.path.split(imageFile.filename)[1]
|
filename = os.path.split(image_file.filename)[1]
|
||||||
ext = os.path.splitext(imageFile.filename)[1].lower()
|
thumb = self.generate_thumbnail_path(image_file)
|
||||||
thumb = os.path.join(self.service_path, "%s%s" % (str(imageFile.id), ext))
|
if not os.path.exists(image_file.filename):
|
||||||
if not os.path.exists(imageFile.filename):
|
|
||||||
icon = build_icon(':/general/general_delete.png')
|
icon = build_icon(':/general/general_delete.png')
|
||||||
else:
|
else:
|
||||||
if validate_thumb(imageFile.filename, thumb):
|
if validate_thumb(image_file.filename, thumb):
|
||||||
icon = build_icon(thumb)
|
icon = build_icon(thumb)
|
||||||
else:
|
else:
|
||||||
icon = create_thumb(imageFile.filename, thumb)
|
icon = create_thumb(image_file.filename, thumb)
|
||||||
item_name = QtGui.QTreeWidgetItem([filename])
|
item_name = QtGui.QTreeWidgetItem([filename])
|
||||||
item_name.setText(0, filename)
|
item_name.setText(0, filename)
|
||||||
item_name.setIcon(0, icon)
|
item_name.setIcon(0, icon)
|
||||||
item_name.setToolTip(0, imageFile.filename)
|
item_name.setToolTip(0, image_file.filename)
|
||||||
item_name.setData(0, QtCore.Qt.UserRole, imageFile)
|
item_name.setData(0, QtCore.Qt.UserRole, image_file)
|
||||||
if imageFile.group_id == 0:
|
if image_file.group_id == 0:
|
||||||
self.list_view.addTopLevelItem(item_name)
|
self.list_view.addTopLevelItem(item_name)
|
||||||
else:
|
else:
|
||||||
group_items[imageFile.group_id].addChild(item_name)
|
group_items[image_file.group_id].addChild(item_name)
|
||||||
if not initial_load:
|
if not initial_load:
|
||||||
self.main_window.increment_progress_bar()
|
self.main_window.increment_progress_bar()
|
||||||
if not initial_load:
|
if not initial_load:
|
||||||
@ -549,24 +558,24 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
# force a nonexistent theme
|
# force a nonexistent theme
|
||||||
service_item.theme = -1
|
service_item.theme = -1
|
||||||
missing_items_file_names = []
|
missing_items_file_names = []
|
||||||
images_file_names = []
|
images = []
|
||||||
# Expand groups to images
|
# Expand groups to images
|
||||||
for bitem in items:
|
for bitem in items:
|
||||||
if isinstance(bitem.data(0, QtCore.Qt.UserRole), ImageGroups) or bitem.data(0, QtCore.Qt.UserRole) is None:
|
if isinstance(bitem.data(0, QtCore.Qt.UserRole), ImageGroups) or bitem.data(0, QtCore.Qt.UserRole) is None:
|
||||||
for index in range(0, bitem.childCount()):
|
for index in range(0, bitem.childCount()):
|
||||||
if isinstance(bitem.child(index).data(0, QtCore.Qt.UserRole), ImageFilenames):
|
if isinstance(bitem.child(index).data(0, QtCore.Qt.UserRole), ImageFilenames):
|
||||||
images_file_names.append(bitem.child(index).data(0, QtCore.Qt.UserRole).filename)
|
images.append(bitem.child(index).data(0, QtCore.Qt.UserRole))
|
||||||
elif isinstance(bitem.data(0, QtCore.Qt.UserRole), ImageFilenames):
|
elif isinstance(bitem.data(0, QtCore.Qt.UserRole), ImageFilenames):
|
||||||
images_file_names.append(bitem.data(0, QtCore.Qt.UserRole).filename)
|
images.append(bitem.data(0, QtCore.Qt.UserRole))
|
||||||
# Don't try to display empty groups
|
# Don't try to display empty groups
|
||||||
if not images_file_names:
|
if not images:
|
||||||
return False
|
return False
|
||||||
# Find missing files
|
# Find missing files
|
||||||
for filename in images_file_names:
|
for image in images:
|
||||||
if not os.path.exists(filename):
|
if not os.path.exists(image.filename):
|
||||||
missing_items_file_names.append(filename)
|
missing_items_file_names.append(image.filename)
|
||||||
# We cannot continue, as all images do not exist.
|
# We cannot continue, as all images do not exist.
|
||||||
if not images_file_names:
|
if not images:
|
||||||
if not remote:
|
if not remote:
|
||||||
critical_error_message_box(
|
critical_error_message_box(
|
||||||
translate('ImagePlugin.MediaItem', 'Missing Image(s)'),
|
translate('ImagePlugin.MediaItem', 'Missing Image(s)'),
|
||||||
@ -582,9 +591,10 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
QtGui.QMessageBox.No:
|
QtGui.QMessageBox.No:
|
||||||
return False
|
return False
|
||||||
# Continue with the existing images.
|
# Continue with the existing images.
|
||||||
for filename in images_file_names:
|
for image in images:
|
||||||
name = os.path.split(filename)[1]
|
name = os.path.split(image.filename)[1]
|
||||||
service_item.add_from_image(filename, name, background, os.path.join(self.service_path, name))
|
thumbnail = self.generate_thumbnail_path(image)
|
||||||
|
service_item.add_from_image(image.filename, name, background, thumbnail)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def check_group_exists(self, new_group):
|
def check_group_exists(self, new_group):
|
||||||
|
@ -143,7 +143,10 @@ class PresentationPlugin(Plugin):
|
|||||||
super().app_startup()
|
super().app_startup()
|
||||||
files_from_config = Settings().value('presentations/presentations files')
|
files_from_config = Settings().value('presentations/presentations files')
|
||||||
for file in files_from_config:
|
for file in files_from_config:
|
||||||
self.media_item.clean_up_thumbnails(file)
|
try:
|
||||||
|
self.media_item.clean_up_thumbnails(file)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
self.media_item.list_view.clear()
|
self.media_item.list_view.clear()
|
||||||
Settings().setValue('presentations/thumbnail_scheme', 'md5')
|
Settings().setValue('presentations/thumbnail_scheme', 'md5')
|
||||||
self.media_item.validate_and_load(files_from_config)
|
self.media_item.validate_and_load(files_from_config)
|
||||||
|
@ -25,7 +25,7 @@ Functional tests to test the AppLocation class and related methods.
|
|||||||
import os
|
import os
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
from openlp.core.utils import clean_filename, get_filesystem_encoding, get_locale_key, \
|
from openlp.core.utils import clean_filename, delete_file, get_filesystem_encoding, get_locale_key, \
|
||||||
get_natural_key, split_filename, _get_user_agent, get_web_page, get_uno_instance, add_actions
|
get_natural_key, split_filename, _get_user_agent, get_web_page, get_uno_instance, add_actions
|
||||||
from tests.functional import MagicMock, patch
|
from tests.functional import MagicMock, patch
|
||||||
|
|
||||||
@ -184,6 +184,59 @@ class TestUtils(TestCase):
|
|||||||
# THEN: The file name should be cleaned.
|
# THEN: The file name should be cleaned.
|
||||||
self.assertEqual(wanted_name, result, 'The file name should not contain any special characters.')
|
self.assertEqual(wanted_name, result, 'The file name should not contain any special characters.')
|
||||||
|
|
||||||
|
def delete_file_no_path_test(self):
|
||||||
|
""""
|
||||||
|
Test the delete_file function when called with out a valid path
|
||||||
|
"""
|
||||||
|
# GIVEN: A blank path
|
||||||
|
# WEHN: Calling delete_file
|
||||||
|
result = delete_file('')
|
||||||
|
|
||||||
|
# THEN: delete_file should return False
|
||||||
|
self.assertFalse(result, "delete_file should return False when called with ''")
|
||||||
|
|
||||||
|
def delete_file_path_success_test(self):
|
||||||
|
""""
|
||||||
|
Test the delete_file function when it successfully deletes a file
|
||||||
|
"""
|
||||||
|
# GIVEN: A mocked os which returns True when os.path.exists is called
|
||||||
|
with patch('openlp.core.utils.os', **{'path.exists.return_value': False}):
|
||||||
|
|
||||||
|
# WHEN: Calling delete_file with a file path
|
||||||
|
result = delete_file('path/file.ext')
|
||||||
|
|
||||||
|
# THEN: delete_file should return True
|
||||||
|
self.assertTrue(result, 'delete_file should return True when it successfully deletes a file')
|
||||||
|
|
||||||
|
def delete_file_path_no_file_exists_test(self):
|
||||||
|
""""
|
||||||
|
Test the delete_file function when the file to remove does not exist
|
||||||
|
"""
|
||||||
|
# GIVEN: A mocked os which returns False when os.path.exists is called
|
||||||
|
with patch('openlp.core.utils.os', **{'path.exists.return_value': False}):
|
||||||
|
|
||||||
|
# WHEN: Calling delete_file with a file path
|
||||||
|
result = delete_file('path/file.ext')
|
||||||
|
|
||||||
|
# THEN: delete_file should return True
|
||||||
|
self.assertTrue(result, 'delete_file should return True when the file doesnt exist')
|
||||||
|
|
||||||
|
def delete_file_path_exception_test(self):
|
||||||
|
""""
|
||||||
|
Test the delete_file function when os.remove raises an exception
|
||||||
|
"""
|
||||||
|
# GIVEN: A mocked os which returns True when os.path.exists is called and raises an OSError when os.remove is
|
||||||
|
# called.
|
||||||
|
with patch('openlp.core.utils.os', **{'path.exists.return_value': True, 'path.exists.side_effect': OSError}), \
|
||||||
|
patch('openlp.core.utils.log') as mocked_log:
|
||||||
|
|
||||||
|
# WHEN: Calling delete_file with a file path
|
||||||
|
result = delete_file('path/file.ext')
|
||||||
|
|
||||||
|
# THEN: delete_file should log and exception and return False
|
||||||
|
self.assertEqual(mocked_log.exception.call_count, 1)
|
||||||
|
self.assertFalse(result, 'delete_file should return False when os.remove raises an OSError')
|
||||||
|
|
||||||
def get_locale_key_test(self):
|
def get_locale_key_test(self):
|
||||||
"""
|
"""
|
||||||
Test the get_locale_key(string) function
|
Test the get_locale_key(string) function
|
||||||
|
Loading…
Reference in New Issue
Block a user