From 6a7da2ade1dc1379a289e7384f7ebdb73fc12715 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Mon, 26 Jan 2015 21:48:45 +0000 Subject: [PATCH 1/8] Fix support for 'end' mark in bible-search. Fixes bug 1412517. Fixes: https://launchpad.net/bugs/1412517 --- openlp/plugins/bibles/lib/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/plugins/bibles/lib/__init__.py b/openlp/plugins/bibles/lib/__init__.py index 1d7216ee5..78e9dcc63 100644 --- a/openlp/plugins/bibles/lib/__init__.py +++ b/openlp/plugins/bibles/lib/__init__.py @@ -371,7 +371,7 @@ def parse_reference(reference, bible, language_selection, book_ref_id=False): from_chapter = from_verse from_verse = None if to_chapter: - if to_chapter < from_chapter: + if from_chapter and to_chapter < from_chapter: continue else: chapter = to_chapter @@ -387,7 +387,7 @@ def parse_reference(reference, bible, language_selection, book_ref_id=False): from_verse = 1 if not to_verse: to_verse = -1 - if to_chapter > from_chapter: + if to_chapter and to_chapter > from_chapter: ref_list.append((book_ref_id, from_chapter, from_verse, -1)) for i in range(from_chapter + 1, to_chapter): ref_list.append((book_ref_id, i, 1, -1)) From 10d25f81733ec68985be7f93b912fdb142bef0bf Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Tue, 27 Jan 2015 15:52:18 +0100 Subject: [PATCH 2/8] Added a cancel-button to FTW when no internet is available. Fixes bug 1410738 Fixes: https://launchpad.net/bugs/1410738 --- openlp/core/ui/firsttimeform.py | 13 +++++++++++++ openlp/core/ui/firsttimewizard.py | 5 ++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/openlp/core/ui/firsttimeform.py b/openlp/core/ui/firsttimeform.py index 9c3b7bf09..8e5ab219f 100644 --- a/openlp/core/ui/firsttimeform.py +++ b/openlp/core/ui/firsttimeform.py @@ -268,9 +268,11 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties): self.web = 'http://openlp.org/files/frw/' self.cancel_button.clicked.connect(self.on_cancel_button_clicked) self.no_internet_finish_button.clicked.connect(self.on_no_internet_finish_button_clicked) + self.no_internet_cancel_button.clicked.connect(self.on_no_internet_cancel_button_clicked) self.currentIdChanged.connect(self.on_current_id_changed) Registry().register_function('config_screen_changed', self.update_screen_list_combo) self.no_internet_finish_button.setVisible(False) + self.no_internet_cancel_button.setVisible(False) # Check if this is a re-run of the wizard. self.has_run_wizard = Settings().value('core/has run wizard') check_directory_exists(os.path.join(gettempdir(), 'openlp')) @@ -327,6 +329,10 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties): self.next_button.setVisible(False) self.cancel_button.setVisible(False) self.no_internet_finish_button.setVisible(True) + if self.has_run_wizard: + self.no_internet_cancel_button.setVisible(False) + else: + self.no_internet_cancel_button.setVisible(True) elif page_id == FirstTimePage.Plugins: self.back_button.setVisible(False) elif page_id == FirstTimePage.Progress: @@ -372,6 +378,13 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties): Settings().setValue('core/has run wizard', True) self.close() + def on_no_internet_cancel_button_clicked(self): + """ + Process the triggering of the "Cancel" button on the No Internet page. + """ + self.was_cancelled = True + self.close() + def url_get_file(self, url, f_path): """" Download a file given a URL. The file is retrieved in chunks, giving the ability to cancel the download at any diff --git a/openlp/core/ui/firsttimewizard.py b/openlp/core/ui/firsttimewizard.py index 63695a09a..041cfc050 100644 --- a/openlp/core/ui/firsttimewizard.py +++ b/openlp/core/ui/firsttimewizard.py @@ -59,7 +59,8 @@ class UiFirstTimeWizard(object): first_time_wizard.resize(550, 386) first_time_wizard.setModal(True) first_time_wizard.setOptions(QtGui.QWizard.IndependentPages | QtGui.QWizard.NoBackButtonOnStartPage | - QtGui.QWizard.NoBackButtonOnLastPage | QtGui.QWizard.HaveCustomButton1) + QtGui.QWizard.NoBackButtonOnLastPage | QtGui.QWizard.HaveCustomButton1 | + QtGui.QWizard.HaveCustomButton2) if is_macosx(): first_time_wizard.setPixmap(QtGui.QWizard.BackgroundPixmap, QtGui.QPixmap(':/wizards/openlp-osx-wizard.png')) @@ -69,6 +70,7 @@ class UiFirstTimeWizard(object): self.finish_button = self.button(QtGui.QWizard.FinishButton) self.no_internet_finish_button = self.button(QtGui.QWizard.CustomButton1) self.cancel_button = self.button(QtGui.QWizard.CancelButton) + self.no_internet_cancel_button = self.button(QtGui.QWizard.CustomButton2) self.next_button = self.button(QtGui.QWizard.NextButton) self.back_button = self.button(QtGui.QWizard.BackButton) add_welcome_page(first_time_wizard, ':/wizards/wizard_firsttime.bmp') @@ -271,3 +273,4 @@ class UiFirstTimeWizard(object): 'and OpenLP is configured.')) self.progress_label.setText(translate('OpenLP.FirstTimeWizard', 'Starting configuration process...')) first_time_wizard.setButtonText(QtGui.QWizard.CustomButton1, translate('OpenLP.FirstTimeWizard', 'Finish')) + first_time_wizard.setButtonText(QtGui.QWizard.CustomButton2, translate('OpenLP.FirstTimeWizard', 'Cancel')) From 6668282fdebc5f3983f432d391d9a46a183a36b7 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Tue, 27 Jan 2015 15:59:06 +0100 Subject: [PATCH 3/8] Set the cursor back to normal after deleting a presentation. Fixes bug 1414978. Fixes: https://launchpad.net/bugs/1414978 --- 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 04553c375..10b295235 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -225,10 +225,10 @@ class PresentationMediaItem(MediaManagerItem): self.clean_up_thumbnails(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()) + self.application.set_normal_cursor() def clean_up_thumbnails(self, filepath): """ From 8e8228a69a3de53dd95eea53df250c528b0ec7dc Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Thu, 29 Jan 2015 15:06:44 +0100 Subject: [PATCH 4/8] Make xml parsing of presentation manager files recover if errors are encountered. Fixes bug 1414980. Fixes: https://launchpad.net/bugs/1414980 --- openlp/plugins/songs/lib/importers/presentationmanager.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openlp/plugins/songs/lib/importers/presentationmanager.py b/openlp/plugins/songs/lib/importers/presentationmanager.py index f35b812a1..eb60f16e1 100644 --- a/openlp/plugins/songs/lib/importers/presentationmanager.py +++ b/openlp/plugins/songs/lib/importers/presentationmanager.py @@ -25,7 +25,7 @@ Presentationmanager song files into the current database. """ import os -from lxml import objectify +from lxml import objectify, etree from openlp.core.ui.wizard import WizardStrings from .songimport import SongImport @@ -42,7 +42,8 @@ class PresentationManagerImport(SongImport): if self.stop_import_flag: return self.import_wizard.increment_progress_bar(WizardStrings.ImportingType % os.path.basename(file_path)) - root = objectify.parse(open(file_path, 'rb')).getroot() + tree = etree.parse(file_path, parser=etree.XMLParser(recover=True)) + root = objectify.fromstring(etree.tostring(tree)) self.process_song(root) def process_song(self, root): From 4c53cb5184a4cd24195ce54b5b15a010460e6639 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Thu, 29 Jan 2015 20:54:06 +0000 Subject: [PATCH 5/8] Added tests --- .../songs/test_presentationmanagerimport.py | 10 +++--- .../bibles/test_lib_parse_reference.py | 10 ++++++ .../Amazing Grace.json | 29 ++++++++++++++++++ .../Amazing Grace.sng | Bin 0 -> 2206 bytes 4 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 tests/resources/presentationmanagersongs/Amazing Grace.json create mode 100644 tests/resources/presentationmanagersongs/Amazing Grace.sng diff --git a/tests/functional/openlp_plugins/songs/test_presentationmanagerimport.py b/tests/functional/openlp_plugins/songs/test_presentationmanagerimport.py index 218596cf7..c351f7ed3 100644 --- a/tests/functional/openlp_plugins/songs/test_presentationmanagerimport.py +++ b/tests/functional/openlp_plugins/songs/test_presentationmanagerimport.py @@ -42,7 +42,9 @@ class TestPresentationManagerFileImport(SongImportTestHelper): """ Test that loading a PresentationManager file works correctly """ - self.file_import([os.path.join(TEST_PATH, 'Great Is Thy Faithfulness.sng')], - self.load_external_result_data(os.path.join(TEST_PATH, 'Great Is Thy Faithfulness.json'))) - self.file_import([os.path.join(TEST_PATH, 'Agnus Dei.sng')], - self.load_external_result_data(os.path.join(TEST_PATH, 'Agnus Dei.json'))) + #self.file_import([os.path.join(TEST_PATH, 'Great Is Thy Faithfulness.sng')], + # self.load_external_result_data(os.path.join(TEST_PATH, 'Great Is Thy Faithfulness.json'))) + #self.file_import([os.path.join(TEST_PATH, 'Agnus Dei.sng')], + # self.load_external_result_data(os.path.join(TEST_PATH, 'Agnus Dei.json'))) + self.file_import([os.path.join(TEST_PATH, 'Amazing Grace.sng')], + self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace.json'))) diff --git a/tests/interfaces/openlp_plugins/bibles/test_lib_parse_reference.py b/tests/interfaces/openlp_plugins/bibles/test_lib_parse_reference.py index 4c0e0fe14..b4eec48af 100644 --- a/tests/interfaces/openlp_plugins/bibles/test_lib_parse_reference.py +++ b/tests/interfaces/openlp_plugins/bibles/test_lib_parse_reference.py @@ -109,3 +109,13 @@ class TestBibleManager(TestCase, TestMixin): results = parse_reference('Raoul 1', self.manager.db_cache['tests'], MagicMock()) # THEN a verse array should be returned self.assertEqual(False, results, "The bible Search should return False") + + def parse_reference_five_test(self): + """ + Test the parse_reference method with 1 Timothy 1:3-end + """ + # GIVEN given a bible in the bible manager + # WHEN asking to parse the bible reference + results = parse_reference('1 Timothy 1:3-end', self.manager.db_cache['tests'], MagicMock(), 54) + # THEN a verse array should be returned + self.assertEqual([(54, 1, 3, -1)], results, "The bible verses should matches the expected results") diff --git a/tests/resources/presentationmanagersongs/Amazing Grace.json b/tests/resources/presentationmanagersongs/Amazing Grace.json new file mode 100644 index 000000000..fa2e182a9 --- /dev/null +++ b/tests/resources/presentationmanagersongs/Amazing Grace.json @@ -0,0 +1,29 @@ +{ + "title": "Amazing Grace", + "authors": [ + "John Newton" + ], + "verse_order_list": ["v1", "v2", "v3", "v4", "v5"], + "verses": [ + [ + "Amazing grace! How sweet the sound!\nThat saved a wretch like me!\nI once was lost, but now am found;\nWas blind, but now I see.", + "v1" + ], + [ + "'Twas grace that taught my heart to fear,\nAnd grace my fears relieved.\nHow precious did that grace appear,\nThe hour I first believed.", + "v2" + ], + [ + "The Lord has promised good to me,\nHis Word my hope secures.\nHe will my shield and portion be\nAs long as life endures.", + "v3" + ], + [ + "Thro' many dangers, toils and snares\nI have already come.\n'Tis grace that brought me safe thus far,\nAnd grace will lead me home.", + "v4" + ], + [ + "When we've been there ten thousand years,\nBright shining as the sun,\nWe've no less days to sing God's praise,\nThan when we first begun.", + "v5" + ] + ] +} diff --git a/tests/resources/presentationmanagersongs/Amazing Grace.sng b/tests/resources/presentationmanagersongs/Amazing Grace.sng new file mode 100644 index 0000000000000000000000000000000000000000..47b5ff3b3a471513105cdef53394950c49f55a72 GIT binary patch literal 2206 zcmbW2OK;Oq5QS%r#D8$R$)=(_SCm%aAzFlBQ^*oIiJL~GPE zk6OM{8`@HD*ri;=s@?b4`l=+iUpk5G@8y##YavXBvg#}YXYSE1h4xzUKInNV&rEd{ zwvs(n;JIxVzOb}nrN5bUka}^G;YrKzp6pJ=$x6>ke+&K8dauO|G0?

