openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #26158
[Merge] lp:~tomasgroth/openlp/bugfixes14 into lp:openlp
Tomas Groth has proposed merging lp:~tomasgroth/openlp/bugfixes14 into lp:openlp.
Requested reviews:
OpenLP Core (openlp-core)
Related bugs:
Bug #1412570 in OpenLP: "Slide preview viewer pane"
https://bugs.launchpad.net/openlp/+bug/1412570
Bug #1420785 in OpenLP: "Second Bible verse separation"
https://bugs.launchpad.net/openlp/+bug/1420785
Bug #1421136 in OpenLP: "Traceback when importing CSV bibles"
https://bugs.launchpad.net/openlp/+bug/1421136
Bug #1422197 in OpenLP: "Double clicking item in preview adds to service instead of sending live"
https://bugs.launchpad.net/openlp/+bug/1422197
For more details, see:
https://code.launchpad.net/~tomasgroth/openlp/bugfixes14/+merge/249897
Use the doubleclick-go-live setting in the preview controller. Fixes bug 1422197.
If no copyright info is given for bible, don't print it. Fixes bug 1420785.
Make csv-bible import work with python3. Fixes bug 1421136.
Add default shortcut bindings for preview next/prev, and make the appear in the shortcut edit dialog. Fixes bug 1412570.
--
Your team OpenLP Core is requested to review the proposed merge of lp:~tomasgroth/openlp/bugfixes14 into lp:openlp.
=== modified file 'openlp/core/common/settings.py'
--- openlp/core/common/settings.py 2015-01-18 13:39:21 +0000
+++ openlp/core/common/settings.py 2015-02-16 22:11:10 +0000
@@ -216,7 +216,8 @@
'shortcuts/moveDown': [QtGui.QKeySequence(QtCore.Qt.Key_PageDown)],
'shortcuts/nextTrackItem': [],
'shortcuts/nextItem_live': [QtGui.QKeySequence(QtCore.Qt.Key_Down), QtGui.QKeySequence(QtCore.Qt.Key_PageDown)],
- 'shortcuts/nextItem_preview': [],
+ 'shortcuts/nextItem_preview': [QtGui.QKeySequence(QtCore.Qt.Key_Down),
+ QtGui.QKeySequence(QtCore.Qt.Key_PageDown)],
'shortcuts/nextService': [QtGui.QKeySequence(QtCore.Qt.Key_Right)],
'shortcuts/newService': [],
'shortcuts/offlineHelpItem': [],
@@ -230,7 +231,8 @@
'shortcuts/playSlidesLoop': [],
'shortcuts/playSlidesOnce': [],
'shortcuts/previousService': [QtGui.QKeySequence(QtCore.Qt.Key_Left)],
- 'shortcuts/previousItem_preview': [],
+ 'shortcuts/previousItem_preview': [QtGui.QKeySequence(QtCore.Qt.Key_Up),
+ QtGui.QKeySequence(QtCore.Qt.Key_PageUp)],
'shortcuts/printServiceItem': [QtGui.QKeySequence('Ctrl+P')],
'shortcuts/songExportItem': [],
'shortcuts/songUsageStatus': [QtGui.QKeySequence(QtCore.Qt.Key_F4)],
=== modified file 'openlp/core/common/uistrings.py'
--- openlp/core/common/uistrings.py 2015-01-18 13:39:21 +0000
+++ openlp/core/common/uistrings.py 2015-02-16 22:11:10 +0000
@@ -115,6 +115,7 @@
self.PlaySlidesInLoop = translate('OpenLP.Ui', 'Play Slides in Loop')
self.PlaySlidesToEnd = translate('OpenLP.Ui', 'Play Slides to End')
self.Preview = translate('OpenLP.Ui', 'Preview')
+ self.PreviewToolbar = translate('OpenLP.Ui', 'Preview Toolbar')
self.PrintService = translate('OpenLP.Ui', 'Print Service')
self.Projector = translate('OpenLP.Ui', 'Projector', 'Singular')
self.Projectors = translate('OpenLP.Ui', 'Projectors', 'Plural')
=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py 2015-01-29 21:21:03 +0000
+++ openlp/core/ui/slidecontroller.py 2015-02-16 22:11:10 +0000
@@ -408,7 +408,7 @@
self.set_live_hot_keys(self)
self.__add_actions_to_widget(self.controller)
else:
- self.preview_widget.doubleClicked.connect(self.on_preview_add_to_service)
+ self.preview_widget.doubleClicked.connect(self.on_preview_double_click)
self.toolbar.set_widget_visible(['editSong'], False)
self.controller.addActions([self.next_item, self.previous_item])
Registry().register_function('slidecontroller_%s_stop_loop' % self.type_prefix, self.on_stop_loop)
@@ -1309,18 +1309,21 @@
if self.service_item:
self.service_manager.add_service_item(self.service_item)
- def on_go_live_click(self, field=None):
- """
- triggered by clicking the Preview slide items
- """
- if Settings().value('advanced/double click live'):
- # Live and Preview have issues if we have video or presentations
- # playing in both at the same time.
- if self.service_item.is_command():
- Registry().execute('%s_stop' % self.service_item.name.lower(), [self.service_item, self.is_live])
- if self.service_item.is_media():
- self.on_media_close()
- self.on_go_live()
+ def on_preview_double_click(self, field=None):
+ """
+ Triggered when a preview slide item is doubleclicked
+ """
+ if self.service_item:
+ if Settings().value('advanced/double click live'):
+ # Live and Preview have issues if we have video or presentations
+ # playing in both at the same time.
+ if self.service_item.is_command():
+ Registry().execute('%s_stop' % self.service_item.name.lower(), [self.service_item, self.is_live])
+ if self.service_item.is_media():
+ self.on_media_close()
+ self.on_go_live()
+ else:
+ self.on_preview_add_to_service()
def on_go_live(self, field=None):
"""
@@ -1418,7 +1421,7 @@
super(PreviewController, self).__init__(parent)
self.split = 0
self.type_prefix = 'preview'
- self.category = None
+ self.category = 'Preview Toolbar'
def bootstrap_post_set_up(self):
"""
=== modified file 'openlp/plugins/bibles/lib/csvbible.py'
--- openlp/plugins/bibles/lib/csvbible.py 2015-01-18 13:39:21 +0000
+++ openlp/plugins/bibles/lib/csvbible.py 2015-02-16 22:11:10 +0000
@@ -73,7 +73,7 @@
"""
log.info(self.__class__.__name__)
BibleDB.__init__(self, parent, **kwargs)
- self.books_file = kwargs['books_file']
+ self.books_file = kwargs['booksfile']
self.verses_file = kwargs['versefile']
def do_import(self, bible_name=None):
@@ -93,23 +93,20 @@
# Populate the Tables
try:
details = get_file_encoding(self.books_file)
- books_file = open(self.books_file, 'r')
- if not books_file.read(3) == '\xEF\xBB\xBF':
- # no BOM was found
- books_file.seek(0)
+ books_file = open(self.books_file, 'r', encoding=details['encoding'])
books_reader = csv.reader(books_file, delimiter=',', quotechar='"')
for line in books_reader:
if self.stop_import_flag:
break
- self.wizard.increment_progress_bar(translate('BiblesPlugin.CSVBible', 'Importing books... %s') %
- str(line[2], details['encoding']))
- book_ref_id = self.get_book_ref_id_by_name(str(line[2], details['encoding']), 67, language_id)
+ self.wizard.increment_progress_bar(translate('BiblesPlugin.CSVBible', 'Importing books... %s')
+ % line[2])
+ book_ref_id = self.get_book_ref_id_by_name(line[2], 67, language_id)
if not book_ref_id:
log.error('Importing books from "%s" failed' % self.books_file)
return False
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
- self.create_book(str(line[2], details['encoding']), book_ref_id, book_details['testament_id'])
- book_list[int(line[0])] = str(line[2], details['encoding'])
+ self.create_book(line[2], book_ref_id, book_details['testament_id'])
+ book_list.update({int(line[0]): line[2]})
self.application.process_events()
except (IOError, IndexError):
log.exception('Loading books from file failed')
@@ -125,10 +122,7 @@
try:
book_ptr = None
details = get_file_encoding(self.verses_file)
- verse_file = open(self.verses_file, 'rb')
- if not verse_file.read(3) == '\xEF\xBB\xBF':
- # no BOM was found
- verse_file.seek(0)
+ verse_file = open(self.verses_file, 'r', encoding=details['encoding'])
verse_reader = csv.reader(verse_file, delimiter=',', quotechar='"')
for line in verse_reader:
if self.stop_import_flag:
@@ -136,7 +130,7 @@
try:
line_book = book_list[int(line[0])]
except ValueError:
- line_book = str(line[0], details['encoding'])
+ line_book = line[0]
if book_ptr != line_book:
book = self.get_book(line_book)
book_ptr = book.name
@@ -144,10 +138,7 @@
translate('BiblesPlugin.CSVBible',
'Importing verses from %s...' % book.name, 'Importing verses from <book name>...'))
self.session.commit()
- try:
- verse_text = str(line[3], details['encoding'])
- except UnicodeError:
- verse_text = str(line[3], 'cp1252')
+ verse_text = line[3]
self.create_verse(book.id, line[1], line[2], verse_text)
self.wizard.increment_progress_bar(translate('BiblesPlugin.CSVBible', 'Importing verses... done.'))
self.application.process_events()
@@ -170,7 +161,7 @@
"""
detect_file = None
try:
- detect_file = open(filename, 'r')
+ detect_file = open(filename, 'rb')
details = chardet.detect(detect_file.read(1024))
except IOError:
log.exception('Error detecting file encoding')
=== modified file 'openlp/plugins/bibles/lib/versereferencelist.py'
--- openlp/plugins/bibles/lib/versereferencelist.py 2015-01-18 13:39:21 +0000
+++ openlp/plugins/bibles/lib/versereferencelist.py 2015-02-16 22:11:10 +0000
@@ -82,9 +82,11 @@
if result[-1] not in [';', ',', '.']:
result += ';'
result += ' '
- result = '%s%s, %s' % (result, version['version'], version['copyright'])
+ result += version['version']
+ if version['copyright'].strip():
+ result += ', ' + version['copyright']
if version['permission'].strip():
- result = result + ', ' + version['permission']
+ result += ', ' + version['permission']
result = result.rstrip()
if result.endswith(','):
return result[:len(result) - 1]
=== added file 'tests/functional/openlp_plugins/bibles/test_csvimport.py'
--- tests/functional/openlp_plugins/bibles/test_csvimport.py 1970-01-01 00:00:00 +0000
+++ tests/functional/openlp_plugins/bibles/test_csvimport.py 2015-02-16 22:11:10 +0000
@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2015 OpenLP Developers #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it #
+# under the terms of the GNU General Public License as published by the Free #
+# Software Foundation; version 2 of the License. #
+# #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
+# more details. #
+# #
+# You should have received a copy of the GNU General Public License along #
+# with this program; if not, write to the Free Software Foundation, Inc., 59 #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
+###############################################################################
+"""
+This module contains tests for the CSV Bible importer.
+"""
+
+import os
+import json
+from unittest import TestCase
+
+from tests.functional import MagicMock, patch
+from openlp.plugins.bibles.lib.csvbible import CSVBible
+from openlp.plugins.bibles.lib.db import BibleDB
+
+TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__),
+ '..', '..', '..', 'resources', 'bibles'))
+
+
+class TestCSVImport(TestCase):
+ """
+ Test the functions in the :mod:`csvimport` module.
+ """
+
+ def setUp(self):
+ self.registry_patcher = patch('openlp.plugins.bibles.lib.db.Registry')
+ self.registry_patcher.start()
+ self.manager_patcher = patch('openlp.plugins.bibles.lib.db.Manager')
+ self.manager_patcher.start()
+
+ def tearDown(self):
+ self.registry_patcher.stop()
+ self.manager_patcher.stop()
+
+ def create_importer_test(self):
+ """
+ Test creating an instance of the CSV file importer
+ """
+ # GIVEN: A mocked out "manager"
+ mocked_manager = MagicMock()
+
+ # WHEN: An importer object is created
+ importer = CSVBible(mocked_manager, path='.', name='.', booksfile='.', versefile='.')
+
+ # THEN: The importer should be an instance of BibleDB
+ self.assertIsInstance(importer, BibleDB)
+
+ def file_import_test(self):
+ """
+ Test the actual import of CSV Bible file
+ """
+ # GIVEN: Test files with a mocked out "manager", "import_wizard", and mocked functions
+ # get_book_ref_id_by_name, create_verse, create_book, session and get_language.
+ result_file = open(os.path.join(TEST_PATH, 'dk1933.json'), 'rb')
+ test_data = json.loads(result_file.read().decode())
+ books_file = os.path.join(TEST_PATH, 'dk1933-books.csv')
+ verses_file = os.path.join(TEST_PATH, 'dk1933-verses.csv')
+ with patch('openlp.plugins.bibles.lib.csvbible.CSVBible.application'):
+ mocked_manager = MagicMock()
+ mocked_import_wizard = MagicMock()
+ importer = CSVBible(mocked_manager, path='.', name='.', booksfile=books_file, versefile=verses_file)
+ importer.wizard = mocked_import_wizard
+ importer.get_book_ref_id_by_name = MagicMock()
+ importer.create_verse = MagicMock()
+ importer.create_book = MagicMock()
+ importer.session = MagicMock()
+ importer.get_language = MagicMock()
+ importer.get_language.return_value = 'Danish'
+ importer.get_book = MagicMock()
+
+ # WHEN: Importing bible file
+ importer.do_import()
+
+ # THEN: The create_verse() method should have been called with each verse in the file.
+ self.assertTrue(importer.create_verse.called)
+ for verse_tag, verse_text in test_data['verses']:
+ importer.create_verse.assert_any_call(importer.get_book().id, '1', verse_tag, verse_text)
+ importer.create_book.assert_any_call('1. Mosebog', importer.get_book_ref_id_by_name(), 1)
+ importer.create_book.assert_any_call('1. Krønikebog', importer.get_book_ref_id_by_name(), 1)
=== added file 'tests/resources/bibles/dk1933-books.csv'
--- tests/resources/bibles/dk1933-books.csv 1970-01-01 00:00:00 +0000
+++ tests/resources/bibles/dk1933-books.csv 2015-02-16 22:11:10 +0000
@@ -0,0 +1,22 @@
+1,1,1. Mosebog,1Mos
+2,1,2. Mosebog,2Mos
+3,1,3. Mosebog,3Mos
+4,1,4. Mosebog,4Mos
+5,1,5. Mosebog,5Mos
+6,1,Josvabogen,jos
+7,1,Dommerbogen,dom
+8,1,Ruths Bog,ruth
+9,1,1. Samuelsbog,1Sam
+10,1,2. Samuelsbog,2Sam
+11,1,1. Kongebog,1kong
+12,1,2. Kongebog,2kong
+13,1,1. Krønikebog,1kron
+14,1,2. Krønikebog,2kron
+15,1,Ezras Bog,ezra
+16,1,Nehemias' Bog,neh
+17,1,Esters Bog,est
+18,1,Jobs Bog,job
+19,1,Salmernes Bog,sl
+20,1,Ordsprogenes Bog,ordsp
+21,1,Prædikerens Bog,prad
+22,1,Højsangen,hojs
=== added file 'tests/resources/bibles/dk1933-verses.csv'
--- tests/resources/bibles/dk1933-verses.csv 1970-01-01 00:00:00 +0000
+++ tests/resources/bibles/dk1933-verses.csv 2015-02-16 22:11:10 +0000
@@ -0,0 +1,10 @@
+1,1,1,"I Begyndelsen skabte Gud Himmelen og Jorden."
+1,1,2,"Og Jorden var øde og tom, og der var Mørke over Verdensdybet. Men Guds Ånd svævede over Vandene."
+1,1,3,"Og Gud sagde: ""Der blive Lys!"" Og der blev Lys."
+1,1,4,"Og Gud så, at Lyset var godt, og Gud satte Skel mellem Lyset og Mørket,"
+1,1,5,"og Gud kaldte Lyset Dag, og Mørket kaldte han Nat. Og det blev Aften, og det blev Morgen, første Dag."
+1,1,6,"Derpå sagde Gud: ""Der blive en Hvælving midt i Vandene til at skille Vandene ad!"""
+1,1,7,"Og således skete det: Gud gjorde Hvælvingen og skilte Vandet under Hvælvingen fra Vandet over Hvælvingen;"
+1,1,8,"og Gud kaldte Hvælvingen Himmel. Og det blev Aften, og det blev Morgen, anden Dag."
+1,1,9,"Derpå sagde Gud: ""Vandet under Himmelen samle sig på eet Sted, så det faste Land kommer til Syne!"" Og således skete det;"
+1,1,10,"og Gud kaldte det faste Land Jord, og Stedet, hvor Vandet samlede sig, kaldte han Hav. Og Gud så, at det var godt."
References