From 37be7e2ef11b707d2b81e26a2daaaec14421c35d Mon Sep 17 00:00:00 2001 From: Phill Ridout Date: Tue, 13 Jan 2015 21:28:55 +0000 Subject: [PATCH 01/11] fix images with same name getting same thumbnail --- openlp/plugins/images/lib/mediaitem.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index c8d9493c6..b29536e7a 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -345,7 +345,8 @@ class ImageMediaItem(MediaManagerItem): for imageFile in images: log.debug('Loading image: %s', imageFile.filename) filename = os.path.split(imageFile.filename)[1] - thumb = os.path.join(self.service_path, filename) + ext = os.path.splitext(imageFile.filename)[1].lower() + thumb = os.path.join(self.service_path, "%s%s" % (str(imageFile.id), ext)) if not os.path.exists(imageFile.filename): icon = build_icon(':/general/general_delete.png') else: From b4eb42fed251e66f15c6e5d1af012f0011259786 Mon Sep 17 00:00:00 2001 From: Phill Ridout Date: Fri, 16 Jan 2015 22:13:10 +0000 Subject: [PATCH 02/11] remove old thumbnails --- openlp/plugins/images/imageplugin.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openlp/plugins/images/imageplugin.py b/openlp/plugins/images/imageplugin.py index 911ee0216..4c39863aa 100644 --- a/openlp/plugins/images/imageplugin.py +++ b/openlp/plugins/images/imageplugin.py @@ -30,6 +30,7 @@ from PyQt4 import QtGui import logging +import os from openlp.core.common import Registry, Settings, translate from openlp.core.lib import Plugin, StringContent, ImageSource, build_icon @@ -77,6 +78,13 @@ class ImagePlugin(Plugin): # Convert old settings-based image list to the database. files_from_config = Settings().get_files_from_config(self) if files_from_config: + for file in files_from_config: + filename = os.path.split(file)[1] + thumb = os.path.join(self.media_item.service_path, filename) + try: + os.remove(thumb) + except: + pass log.debug('Importing images list from old config: %s' % files_from_config) self.media_item.save_new_images_list(files_from_config) From 4d749a89ac236eb9d3b2233e67c1a43afb7071f8 Mon Sep 17 00:00:00 2001 From: Phill Ridout Date: Tue, 20 Jan 2015 21:56:05 +0000 Subject: [PATCH 03/11] Presentation fixes --- openlp/core/lib/mediamanageritem.py | 3 +-- openlp/plugins/images/imageplugin.py | 2 ++ openlp/plugins/presentations/lib/mediaitem.py | 11 +++++++---- .../lib/presentationcontroller.py | 15 ++++++++++++--- .../presentations/presentationplugin.py | 18 ++++++++++++++++-- 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index f9f567773..9edba75da 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -373,8 +373,7 @@ s duplicates_found = False files_added = False for file_path in files: - filename = os.path.split(str(file_path))[1] - if filename in names: + if file_path in full_list: duplicates_found = True else: files_added = True diff --git a/openlp/plugins/images/imageplugin.py b/openlp/plugins/images/imageplugin.py index 4c39863aa..04cd8c952 100644 --- a/openlp/plugins/images/imageplugin.py +++ b/openlp/plugins/images/imageplugin.py @@ -74,6 +74,7 @@ class ImagePlugin(Plugin): """ Perform tasks on application startup. """ + # TODO: Can be removed when the upgrade path from 2.0.x to 2.2.x is no longer needed Plugin.app_startup(self) # Convert old settings-based image list to the database. files_from_config = Settings().get_files_from_config(self) @@ -94,6 +95,7 @@ class ImagePlugin(Plugin): :param settings: The Settings object containing the old settings. """ + # TODO: Can be removed when the upgrade path from 2.0.x to 2.2.x is no longer needed files_from_config = settings.get_files_from_config(self) if files_from_config: log.debug('Importing images list from old config: %s' % files_from_config) diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index 42cd92b81..154e668be 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -229,16 +229,19 @@ class PresentationMediaItem(MediaManagerItem): self.main_window.display_progress_bar(len(row_list)) for item in items: filepath = str(item.data(QtCore.Qt.UserRole)) - for cidx in self.controllers: - doc = self.controllers[cidx].add_document(filepath) - doc.presentation_deleted() - doc.close_presentation() + self.delete_presentation(filepath) self.main_window.increment_progress_bar() self.main_window.finished_progress_bar() self.application.set_busy_cursor() for row in row_list: self.list_view.takeItem(row) Settings().setValue(self.settings_section + '/presentations files', self.get_file_list()) + + def delete_presentation(self, filepath): + for cidx in self.controllers: + doc = self.controllers[cidx].add_document(filepath) + doc.presentation_deleted() + doc.close_presentation() def generate_slide_data(self, service_item, item=None, xml_version=False, remote=False, context=ServiceItemContext.Service, presentation_file=None): diff --git a/openlp/plugins/presentations/lib/presentationcontroller.py b/openlp/plugins/presentations/lib/presentationcontroller.py index 977a9ae84..f56827b3d 100644 --- a/openlp/plugins/presentations/lib/presentationcontroller.py +++ b/openlp/plugins/presentations/lib/presentationcontroller.py @@ -27,13 +27,14 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### +import hashlib import logging import os import shutil from PyQt4 import QtCore -from openlp.core.common import Registry, AppLocation, Settings, check_directory_exists +from openlp.core.common import Registry, AppLocation, Settings, check_directory_exists, md5_hash from openlp.core.lib import create_thumb, validate_thumb log = logging.getLogger(__name__) @@ -139,13 +140,21 @@ class PresentationDocument(object): """ The location where thumbnail images will be stored """ - return os.path.join(self.controller.thumbnail_folder, self.get_file_name()) + if Settings().value('presentations/thumbnail_scheme') == 'md5': + folder = md5_hash('', self.file_path) + else: + folder = self.get_file_name() + return os.path.join(self.controller.thumbnail_folder, folder) def get_temp_folder(self): """ The location where thumbnail images will be stored """ - return os.path.join(self.controller.temp_folder, self.get_file_name()) + if Settings().value('presentations/thumbnail_scheme') == 'md5': + folder = md5_hash('', self.file_path) + else: + folder = folder = self.get_file_name() + return os.path.join(self.controller.temp_folder, folder) def check_thumbnails(self): """ diff --git a/openlp/plugins/presentations/presentationplugin.py b/openlp/plugins/presentations/presentationplugin.py index b10df4fcf..706077781 100644 --- a/openlp/plugins/presentations/presentationplugin.py +++ b/openlp/plugins/presentations/presentationplugin.py @@ -35,7 +35,7 @@ import logging from PyQt4 import QtCore -from openlp.core.common import AppLocation, translate +from openlp.core.common import AppLocation, Settings, translate from openlp.core.lib import Plugin, StringContent, build_icon from openlp.plugins.presentations.lib import PresentationController, PresentationMediaItem, PresentationTab @@ -50,7 +50,8 @@ __default_settings__ = {'presentations/override app': QtCore.Qt.Unchecked, 'presentations/Powerpoint': QtCore.Qt.Checked, 'presentations/Powerpoint Viewer': QtCore.Qt.Checked, 'presentations/Pdf': QtCore.Qt.Checked, - 'presentations/presentations files': [] + 'presentations/presentations files': [], + 'presentations/thumbnail_scheme': '' } @@ -141,6 +142,19 @@ class PresentationPlugin(Plugin): self.register_controllers(controller) return bool(self.controllers) + def app_startup(self): + """ + Perform tasks on application startup. + """ + super().app_startup() + files_from_config = Settings().value('presentations/presentations files') + for file in files_from_config: + self.media_item.delete_presentation(file) + #Settings().setValue('presentations/presentations files', []) + self.media_item.list_view.clear() + Settings().setValue('presentations/thumbnail_scheme', 'md5') + self.media_item.validate_and_load(files_from_config) + def about(self): """ Return information about this plugin. From d6b8cd1d2af2dab9a8b03ee15d21572a66a6dce7 Mon Sep 17 00:00:00 2001 From: Phill Ridout Date: Thu, 22 Jan 2015 13:59:46 +0000 Subject: [PATCH 04/11] code tidies --- openlp/plugins/presentations/lib/mediaitem.py | 10 ++++++++-- .../presentations/lib/presentationcontroller.py | 3 ++- openlp/plugins/presentations/presentationplugin.py | 3 +-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index 154e668be..89133404d 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -229,7 +229,7 @@ class PresentationMediaItem(MediaManagerItem): self.main_window.display_progress_bar(len(row_list)) for item in items: filepath = str(item.data(QtCore.Qt.UserRole)) - self.delete_presentation(filepath) + self.clean_up_thumbnails(filepath) self.main_window.increment_progress_bar() self.main_window.finished_progress_bar() self.application.set_busy_cursor() @@ -237,7 +237,13 @@ class PresentationMediaItem(MediaManagerItem): self.list_view.takeItem(row) Settings().setValue(self.settings_section + '/presentations files', self.get_file_list()) - def delete_presentation(self, filepath): + def clean_up_thumbnails(self, filepath): + """ + Clean up the files created such as thumbnails + + :param filepath: File path of the presention to clean up after + :return: None + """ for cidx in self.controllers: doc = self.controllers[cidx].add_document(filepath) doc.presentation_deleted() diff --git a/openlp/plugins/presentations/lib/presentationcontroller.py b/openlp/plugins/presentations/lib/presentationcontroller.py index f56827b3d..0a7aecd60 100644 --- a/openlp/plugins/presentations/lib/presentationcontroller.py +++ b/openlp/plugins/presentations/lib/presentationcontroller.py @@ -27,7 +27,6 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### -import hashlib import logging import os import shutil @@ -140,6 +139,7 @@ class PresentationDocument(object): """ The location where thumbnail images will be stored """ + # TODO: If statment can be removed when the upgrade path from 2.0.x to 2.2.x is no longer needed if Settings().value('presentations/thumbnail_scheme') == 'md5': folder = md5_hash('', self.file_path) else: @@ -150,6 +150,7 @@ class PresentationDocument(object): """ The location where thumbnail images will be stored """ + # TODO: If statment can be removed when the upgrade path from 2.0.x to 2.2.x is no longer needed if Settings().value('presentations/thumbnail_scheme') == 'md5': folder = md5_hash('', self.file_path) else: diff --git a/openlp/plugins/presentations/presentationplugin.py b/openlp/plugins/presentations/presentationplugin.py index 706077781..0b2faed36 100644 --- a/openlp/plugins/presentations/presentationplugin.py +++ b/openlp/plugins/presentations/presentationplugin.py @@ -149,8 +149,7 @@ class PresentationPlugin(Plugin): super().app_startup() files_from_config = Settings().value('presentations/presentations files') for file in files_from_config: - self.media_item.delete_presentation(file) - #Settings().setValue('presentations/presentations files', []) + self.media_item.clean_up_thumbnails(file) self.media_item.list_view.clear() Settings().setValue('presentations/thumbnail_scheme', 'md5') self.media_item.validate_and_load(files_from_config) From 833c6fb80096cb986820d4165e700e1278b215d9 Mon Sep 17 00:00:00 2001 From: Phill Ridout Date: Thu, 22 Jan 2015 15:05:03 +0000 Subject: [PATCH 05/11] Add test --- openlp/core/__init__.py | 39 ++++++++++++------- .../presentations/presentationplugin.py | 1 + tests/functional/test_init.py | 17 +++++++- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index 5f4d0eb24..7987ae823 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -269,6 +269,29 @@ class OpenLP(OpenLPMixin, QtGui.QApplication): else: return QtGui.QApplication.event(self, event) +def parse_options(args): + """ + Parse the command line arguments + + :param args: list of command line arguments + :return: a tuple of parsed options of type optparse.Value and a list of remaining argsZ + """ + print(args) + print(sys.argv) + # Set up command line options. + usage = 'Usage: %prog [options] [qt-options]' + parser = OptionParser(usage=usage) + parser.add_option('-e', '--no-error-form', dest='no_error_form', action='store_true', + help='Disable the error notification form.') + parser.add_option('-l', '--log-level', dest='loglevel', default='warning', metavar='LEVEL', + help='Set logging to LEVEL level. Valid values are "debug", "info", "warning".') + parser.add_option('-p', '--portable', dest='portable', action='store_true', + help='Specify if this should be run as a portable app, off a USB flash drive (not implemented).') + parser.add_option('-d', '--dev-version', dest='dev_version', action='store_true', + help='Ignore the version file and pull the version directly from Bazaar') + parser.add_option('-s', '--style', dest='style', help='Set the Qt4 style (passed directly to Qt4).') + # Parse command line options and deal with them. Use args supplied pragmatically if possible. + return parser.parse_args(args) if args else parser.parse_args() def set_up_logging(log_path): """ @@ -291,21 +314,7 @@ def main(args=None): :param args: Some args """ - # Set up command line options. - usage = 'Usage: %prog [options] [qt-options]' - parser = OptionParser(usage=usage) - parser.add_option('-e', '--no-error-form', dest='no_error_form', action='store_true', - help='Disable the error notification form.') - parser.add_option('-l', '--log-level', dest='loglevel', default='warning', metavar='LEVEL', - help='Set logging to LEVEL level. Valid values are "debug", "info", "warning".') - parser.add_option('-p', '--portable', dest='portable', action='store_true', - help='Specify if this should be run as a portable app, off a USB flash drive (not implemented).') - parser.add_option('-d', '--dev-version', dest='dev_version', action='store_true', - help='Ignore the version file and pull the version directly from Bazaar') - parser.add_option('-s', '--style', dest='style', help='Set the Qt4 style (passed directly to Qt4).') - # Parse command line options and deal with them. - # Use args supplied pragmatically if possible. - (options, args) = parser.parse_args(args) if args else parser.parse_args() + (options, args) = parse_options(args) qt_args = [] if options.loglevel.lower() in ['d', 'debug']: log.setLevel(logging.DEBUG) diff --git a/openlp/plugins/presentations/presentationplugin.py b/openlp/plugins/presentations/presentationplugin.py index 0b2faed36..21bb38b0d 100644 --- a/openlp/plugins/presentations/presentationplugin.py +++ b/openlp/plugins/presentations/presentationplugin.py @@ -146,6 +146,7 @@ class PresentationPlugin(Plugin): """ Perform tasks on application startup. """ + # TODO: Can be removed when the upgrade path from 2.0.x to 2.2.x is no longer needed super().app_startup() files_from_config = Settings().value('presentations/presentations files') for file in files_from_config: diff --git a/tests/functional/test_init.py b/tests/functional/test_init.py index 20751b832..ed3f62cf4 100644 --- a/tests/functional/test_init.py +++ b/tests/functional/test_init.py @@ -29,13 +29,14 @@ """ Package to test the openlp.core.__init__ package. """ +from optparse import Values import os from unittest import TestCase from unittest.mock import MagicMock, patch from PyQt4 import QtCore, QtGui -from openlp.core import OpenLP +from openlp.core import OpenLP, parse_options from openlp.core.common import Settings from tests.helpers.testmixin import TestMixin @@ -119,3 +120,17 @@ class TestInit(TestCase, TestMixin): # THEN: It should ask if we want to create a backup self.assertEqual(Settings().value('core/application version'), '2.2.0', 'Version should be upgraded!') self.assertEqual(mocked_question.call_count, 1, 'A question should have been asked!') + + def parse_options_short_options_test(self): + """ + Test that parse_options parses short options correctly + """ + # GIVEN: A list of vaild short options + options = ['-e', 'extra', '-l', 'debug', 'qt', '-pd', 'args', '-s', 'style'] + + # WHEN: Calling parse_options + resluts = parse_options(options) + + # THEN: A tuple should be returned with the parsed options and left over args + self.assertEqual(resluts, (Values({'no_error_form': True, 'dev_version': True, 'portable': True, + 'style': 'style', 'loglevel': 'debug'}),['extra', 'qt', 'args'])) From a64fdd86974ec574a12cd775fa3fab4179402a7a Mon Sep 17 00:00:00 2001 From: Phill Ridout Date: Thu, 22 Jan 2015 15:35:52 +0000 Subject: [PATCH 06/11] fix tests --- .../openlp_plugins/presentations/test_pdfcontroller.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py b/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py index 926f6e03c..c196bab67 100644 --- a/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py +++ b/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py @@ -43,7 +43,8 @@ from tests.utils.constants import TEST_RESOURCES_PATH from tests.helpers.testmixin import TestMixin __default_settings__ = { - 'presentations/enable_pdf_program': False + 'presentations/enable_pdf_program': False, + 'presentations/thumbnail_scheme': '' } SCREEN = { From 125f0194860e09786c3ee0198de928c333c184cb Mon Sep 17 00:00:00 2001 From: Phill Ridout Date: Thu, 22 Jan 2015 17:52:48 +0000 Subject: [PATCH 07/11] test fixes --- .../openlp_plugins/presentations/test_impresscontroller.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/functional/openlp_plugins/presentations/test_impresscontroller.py b/tests/functional/openlp_plugins/presentations/test_impresscontroller.py index 6409aaab0..62d79b0ad 100644 --- a/tests/functional/openlp_plugins/presentations/test_impresscontroller.py +++ b/tests/functional/openlp_plugins/presentations/test_impresscontroller.py @@ -31,8 +31,10 @@ from tests.functional import patch, MagicMock from tests.utils.constants import TEST_RESOURCES_PATH from tests.helpers.testmixin import TestMixin +from openlp.core.common import Settings from openlp.plugins.presentations.lib.impresscontroller import \ ImpressController, ImpressDocument, TextType +from openlp.plugins.presentations.presentationplugin import __default_settings__ class TestImpressController(TestCase, TestMixin): @@ -79,6 +81,7 @@ class TestImpressDocument(TestCase): def setUp(self): mocked_plugin = MagicMock() mocked_plugin.settings_section = 'presentations' + Settings().extend_default_settings(__default_settings__) self.file_name = os.path.join(TEST_RESOURCES_PATH, 'presentations', 'test.pptx') self.ppc = ImpressController(mocked_plugin) self.doc = ImpressDocument(self.ppc, self.file_name) From 854537b3e64d19b830ba860791099ee9d9ec4ccd Mon Sep 17 00:00:00 2001 From: Phill Ridout Date: Thu, 22 Jan 2015 18:01:54 +0000 Subject: [PATCH 08/11] PEP fix --- openlp/plugins/presentations/lib/mediaitem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index 7ac6ba42d..04553c375 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -229,7 +229,7 @@ class PresentationMediaItem(MediaManagerItem): for row in row_list: self.list_view.takeItem(row) Settings().setValue(self.settings_section + '/presentations files', self.get_file_list()) - + def clean_up_thumbnails(self, filepath): """ Clean up the files created such as thumbnails From 92eee52d3f2c92ca826bda39841c2d848ca51fc0 Mon Sep 17 00:00:00 2001 From: Phill Ridout Date: Thu, 22 Jan 2015 18:07:56 +0000 Subject: [PATCH 09/11] pep fixes --- openlp/core/__init__.py | 2 ++ tests/functional/test_init.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index 23ac813bd..6b2fefd6a 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -262,6 +262,7 @@ class OpenLP(OpenLPMixin, QtGui.QApplication): else: return QtGui.QApplication.event(self, event) + def parse_options(args): """ Parse the command line arguments @@ -286,6 +287,7 @@ def parse_options(args): # Parse command line options and deal with them. Use args supplied pragmatically if possible. return parser.parse_args(args) if args else parser.parse_args() + def set_up_logging(log_path): """ Setup our logging using log_path diff --git a/tests/functional/test_init.py b/tests/functional/test_init.py index 22fda5c50..6fc9aa651 100644 --- a/tests/functional/test_init.py +++ b/tests/functional/test_init.py @@ -126,4 +126,4 @@ class TestInit(TestCase, TestMixin): # THEN: A tuple should be returned with the parsed options and left over args self.assertEqual(resluts, (Values({'no_error_form': True, 'dev_version': True, 'portable': True, - 'style': 'style', 'loglevel': 'debug'}),['extra', 'qt', 'args'])) + 'style': 'style', 'loglevel': 'debug'}), ['extra', 'qt', 'args'])) From 14719b8ab36e93a7750363dd2c3c32eb247b7556 Mon Sep 17 00:00:00 2001 From: Phill Ridout Date: Thu, 22 Jan 2015 20:12:23 +0000 Subject: [PATCH 10/11] remove print statments --- openlp/core/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index 6b2fefd6a..a4a9d488e 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -270,8 +270,6 @@ def parse_options(args): :param args: list of command line arguments :return: a tuple of parsed options of type optparse.Value and a list of remaining argsZ """ - print(args) - print(sys.argv) # Set up command line options. usage = 'Usage: %prog [options] [qt-options]' parser = OptionParser(usage=usage) From 4a52a90a4edcc0f25092cf62f9c87ed6b6a35b33 Mon Sep 17 00:00:00 2001 From: Phill Ridout Date: Sat, 24 Jan 2015 10:21:13 +0000 Subject: [PATCH 11/11] test fix. Test options in order as per --help --- tests/functional/test_init.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/test_init.py b/tests/functional/test_init.py index 6fc9aa651..a5ec608ef 100644 --- a/tests/functional/test_init.py +++ b/tests/functional/test_init.py @@ -119,7 +119,7 @@ class TestInit(TestCase, TestMixin): Test that parse_options parses short options correctly """ # GIVEN: A list of vaild short options - options = ['-e', 'extra', '-l', 'debug', 'qt', '-pd', 'args', '-s', 'style'] + options = ['-e', '-l', 'debug', '-pd', '-s', 'style', 'extra', 'qt', 'args'] # WHEN: Calling parse_options resluts = parse_options(options)