gu+rgM5jXR*%}1IxLdwH@d^bdt#? z5anVolhzW3myTi3cn&=a*mn7n4IT-RW)~pSC>q?7YR@aTsg`E48pK z8)aoezZMFZ%*9UdI`@j=+k8}@L*faC= zhE4{y&G@;dV9`Vm6m*upFjq@O%d{one(L$bj`D9KK+_$A|HJFEme-W~qjFz6YA{m; zbumR#?P%mz$R zAB?72D%qedn4ku_4eRt0tC`>BibhQKBTNTp%mE$Q)@-M=p?pzMY}n{gYz!0~nhcd* zIEK6DVCA^!3*Q;gq-f~0Lv(*OU$krvd;;hzd$89qf$G`dff`Pug6=FPF7dk7eaviB z^;#b3TLTB^s`OvJw4oH3BWfki%0|rtog@tG!(gCt*6Hxt-(m*%`loLvv(fWAW+> cTdeBwy{wK+E@KYiQ(0@S8!lmGw# literal 0 HcmV?d00001 From 1b75cc9c6b37a6f762905b0af7851d8940d2dfff Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Thu, 29 Jan 2015 21:15:39 +0000 Subject: [PATCH 6/8] Fallback to manual encoding detection. --- .../plugins/songs/lib/importers/presentationmanager.py | 9 ++++++++- .../songs/test_presentationmanagerimport.py | 8 ++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/openlp/plugins/songs/lib/importers/presentationmanager.py b/openlp/plugins/songs/lib/importers/presentationmanager.py index eb60f16e1..c913fd232 100644 --- a/openlp/plugins/songs/lib/importers/presentationmanager.py +++ b/openlp/plugins/songs/lib/importers/presentationmanager.py @@ -25,6 +25,7 @@ Presentationmanager song files into the current database. """ import os +import chardet from lxml import objectify, etree from openlp.core.ui.wizard import WizardStrings @@ -42,7 +43,13 @@ class PresentationManagerImport(SongImport): if self.stop_import_flag: return self.import_wizard.increment_progress_bar(WizardStrings.ImportingType % os.path.basename(file_path)) - tree = etree.parse(file_path, parser=etree.XMLParser(recover=True)) + try: + tree = etree.parse(file_path, parser=etree.XMLParser(recover=True)) + except etree.XMLSyntaxError: + # Try to detect encoding and use it + file = open(file_path, mode='rb') + encoding = chardet.detect(file)['encoding'] + tree = etree.parse(file_path, parser=etree.XMLParser(recover=True, encoding=encoding)) root = objectify.fromstring(etree.tostring(tree)) self.process_song(root) diff --git a/tests/functional/openlp_plugins/songs/test_presentationmanagerimport.py b/tests/functional/openlp_plugins/songs/test_presentationmanagerimport.py index c351f7ed3..585aa34c5 100644 --- a/tests/functional/openlp_plugins/songs/test_presentationmanagerimport.py +++ b/tests/functional/openlp_plugins/songs/test_presentationmanagerimport.py @@ -42,9 +42,9 @@ class TestPresentationManagerFileImport(SongImportTestHelper): """ Test that loading a PresentationManager file works correctly """ - #self.file_import([os.path.join(TEST_PATH, 'Great Is Thy Faithfulness.sng')], - # self.load_external_result_data(os.path.join(TEST_PATH, 'Great Is Thy Faithfulness.json'))) - #self.file_import([os.path.join(TEST_PATH, 'Agnus Dei.sng')], - # self.load_external_result_data(os.path.join(TEST_PATH, 'Agnus Dei.json'))) + self.file_import([os.path.join(TEST_PATH, 'Great Is Thy Faithfulness.sng')], + self.load_external_result_data(os.path.join(TEST_PATH, 'Great Is Thy Faithfulness.json'))) + self.file_import([os.path.join(TEST_PATH, 'Agnus Dei.sng')], + self.load_external_result_data(os.path.join(TEST_PATH, 'Agnus Dei.json'))) self.file_import([os.path.join(TEST_PATH, 'Amazing Grace.sng')], self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace.json'))) From 46ee502ad6fe7ed29efcb69088b7ec0125981bb3 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Thu, 29 Jan 2015 21:20:36 +0000 Subject: [PATCH 7/8] Fix for chardet input. --- openlp/plugins/songs/lib/importers/presentationmanager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/songs/lib/importers/presentationmanager.py b/openlp/plugins/songs/lib/importers/presentationmanager.py index c913fd232..b9df92961 100644 --- a/openlp/plugins/songs/lib/importers/presentationmanager.py +++ b/openlp/plugins/songs/lib/importers/presentationmanager.py @@ -48,7 +48,7 @@ class PresentationManagerImport(SongImport): except etree.XMLSyntaxError: # Try to detect encoding and use it file = open(file_path, mode='rb') - encoding = chardet.detect(file)['encoding'] + encoding = chardet.detect(file.read())['encoding'] tree = etree.parse(file_path, parser=etree.XMLParser(recover=True, encoding=encoding)) root = objectify.fromstring(etree.tostring(tree)) self.process_song(root) From cf9c91f171268e920ae30e20ec3d9e1b7329db0e Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Fri, 30 Jan 2015 21:50:36 +0000 Subject: [PATCH 8/8] Fix parsing of partly broken presentation manager files on windows. --- openlp/plugins/bibles/lib/__init__.py | 2 +- openlp/plugins/songs/lib/importers/presentationmanager.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/openlp/plugins/bibles/lib/__init__.py b/openlp/plugins/bibles/lib/__init__.py index 78e9dcc63..df72514fa 100644 --- a/openlp/plugins/bibles/lib/__init__.py +++ b/openlp/plugins/bibles/lib/__init__.py @@ -178,7 +178,7 @@ def update_reference_separators(): default_separators = [ '|'.join([ translate('BiblesPlugin', ':', 'Verse identifier e.g. Genesis 1 : 1 = Genesis Chapter 1 Verse 1'), - translate('BiblesPlugin', 'v','Verse identifier e.g. Genesis 1 v 1 = Genesis Chapter 1 Verse 1'), + translate('BiblesPlugin', 'v', 'Verse identifier e.g. Genesis 1 v 1 = Genesis Chapter 1 Verse 1'), translate('BiblesPlugin', 'V', 'Verse identifier e.g. Genesis 1 V 1 = Genesis Chapter 1 Verse 1'), translate('BiblesPlugin', 'verse', 'Verse identifier e.g. Genesis 1 verse 1 = Genesis Chapter 1 Verse 1'), translate('BiblesPlugin', 'verses', diff --git a/openlp/plugins/songs/lib/importers/presentationmanager.py b/openlp/plugins/songs/lib/importers/presentationmanager.py index b9df92961..523bc5763 100644 --- a/openlp/plugins/songs/lib/importers/presentationmanager.py +++ b/openlp/plugins/songs/lib/importers/presentationmanager.py @@ -25,6 +25,7 @@ Presentationmanager song files into the current database. """ import os +import re import chardet from lxml import objectify, etree @@ -49,7 +50,11 @@ class PresentationManagerImport(SongImport): # Try to detect encoding and use it file = open(file_path, mode='rb') encoding = chardet.detect(file.read())['encoding'] - tree = etree.parse(file_path, parser=etree.XMLParser(recover=True, encoding=encoding)) + file.close() + # Open file with detected encoding and remove encoding declaration + text = open(file_path, mode='r', encoding=encoding).read() + text = re.sub('.+\?>\n', '', text) + tree = etree.fromstring(text, parser=etree.XMLParser(recover=True)) root = objectify.fromstring(etree.tostring(tree)) self.process_song(root)