From 63f08f0c4aba91196866aaeb5a78da99e075ad54 Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Mon, 18 Aug 2014 20:45:15 +0200 Subject: [PATCH 1/5] Fix ProPresenter import Fixes: https://launchpad.net/bugs/1358418 --- openlp/plugins/songs/lib/importer.py | 2 +- openlp/plugins/songs/lib/importers/__init__.py | 2 +- openlp/plugins/songs/lib/importers/propresenter.py | 11 ++++++++++- openlp/plugins/songs/lib/importers/songimport.py | 9 +++++++++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/openlp/plugins/songs/lib/importer.py b/openlp/plugins/songs/lib/importer.py index 0084a74de..9c17e1f67 100644 --- a/openlp/plugins/songs/lib/importer.py +++ b/openlp/plugins/songs/lib/importer.py @@ -292,7 +292,7 @@ class SongFormat(object): 'class': ProPresenterImport, 'name': 'ProPresenter', 'prefix': 'proPresenter', - 'filter': '%s (*.pro4)' % translate('SongsPlugin.ImportWizardForm', 'ProPresenter Song Files') + 'filter': '%s (*.pro4)' % translate('SongsPlugin.ImportWizardForm', 'ProPresenter 4 Song Files') }, SongBeamer: { 'class': SongBeamerImport, diff --git a/openlp/plugins/songs/lib/importers/__init__.py b/openlp/plugins/songs/lib/importers/__init__.py index da302572e..f86a3e95e 100644 --- a/openlp/plugins/songs/lib/importers/__init__.py +++ b/openlp/plugins/songs/lib/importers/__init__.py @@ -27,5 +27,5 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### """ -The :mod:`~openlp.plugins.songs.lib.import` module contains importers for the Songs plugin. +The :mod:`~openlp.plugins.songs.lib.importers` module contains importers for the Songs plugin. """ diff --git a/openlp/plugins/songs/lib/importers/propresenter.py b/openlp/plugins/songs/lib/importers/propresenter.py index 3bf7f9cd8..ca9a2e9c8 100644 --- a/openlp/plugins/songs/lib/importers/propresenter.py +++ b/openlp/plugins/songs/lib/importers/propresenter.py @@ -33,17 +33,20 @@ ProPresenter song files into the current installation database. import os import base64 +import logging from lxml import objectify from openlp.core.ui.wizard import WizardStrings from openlp.plugins.songs.lib import strip_rtf from .songimport import SongImport +log = logging.getLogger(__name__) + class ProPresenterImport(SongImport): """ The :class:`ProPresenterImport` class provides OpenLP with the - ability to import ProPresenter song files. + ability to import ProPresenter 4 song files. """ def do_import(self): self.import_wizard.progress_bar.setMaximum(len(self.import_source)) @@ -67,9 +70,15 @@ class ProPresenterImport(SongImport): count = 0 for slide in root.slides.RVDisplaySlide: count += 1 + if not hasattr(slide.displayElements, 'RVTextElement'): + log.debug('No text found, may be an image slide') + continue RTFData = slide.displayElements.RVTextElement.get('RTFData') rtf = base64.standard_b64decode(RTFData) words, encoding = strip_rtf(rtf.decode()) self.add_verse(words, "v%d" % count) + # Some songs don't have a title - use the first line as title + if not self.title: + self.title = self.guess_title() if not self.finish(): self.log_error(self.import_source) diff --git a/openlp/plugins/songs/lib/importers/songimport.py b/openlp/plugins/songs/lib/importers/songimport.py index 5382efbe5..14622e978 100644 --- a/openlp/plugins/songs/lib/importers/songimport.py +++ b/openlp/plugins/songs/lib/importers/songimport.py @@ -316,6 +316,15 @@ class SongImport(QtCore.QObject): self.verse_order_list_generated.append(self.verse_order_list_generated[-1]) self.verse_order_list_generated_useful = True + def guess_title(self): + """ + Guess the title from the first verse (to be used when the song has no title information) + :return: The guessed title + """ + if not self.verses: + return '' + return self.verses[0][1].split('\n')[0].strip() + def check_complete(self): """ Check the mandatory fields are entered (i.e. title and a verse) From 0bf256070a898317a88d0cfca8af6ca9aa16c3dd Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Mon, 18 Aug 2014 21:04:46 +0200 Subject: [PATCH 2/5] Add test --- .../songs/lib/importers/propresenter.py | 9 ++--- .../plugins/songs/lib/importers/songimport.py | 9 ----- .../songs/test_propresenterimport.py | 2 ++ .../propresentersongs/Vaste Grond.json | 34 +++++++++++++++++++ .../propresentersongs/Vaste Grond.pro4 | 1 + 5 files changed, 40 insertions(+), 15 deletions(-) create mode 100644 tests/resources/propresentersongs/Vaste Grond.json create mode 100644 tests/resources/propresentersongs/Vaste Grond.pro4 diff --git a/openlp/plugins/songs/lib/importers/propresenter.py b/openlp/plugins/songs/lib/importers/propresenter.py index ca9a2e9c8..b0509393b 100644 --- a/openlp/plugins/songs/lib/importers/propresenter.py +++ b/openlp/plugins/songs/lib/importers/propresenter.py @@ -55,11 +55,11 @@ class ProPresenterImport(SongImport): return self.import_wizard.increment_progress_bar(WizardStrings.ImportingType % os.path.basename(file_path)) root = objectify.parse(open(file_path, 'rb')).getroot() - self.process_song(root) + self.process_song(root, file_path) - def process_song(self, root): + def process_song(self, root, filename): self.set_defaults() - self.title = root.get('CCLISongTitle') + self.title = os.path.basename(filename).rstrip('.pro4') self.copyright = root.get('CCLICopyrightInfo') self.comments = root.get('notes') self.ccli_number = root.get('CCLILicenseNumber') @@ -77,8 +77,5 @@ class ProPresenterImport(SongImport): rtf = base64.standard_b64decode(RTFData) words, encoding = strip_rtf(rtf.decode()) self.add_verse(words, "v%d" % count) - # Some songs don't have a title - use the first line as title - if not self.title: - self.title = self.guess_title() if not self.finish(): self.log_error(self.import_source) diff --git a/openlp/plugins/songs/lib/importers/songimport.py b/openlp/plugins/songs/lib/importers/songimport.py index 14622e978..5382efbe5 100644 --- a/openlp/plugins/songs/lib/importers/songimport.py +++ b/openlp/plugins/songs/lib/importers/songimport.py @@ -316,15 +316,6 @@ class SongImport(QtCore.QObject): self.verse_order_list_generated.append(self.verse_order_list_generated[-1]) self.verse_order_list_generated_useful = True - def guess_title(self): - """ - Guess the title from the first verse (to be used when the song has no title information) - :return: The guessed title - """ - if not self.verses: - return '' - return self.verses[0][1].split('\n')[0].strip() - def check_complete(self): """ Check the mandatory fields are entered (i.e. title and a verse) diff --git a/tests/functional/openlp_plugins/songs/test_propresenterimport.py b/tests/functional/openlp_plugins/songs/test_propresenterimport.py index 3b79961f9..f3bdcb959 100644 --- a/tests/functional/openlp_plugins/songs/test_propresenterimport.py +++ b/tests/functional/openlp_plugins/songs/test_propresenterimport.py @@ -52,3 +52,5 @@ class TestProPresenterFileImport(SongImportTestHelper): """ self.file_import([os.path.join(TEST_PATH, 'Amazing Grace.pro4')], self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace.json'))) + self.file_import([os.path.join(TEST_PATH, 'Vaste Grond.pro4')], + self.load_external_result_data(os.path.join(TEST_PATH, 'Vaste Grond.json'))) diff --git a/tests/resources/propresentersongs/Vaste Grond.json b/tests/resources/propresentersongs/Vaste Grond.json new file mode 100644 index 000000000..f55abd83e --- /dev/null +++ b/tests/resources/propresentersongs/Vaste Grond.json @@ -0,0 +1,34 @@ +{ + "title": "Vaste Grond", + "verse_order_list": [], + "verses": [ + [ + "God voor U is niets onmogelijk\nHoe ongelofelijk\nU heeft alles in de hand", + "v1" + ], + [ + "U bent God en trekt Uw eigen plan\nU bent voor niemand bang\nVoor niets en niemand bang", + "v2" + ], + [ + "U houd me vast en geeft me moed\nOm door te gaan als ik niet durf\nIk wil van U zijn", + "v3" + ], + [ + "U geeft me kracht, en bent de vaste grond\nwaarop ik stevig sta\nik wil van U zijn, voor altijd van U zijn\nO God.", + "v4" + ], + [ + "Grote God, U bent uitzonderlijk\nen ondoorgrondelijk\nU biedt Uw liefde aan", + "v5" + ], + [ + "Wie ben ik, dat U mij ziet staan\nen met mij om wilt gaan?\nIk kan U niet weerstaan", + "v6" + ], + [ + "Onweerstaanbaar,\nonweerstaanbare God", + "v7" + ] + ] +} \ No newline at end of file diff --git a/tests/resources/propresentersongs/Vaste Grond.pro4 b/tests/resources/propresentersongs/Vaste Grond.pro4 new file mode 100644 index 000000000..7abfb593d --- /dev/null +++ b/tests/resources/propresentersongs/Vaste Grond.pro4 @@ -0,0 +1 @@ +<_-RVRect3D-_position x="32.37209" y="29" z="0" width="1074.349" height="818.7442"><_-D-_serializedShadow containerClass="NSMutableDictionary"><_-RVRect3D-_position x="32.37209" y="29" z="0" width="1074.349" height="818.7442"><_-D-_serializedShadow containerClass="NSMutableDictionary"><_-RVRect3D-_position x="32.37209" y="29" z="0" width="1074.349" height="818.7442"><_-D-_serializedShadow containerClass="NSMutableDictionary"><_-RVRect3D-_position x="32.37209" y="29" z="0" width="1074.349" height="818.7442"><_-D-_serializedShadow containerClass="NSMutableDictionary"><_-RVRect3D-_position x="32.37209" y="29" z="0" width="1074.349" height="818.7442"><_-D-_serializedShadow containerClass="NSMutableDictionary"><_-RVRect3D-_position x="32.37209" y="29" z="0" width="1074.349" height="818.7442"><_-D-_serializedShadow containerClass="NSMutableDictionary"><_-RVRect3D-_position x="32.37209" y="29" z="0" width="1074.349" height="818.7442"><_-D-_serializedShadow containerClass="NSMutableDictionary"> \ No newline at end of file From eeeb2b558ee7080fe378bdb496d5f146970a846f Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Mon, 18 Aug 2014 21:05:39 +0200 Subject: [PATCH 3/5] PEP8 --- scripts/jenkins_script.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/jenkins_script.py b/scripts/jenkins_script.py index 6c6fdac80..d7c8a3427 100755 --- a/scripts/jenkins_script.py +++ b/scripts/jenkins_script.py @@ -67,7 +67,8 @@ class OpenLPJobs(object): Branch_PEP = 'Branch-05a-Code_Analysis' Branch_Coverage = 'Branch-05b-Test_Coverage' - Jobs = [Branch_Pull, Branch_Functional, Branch_Interface, Branch_Windows_Functional, Branch_Windows_Interface, Branch_PEP, Branch_Coverage] + Jobs = [Branch_Pull, Branch_Functional, Branch_Interface, Branch_Windows_Functional, + Branch_Windows_Interface, Branch_PEP, Branch_Coverage] class Colour(object): From bde55c79f87d911a675f4556379a85ac51aa78b1 Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Mon, 18 Aug 2014 21:15:23 +0200 Subject: [PATCH 4/5] No newline at end of file... --- tests/resources/propresentersongs/Vaste Grond.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/resources/propresentersongs/Vaste Grond.json b/tests/resources/propresentersongs/Vaste Grond.json index f55abd83e..75ffac7a2 100644 --- a/tests/resources/propresentersongs/Vaste Grond.json +++ b/tests/resources/propresentersongs/Vaste Grond.json @@ -31,4 +31,4 @@ "v7" ] ] -} \ No newline at end of file +} From ce26493dac45976aa2b54aa75d370dcc3e670f3c Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Tue, 19 Aug 2014 07:57:54 +0200 Subject: [PATCH 5/5] We only support v4 files --- openlp/plugins/songs/lib/importer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/songs/lib/importer.py b/openlp/plugins/songs/lib/importer.py index 9c17e1f67..e9ee2c2f3 100644 --- a/openlp/plugins/songs/lib/importer.py +++ b/openlp/plugins/songs/lib/importer.py @@ -290,7 +290,7 @@ class SongFormat(object): }, ProPresenter: { 'class': ProPresenterImport, - 'name': 'ProPresenter', + 'name': 'ProPresenter 4', 'prefix': 'proPresenter', 'filter': '%s (*.pro4)' % translate('SongsPlugin.ImportWizardForm', 'ProPresenter 4 Song Files') },