forked from openlp/openlp
HEAD
This commit is contained in:
commit
0fc598fab5
201
openlp/core/common/languages.py
Normal file
201
openlp/core/common/languages.py
Normal file
@ -0,0 +1,201 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 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 #
|
||||
###############################################################################
|
||||
"""
|
||||
The :mod:`languages` module provides a list of language names with utility functions.
|
||||
"""
|
||||
from collections import namedtuple
|
||||
|
||||
from openlp.core.common import translate
|
||||
|
||||
|
||||
Language = namedtuple('Language', ['id', 'name', 'code'])
|
||||
languages = sorted([
|
||||
Language(1, translate('common.languages', '(Afan) Oromo', 'Language code: om'), 'om'),
|
||||
Language(2, translate('common.languages', 'Abkhazian', 'Language code: ab'), 'ab'),
|
||||
Language(3, translate('common.languages', 'Afar', 'Language code: aa'), 'aa'),
|
||||
Language(4, translate('common.languages', 'Afrikaans', 'Language code: af'), 'af'),
|
||||
Language(5, translate('common.languages', 'Albanian', 'Language code: sq'), 'sq'),
|
||||
Language(6, translate('common.languages', 'Amharic', 'Language code: am'), 'am'),
|
||||
Language(140, translate('common.languages', 'Amuzgo', 'Language code: amu'), 'amu'),
|
||||
Language(152, translate('common.languages', 'Ancient Greek', 'Language code: grc'), 'grc'),
|
||||
Language(7, translate('common.languages', 'Arabic', 'Language code: ar'), 'ar'),
|
||||
Language(8, translate('common.languages', 'Armenian', 'Language code: hy'), 'hy'),
|
||||
Language(9, translate('common.languages', 'Assamese', 'Language code: as'), 'as'),
|
||||
Language(10, translate('common.languages', 'Aymara', 'Language code: ay'), 'ay'),
|
||||
Language(11, translate('common.languages', 'Azerbaijani', 'Language code: az'), 'az'),
|
||||
Language(12, translate('common.languages', 'Bashkir', 'Language code: ba'), 'ba'),
|
||||
Language(13, translate('common.languages', 'Basque', 'Language code: eu'), 'eu'),
|
||||
Language(14, translate('common.languages', 'Bengali', 'Language code: bn'), 'bn'),
|
||||
Language(15, translate('common.languages', 'Bhutani', 'Language code: dz'), 'dz'),
|
||||
Language(16, translate('common.languages', 'Bihari', 'Language code: bh'), 'bh'),
|
||||
Language(17, translate('common.languages', 'Bislama', 'Language code: bi'), 'bi'),
|
||||
Language(18, translate('common.languages', 'Breton', 'Language code: br'), 'br'),
|
||||
Language(19, translate('common.languages', 'Bulgarian', 'Language code: bg'), 'bg'),
|
||||
Language(20, translate('common.languages', 'Burmese', 'Language code: my'), 'my'),
|
||||
Language(21, translate('common.languages', 'Byelorussian', 'Language code: be'), 'be'),
|
||||
Language(142, translate('common.languages', 'Cakchiquel', 'Language code: cak'), 'cak'),
|
||||
Language(22, translate('common.languages', 'Cambodian', 'Language code: km'), 'km'),
|
||||
Language(23, translate('common.languages', 'Catalan', 'Language code: ca'), 'ca'),
|
||||
Language(24, translate('common.languages', 'Chinese', 'Language code: zh'), 'zh'),
|
||||
Language(141, translate('common.languages', 'Comaltepec Chinantec', 'Language code: cco'), 'cco'),
|
||||
Language(25, translate('common.languages', 'Corsican', 'Language code: co'), 'co'),
|
||||
Language(26, translate('common.languages', 'Croatian', 'Language code: hr'), 'hr'),
|
||||
Language(27, translate('common.languages', 'Czech', 'Language code: cs'), 'cs'),
|
||||
Language(28, translate('common.languages', 'Danish', 'Language code: da'), 'da'),
|
||||
Language(29, translate('common.languages', 'Dutch', 'Language code: nl'), 'nl'),
|
||||
Language(30, translate('common.languages', 'English', 'Language code: en'), 'en'),
|
||||
Language(31, translate('common.languages', 'Esperanto', 'Language code: eo'), 'eo'),
|
||||
Language(32, translate('common.languages', 'Estonian', 'Language code: et'), 'et'),
|
||||
Language(33, translate('common.languages', 'Faeroese', 'Language code: fo'), 'fo'),
|
||||
Language(34, translate('common.languages', 'Fiji', 'Language code: fj'), 'fj'),
|
||||
Language(35, translate('common.languages', 'Finnish', 'Language code: fi'), 'fi'),
|
||||
Language(36, translate('common.languages', 'French', 'Language code: fr'), 'fr'),
|
||||
Language(37, translate('common.languages', 'Frisian', 'Language code: fy'), 'fy'),
|
||||
Language(38, translate('common.languages', 'Galician', 'Language code: gl'), 'gl'),
|
||||
Language(39, translate('common.languages', 'Georgian', 'Language code: ka'), 'ka'),
|
||||
Language(40, translate('common.languages', 'German', 'Language code: de'), 'de'),
|
||||
Language(41, translate('common.languages', 'Greek', 'Language code: el'), 'el'),
|
||||
Language(42, translate('common.languages', 'Greenlandic', 'Language code: kl'), 'kl'),
|
||||
Language(43, translate('common.languages', 'Guarani', 'Language code: gn'), 'gn'),
|
||||
Language(44, translate('common.languages', 'Gujarati', 'Language code: gu'), 'gu'),
|
||||
Language(143, translate('common.languages', 'Haitian Creole', 'Language code: ht'), 'ht'),
|
||||
Language(45, translate('common.languages', 'Hausa', 'Language code: ha'), 'ha'),
|
||||
Language(46, translate('common.languages', 'Hebrew (former iw)', 'Language code: he'), 'he'),
|
||||
Language(144, translate('common.languages', 'Hiligaynon', 'Language code: hil'), 'hil'),
|
||||
Language(47, translate('common.languages', 'Hindi', 'Language code: hi'), 'hi'),
|
||||
Language(48, translate('common.languages', 'Hungarian', 'Language code: hu'), 'hu'),
|
||||
Language(49, translate('common.languages', 'Icelandic', 'Language code: is'), 'is'),
|
||||
Language(50, translate('common.languages', 'Indonesian (former in)', 'Language code: id'), 'id'),
|
||||
Language(51, translate('common.languages', 'Interlingua', 'Language code: ia'), 'ia'),
|
||||
Language(52, translate('common.languages', 'Interlingue', 'Language code: ie'), 'ie'),
|
||||
Language(54, translate('common.languages', 'Inuktitut (Eskimo)', 'Language code: iu'), 'iu'),
|
||||
Language(53, translate('common.languages', 'Inupiak', 'Language code: ik'), 'ik'),
|
||||
Language(55, translate('common.languages', 'Irish', 'Language code: ga'), 'ga'),
|
||||
Language(56, translate('common.languages', 'Italian', 'Language code: it'), 'it'),
|
||||
Language(145, translate('common.languages', 'Jakalteko', 'Language code: jac'), 'jac'),
|
||||
Language(57, translate('common.languages', 'Japanese', 'Language code: ja'), 'ja'),
|
||||
Language(58, translate('common.languages', 'Javanese', 'Language code: jw'), 'jw'),
|
||||
Language(150, translate('common.languages', 'K\'iche\'', 'Language code: quc'), 'quc'),
|
||||
Language(59, translate('common.languages', 'Kannada', 'Language code: kn'), 'kn'),
|
||||
Language(60, translate('common.languages', 'Kashmiri', 'Language code: ks'), 'ks'),
|
||||
Language(61, translate('common.languages', 'Kazakh', 'Language code: kk'), 'kk'),
|
||||
Language(146, translate('common.languages', 'Kekchí ', 'Language code: kek'), 'kek'),
|
||||
Language(62, translate('common.languages', 'Kinyarwanda', 'Language code: rw'), 'rw'),
|
||||
Language(63, translate('common.languages', 'Kirghiz', 'Language code: ky'), 'ky'),
|
||||
Language(64, translate('common.languages', 'Kirundi', 'Language code: rn'), 'rn'),
|
||||
Language(65, translate('common.languages', 'Korean', 'Language code: ko'), 'ko'),
|
||||
Language(66, translate('common.languages', 'Kurdish', 'Language code: ku'), 'ku'),
|
||||
Language(67, translate('common.languages', 'Laothian', 'Language code: lo'), 'lo'),
|
||||
Language(68, translate('common.languages', 'Latin', 'Language code: la'), 'la'),
|
||||
Language(69, translate('common.languages', 'Latvian, Lettish', 'Language code: lv'), 'lv'),
|
||||
Language(70, translate('common.languages', 'Lingala', 'Language code: ln'), 'ln'),
|
||||
Language(71, translate('common.languages', 'Lithuanian', 'Language code: lt'), 'lt'),
|
||||
Language(72, translate('common.languages', 'Macedonian', 'Language code: mk'), 'mk'),
|
||||
Language(73, translate('common.languages', 'Malagasy', 'Language code: mg'), 'mg'),
|
||||
Language(74, translate('common.languages', 'Malay', 'Language code: ms'), 'ms'),
|
||||
Language(75, translate('common.languages', 'Malayalam', 'Language code: ml'), 'ml'),
|
||||
Language(76, translate('common.languages', 'Maltese', 'Language code: mt'), 'mt'),
|
||||
Language(148, translate('common.languages', 'Mam', 'Language code: mam'), 'mam'),
|
||||
Language(77, translate('common.languages', 'Maori', 'Language code: mi'), 'mi'),
|
||||
Language(147, translate('common.languages', 'Maori', 'Language code: mri'), 'mri'),
|
||||
Language(78, translate('common.languages', 'Marathi', 'Language code: mr'), 'mr'),
|
||||
Language(79, translate('common.languages', 'Moldavian', 'Language code: mo'), 'mo'),
|
||||
Language(80, translate('common.languages', 'Mongolian', 'Language code: mn'), 'mn'),
|
||||
Language(149, translate('common.languages', 'Nahuatl', 'Language code: nah'), 'nah'),
|
||||
Language(81, translate('common.languages', 'Nauru', 'Language code: na'), 'na'),
|
||||
Language(82, translate('common.languages', 'Nepali', 'Language code: ne'), 'ne'),
|
||||
Language(83, translate('common.languages', 'Norwegian', 'Language code: no'), 'no'),
|
||||
Language(84, translate('common.languages', 'Occitan', 'Language code: oc'), 'oc'),
|
||||
Language(85, translate('common.languages', 'Oriya', 'Language code: or'), 'or'),
|
||||
Language(86, translate('common.languages', 'Pashto, Pushto', 'Language code: ps'), 'ps'),
|
||||
Language(87, translate('common.languages', 'Persian', 'Language code: fa'), 'fa'),
|
||||
Language(151, translate('common.languages', 'Plautdietsch', 'Language code: pdt'), 'pdt'),
|
||||
Language(88, translate('common.languages', 'Polish', 'Language code: pl'), 'pl'),
|
||||
Language(89, translate('common.languages', 'Portuguese', 'Language code: pt'), 'pt'),
|
||||
Language(90, translate('common.languages', 'Punjabi', 'Language code: pa'), 'pa'),
|
||||
Language(91, translate('common.languages', 'Quechua', 'Language code: qu'), 'qu'),
|
||||
Language(92, translate('common.languages', 'Rhaeto-Romance', 'Language code: rm'), 'rm'),
|
||||
Language(93, translate('common.languages', 'Romanian', 'Language code: ro'), 'ro'),
|
||||
Language(94, translate('common.languages', 'Russian', 'Language code: ru'), 'ru'),
|
||||
Language(95, translate('common.languages', 'Samoan', 'Language code: sm'), 'sm'),
|
||||
Language(96, translate('common.languages', 'Sangro', 'Language code: sg'), 'sg'),
|
||||
Language(97, translate('common.languages', 'Sanskrit', 'Language code: sa'), 'sa'),
|
||||
Language(98, translate('common.languages', 'Scots Gaelic', 'Language code: gd'), 'gd'),
|
||||
Language(99, translate('common.languages', 'Serbian', 'Language code: sr'), 'sr'),
|
||||
Language(100, translate('common.languages', 'Serbo-Croatian', 'Language code: sh'), 'sh'),
|
||||
Language(101, translate('common.languages', 'Sesotho', 'Language code: st'), 'st'),
|
||||
Language(102, translate('common.languages', 'Setswana', 'Language code: tn'), 'tn'),
|
||||
Language(103, translate('common.languages', 'Shona', 'Language code: sn'), 'sn'),
|
||||
Language(104, translate('common.languages', 'Sindhi', 'Language code: sd'), 'sd'),
|
||||
Language(105, translate('common.languages', 'Singhalese', 'Language code: si'), 'si'),
|
||||
Language(106, translate('common.languages', 'Siswati', 'Language code: ss'), 'ss'),
|
||||
Language(107, translate('common.languages', 'Slovak', 'Language code: sk'), 'sk'),
|
||||
Language(108, translate('common.languages', 'Slovenian', 'Language code: sl'), 'sl'),
|
||||
Language(109, translate('common.languages', 'Somali', 'Language code: so'), 'so'),
|
||||
Language(110, translate('common.languages', 'Spanish', 'Language code: es'), 'es'),
|
||||
Language(111, translate('common.languages', 'Sudanese', 'Language code: su'), 'su'),
|
||||
Language(112, translate('common.languages', 'Swahili', 'Language code: sw'), 'sw'),
|
||||
Language(113, translate('common.languages', 'Swedish', 'Language code: sv'), 'sv'),
|
||||
Language(114, translate('common.languages', 'Tagalog', 'Language code: tl'), 'tl'),
|
||||
Language(115, translate('common.languages', 'Tajik', 'Language code: tg'), 'tg'),
|
||||
Language(116, translate('common.languages', 'Tamil', 'Language code: ta'), 'ta'),
|
||||
Language(117, translate('common.languages', 'Tatar', 'Language code: tt'), 'tt'),
|
||||
Language(118, translate('common.languages', 'Tegulu', 'Language code: te'), 'te'),
|
||||
Language(119, translate('common.languages', 'Thai', 'Language code: th'), 'th'),
|
||||
Language(120, translate('common.languages', 'Tibetan', 'Language code: bo'), 'bo'),
|
||||
Language(121, translate('common.languages', 'Tigrinya', 'Language code: ti'), 'ti'),
|
||||
Language(122, translate('common.languages', 'Tonga', 'Language code: to'), 'to'),
|
||||
Language(123, translate('common.languages', 'Tsonga', 'Language code: ts'), 'ts'),
|
||||
Language(124, translate('common.languages', 'Turkish', 'Language code: tr'), 'tr'),
|
||||
Language(125, translate('common.languages', 'Turkmen', 'Language code: tk'), 'tk'),
|
||||
Language(126, translate('common.languages', 'Twi', 'Language code: tw'), 'tw'),
|
||||
Language(127, translate('common.languages', 'Uigur', 'Language code: ug'), 'ug'),
|
||||
Language(128, translate('common.languages', 'Ukrainian', 'Language code: uk'), 'uk'),
|
||||
Language(129, translate('common.languages', 'Urdu', 'Language code: ur'), 'ur'),
|
||||
Language(153, translate('common.languages', 'Uspanteco', 'Language code: usp'), 'usp'),
|
||||
Language(130, translate('common.languages', 'Uzbek', 'Language code: uz'), 'uz'),
|
||||
Language(131, translate('common.languages', 'Vietnamese', 'Language code: vi'), 'vi'),
|
||||
Language(132, translate('common.languages', 'Volapuk', 'Language code: vo'), 'vo'),
|
||||
Language(133, translate('common.languages', 'Welch', 'Language code: cy'), 'cy'),
|
||||
Language(134, translate('common.languages', 'Wolof', 'Language code: wo'), 'wo'),
|
||||
Language(135, translate('common.languages', 'Xhosa', 'Language code: xh'), 'xh'),
|
||||
Language(136, translate('common.languages', 'Yiddish (former ji)', 'Language code: yi'), 'yi'),
|
||||
Language(137, translate('common.languages', 'Yoruba', 'Language code: yo'), 'yo'),
|
||||
Language(138, translate('common.languages', 'Zhuang', 'Language code: za'), 'za'),
|
||||
Language(139, translate('common.languages', 'Zulu', 'Language code: zu'), 'zu')
|
||||
], key=lambda language: language.name)
|
||||
|
||||
|
||||
def get_language(name):
|
||||
"""
|
||||
Find the language by its name or code.
|
||||
|
||||
:param name: The name or abbreviation of the language.
|
||||
:return: The first match as a Language namedtuple or None
|
||||
"""
|
||||
if name:
|
||||
name_lower = name.lower()
|
||||
name_title = name_lower[:1].upper() + name_lower[1:]
|
||||
for language in languages:
|
||||
if language.name == name_title or language.code == name_lower:
|
||||
return language
|
||||
return None
|
@ -23,6 +23,7 @@
|
||||
The :mod:`uistrings` module provides standard strings for OpenLP.
|
||||
"""
|
||||
import logging
|
||||
import itertools
|
||||
|
||||
from openlp.core.common import translate
|
||||
|
||||
@ -155,3 +156,30 @@ class UiStrings(object):
|
||||
self.View = translate('OpenLP.Ui', 'View')
|
||||
self.ViewMode = translate('OpenLP.Ui', 'View Mode')
|
||||
self.Video = translate('OpenLP.Ui', 'Video')
|
||||
self.BibleShortSearchTitle = translate('OpenLP.Ui', 'Search is Empty or too Short')
|
||||
self.BibleShortSearch = translate('OpenLP.Ui', '<strong>The search you have entered is empty or shorter '
|
||||
'than 3 characters long.</strong><br><br>Please try again with '
|
||||
'a longer search.')
|
||||
self.BibleNoBiblesTitle = translate('OpenLP.Ui', 'No Bibles Available')
|
||||
self.BibleNoBibles = translate('OpenLP.Ui', '<strong>There are no Bibles currently installed.</strong><br><br>'
|
||||
'Please use the Import Wizard to install one or more Bibles.')
|
||||
book_chapter = translate('OpenLP.Ui', 'Book Chapter')
|
||||
chapter = translate('OpenLP.Ui', 'Chapter')
|
||||
verse = translate('OpenLP.Ui', 'Verse')
|
||||
gap = ' | '
|
||||
psalm = translate('OpenLP.Ui', 'Psalm')
|
||||
may_shorten = translate('OpenLP.Ui', 'Book names may be shortened from full names, for an example Ps 23 = '
|
||||
'Psalm 23')
|
||||
bible_scripture_items = \
|
||||
[book_chapter, gap, psalm, ' 23<br>',
|
||||
book_chapter, '%(range)s', chapter, gap, psalm, ' 23%(range)s24<br>',
|
||||
book_chapter, '%(verse)s', verse, '%(range)s', verse, gap, psalm, ' 23%(verse)s1%(range)s2<br>',
|
||||
book_chapter, '%(verse)s', verse, '%(range)s', verse, '%(list)s', verse, '%(range)s', verse, gap, psalm,
|
||||
' 23%(verse)s1%(range)s2%(list)s5%(range)s6<br>',
|
||||
book_chapter, '%(verse)s', verse, '%(range)s', verse, '%(list)s', chapter, '%(verse)s', verse, '%(range)s',
|
||||
verse, gap, psalm, ' 23%(verse)s1%(range)s2%(list)s24%(verse)s1%(range)s3<br>',
|
||||
book_chapter, '%(verse)s', verse, '%(range)s', chapter, '%(verse)s', verse, gap, psalm,
|
||||
' 23%(verse)s1%(range)s24%(verse)s1<br><br>', may_shorten]
|
||||
itertools.chain.from_iterable(itertools.repeat(strings, 1) if isinstance(strings, str)
|
||||
else strings for strings in bible_scripture_items)
|
||||
self.BibleScriptureError = ''.join(str(joined) for joined in bible_scripture_items)
|
||||
|
@ -651,6 +651,20 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
||||
item.setFont(font)
|
||||
self.list_view.addItem(item)
|
||||
|
||||
def check_search_result_search_while_typing_short(self):
|
||||
"""
|
||||
This is used in Bible "Search while typing" if the search is shorter than the min required len.
|
||||
"""
|
||||
if self.list_view.count():
|
||||
return
|
||||
message = translate('OpenLP.MediaManagerItem', 'Search is too short to be used in: "Search while typing"')
|
||||
item = QtWidgets.QListWidgetItem(message)
|
||||
item.setFlags(QtCore.Qt.NoItemFlags)
|
||||
font = QtGui.QFont()
|
||||
font.setItalic(True)
|
||||
item.setFont(font)
|
||||
self.list_view.addItem(item)
|
||||
|
||||
def _get_id_of_item_to_generate(self, item, remote_item):
|
||||
"""
|
||||
Utility method to check items being submitted for slide generation.
|
||||
|
@ -167,7 +167,7 @@ class ScreenList(object):
|
||||
|
||||
:param number: The screen number (int).
|
||||
"""
|
||||
log.info('remove_screen {number:d}'.forma(number=number))
|
||||
log.info('remove_screen {number:d}'.format(number=number))
|
||||
for screen in self.screen_list:
|
||||
if screen['number'] == number:
|
||||
self.screen_list.remove(screen)
|
||||
|
@ -474,6 +474,7 @@ class ThemeXML(object):
|
||||
if element.startswith('shadow') or element.startswith('outline'):
|
||||
master = 'font_main'
|
||||
# fix bold font
|
||||
ret_value = None
|
||||
if element == 'weight':
|
||||
element = 'bold'
|
||||
if value == 'Normal':
|
||||
@ -482,7 +483,7 @@ class ThemeXML(object):
|
||||
ret_value = True
|
||||
if element == 'proportion':
|
||||
element = 'size'
|
||||
return False, master, element, ret_value
|
||||
return False, master, element, ret_value if ret_value is not None else value
|
||||
|
||||
def _create_attr(self, master, element, value):
|
||||
"""
|
||||
|
@ -41,7 +41,8 @@ __default_settings__ = {
|
||||
'bibles/db password': '',
|
||||
'bibles/db hostname': '',
|
||||
'bibles/db database': '',
|
||||
'bibles/last search type': BibleSearch.Reference,
|
||||
'bibles/last search type': BibleSearch.Combined,
|
||||
'bibles/reset to combined quick search': True,
|
||||
'bibles/verse layout style': LayoutStyle.VersePerSlide,
|
||||
'bibles/book name language': LanguageSelection.Bible,
|
||||
'bibles/display brackets': DisplayStyle.NoBrackets,
|
||||
@ -59,7 +60,9 @@ __default_settings__ = {
|
||||
'bibles/range separator': '',
|
||||
'bibles/list separator': '',
|
||||
'bibles/end separator': '',
|
||||
'bibles/last directory import': ''
|
||||
'bibles/last directory import': '',
|
||||
'bibles/hide combined quick error': False,
|
||||
'bibles/is search while typing enabled': True
|
||||
}
|
||||
|
||||
|
||||
|
@ -29,9 +29,9 @@ from PyQt5.QtWidgets import QDialog
|
||||
from PyQt5 import QtCore
|
||||
|
||||
from openlp.core.common import translate
|
||||
from openlp.core.common.languages import languages
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.plugins.bibles.forms.languagedialog import Ui_LanguageDialog
|
||||
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -51,11 +51,11 @@ class LanguageForm(QDialog, Ui_LanguageDialog):
|
||||
self.setupUi(self)
|
||||
|
||||
def exec(self, bible_name):
|
||||
self.language_combo_box.addItem('')
|
||||
if bible_name:
|
||||
self.bible_label.setText(str(bible_name))
|
||||
items = BiblesResourcesDB.get_languages()
|
||||
self.language_combo_box.addItems([item['name'] for item in items])
|
||||
self.bible_label.setText(bible_name)
|
||||
self.language_combo_box.addItem('')
|
||||
for language in languages:
|
||||
self.language_combo_box.addItem(language.name, language.id)
|
||||
return QDialog.exec(self)
|
||||
|
||||
def accept(self):
|
||||
|
@ -128,6 +128,20 @@ class BiblesTab(SettingsTab):
|
||||
self.language_selection_layout.addWidget(self.language_selection_label)
|
||||
self.language_selection_layout.addWidget(self.language_selection_combo_box)
|
||||
self.right_layout.addWidget(self.language_selection_group_box)
|
||||
self.bible_quick_settings_group_box = QtWidgets.QGroupBox(self.right_column)
|
||||
self.bible_quick_settings_group_box.setObjectName('bible_quick_settings_group_box')
|
||||
self.right_layout.addWidget(self.bible_quick_settings_group_box)
|
||||
self.search_settings_layout = QtWidgets.QFormLayout(self.bible_quick_settings_group_box)
|
||||
self.search_settings_layout.setObjectName('search_settings_layout')
|
||||
self.reset_to_combined_quick_search_check_box = QtWidgets.QCheckBox(self.bible_quick_settings_group_box)
|
||||
self.reset_to_combined_quick_search_check_box.setObjectName('reset_to_combined_quick_search_check_box')
|
||||
self.search_settings_layout.addRow(self.reset_to_combined_quick_search_check_box)
|
||||
self.hide_combined_quick_error_check_box = QtWidgets.QCheckBox(self.bible_quick_settings_group_box)
|
||||
self.hide_combined_quick_error_check_box.setObjectName('hide_combined_quick_error_check_box')
|
||||
self.search_settings_layout.addRow(self.hide_combined_quick_error_check_box)
|
||||
self.bible_search_while_typing_check_box = QtWidgets.QCheckBox(self.bible_quick_settings_group_box)
|
||||
self.bible_search_while_typing_check_box.setObjectName('bible_search_while_typing_check_box')
|
||||
self.search_settings_layout.addRow(self.bible_search_while_typing_check_box)
|
||||
self.left_layout.addStretch()
|
||||
self.right_layout.addStretch()
|
||||
# Signals and slots
|
||||
@ -151,6 +165,12 @@ class BiblesTab(SettingsTab):
|
||||
self.end_separator_line_edit.editingFinished.connect(self.on_end_separator_line_edit_finished)
|
||||
Registry().register_function('theme_update_list', self.update_theme_list)
|
||||
self.language_selection_combo_box.activated.connect(self.on_language_selection_combo_box_changed)
|
||||
self.reset_to_combined_quick_search_check_box.stateChanged.connect(
|
||||
self.on_reset_to_combined_quick_search_check_box_changed)
|
||||
self.hide_combined_quick_error_check_box.stateChanged.connect(
|
||||
self.on_hide_combined_quick_error_check_box_changed)
|
||||
self.bible_search_while_typing_check_box.stateChanged.connect(
|
||||
self.on_bible_search_while_typing_check_box_changed)
|
||||
|
||||
def retranslateUi(self):
|
||||
self.verse_display_group_box.setTitle(translate('BiblesPlugin.BiblesTab', 'Verse Display'))
|
||||
@ -194,6 +214,17 @@ class BiblesTab(SettingsTab):
|
||||
LanguageSelection.Application, translate('BiblesPlugin.BiblesTab', 'Application Language'))
|
||||
self.language_selection_combo_box.setItemText(
|
||||
LanguageSelection.English, translate('BiblesPlugin.BiblesTab', 'English'))
|
||||
self.bible_quick_settings_group_box.setTitle(translate('BiblesPlugin.BiblesTab', 'Quick Search Settings'))
|
||||
self.reset_to_combined_quick_search_check_box.setText(translate('BiblesPlugin.BiblesTab',
|
||||
'Reset search type to "Text or Scripture'
|
||||
' Reference" on startup'))
|
||||
self.hide_combined_quick_error_check_box.setText(translate('BiblesPlugin.BiblesTab',
|
||||
'Don\'t show error if nothing is found in "Text or '
|
||||
'Scripture Reference"'))
|
||||
self.bible_search_while_typing_check_box.setText(translate('BiblesPlugin.BiblesTab',
|
||||
'Search automatically while typing (Text search must'
|
||||
' contain a\nminimum of {count} characters and a '
|
||||
'space for performance reasons)').format(count='8'))
|
||||
|
||||
def on_bible_theme_combo_box_changed(self):
|
||||
self.bible_theme = self.bible_theme_combo_box.currentText()
|
||||
@ -302,6 +333,24 @@ class BiblesTab(SettingsTab):
|
||||
self.end_separator_line_edit.setText(get_reference_separator('sep_e_default'))
|
||||
self.end_separator_line_edit.setPalette(self.get_grey_text_palette(True))
|
||||
|
||||
def on_reset_to_combined_quick_search_check_box_changed(self, check_state):
|
||||
"""
|
||||
Event handler for the 'hide_combined_quick_error' check box
|
||||
"""
|
||||
self.reset_to_combined_quick_search = (check_state == QtCore.Qt.Checked)
|
||||
|
||||
def on_hide_combined_quick_error_check_box_changed(self, check_state):
|
||||
"""
|
||||
Event handler for the 'hide_combined_quick_error' check box
|
||||
"""
|
||||
self.hide_combined_quick_error = (check_state == QtCore.Qt.Checked)
|
||||
|
||||
def on_bible_search_while_typing_check_box_changed(self, check_state):
|
||||
"""
|
||||
Event handler for the 'hide_combined_quick_error' check box
|
||||
"""
|
||||
self.bible_search_while_typing = (check_state == QtCore.Qt.Checked)
|
||||
|
||||
def load(self):
|
||||
settings = Settings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
@ -355,6 +404,12 @@ class BiblesTab(SettingsTab):
|
||||
self.end_separator_check_box.setChecked(True)
|
||||
self.language_selection = settings.value('book name language')
|
||||
self.language_selection_combo_box.setCurrentIndex(self.language_selection)
|
||||
self.reset_to_combined_quick_search = settings.value('reset to combined quick search')
|
||||
self.reset_to_combined_quick_search_check_box.setChecked(self.reset_to_combined_quick_search)
|
||||
self.hide_combined_quick_error = settings.value('hide combined quick error')
|
||||
self.hide_combined_quick_error_check_box.setChecked(self.hide_combined_quick_error)
|
||||
self.bible_search_while_typing = settings.value('is search while typing enabled')
|
||||
self.bible_search_while_typing_check_box.setChecked(self.bible_search_while_typing)
|
||||
settings.endGroup()
|
||||
|
||||
def save(self):
|
||||
@ -386,6 +441,9 @@ class BiblesTab(SettingsTab):
|
||||
if self.language_selection != settings.value('book name language'):
|
||||
settings.setValue('book name language', self.language_selection)
|
||||
self.settings_form.register_post_process('bibles_load_list')
|
||||
settings.setValue('reset to combined quick search', self.reset_to_combined_quick_search)
|
||||
settings.setValue('hide combined quick error', self.hide_combined_quick_error)
|
||||
settings.setValue('is search while typing enabled', self.bible_search_while_typing)
|
||||
settings.endGroup()
|
||||
if self.tab_visited:
|
||||
self.settings_form.register_post_process('bibles_config_updated')
|
||||
|
@ -128,6 +128,12 @@ class BibleDB(Manager, RegistryProperties):
|
||||
The name of the database. This is also used as the file name for SQLite databases.
|
||||
"""
|
||||
log.info('BibleDB loaded')
|
||||
self._setup(parent, **kwargs)
|
||||
|
||||
def _setup(self, parent, **kwargs):
|
||||
"""
|
||||
Run some initial setup. This method is separate from __init__ in order to mock it out in tests.
|
||||
"""
|
||||
self.bible_plugin = parent
|
||||
self.session = None
|
||||
if 'path' not in kwargs:
|
||||
@ -465,14 +471,13 @@ class BibleDB(Manager, RegistryProperties):
|
||||
"""
|
||||
log.debug('BibleDB.get_language()')
|
||||
from openlp.plugins.bibles.forms import LanguageForm
|
||||
language = None
|
||||
language_id = None
|
||||
language_form = LanguageForm(self.wizard)
|
||||
if language_form.exec(bible_name):
|
||||
language = str(language_form.language_combo_box.currentText())
|
||||
if not language:
|
||||
combo_box = language_form.language_combo_box
|
||||
language_id = combo_box.itemData(combo_box.currentIndex())
|
||||
if not language_id:
|
||||
return False
|
||||
language = BiblesResourcesDB.get_language(language)
|
||||
language_id = language['id']
|
||||
self.save_meta('language_id', language_id)
|
||||
return language_id
|
||||
|
||||
@ -767,43 +772,6 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
||||
return book[0]
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_language(name):
|
||||
"""
|
||||
Return a dict containing the language id, name and code by name or abbreviation.
|
||||
|
||||
:param name: The name or abbreviation of the language.
|
||||
"""
|
||||
log.debug('BiblesResourcesDB.get_language("{name}")'.format(name=name))
|
||||
if not isinstance(name, str):
|
||||
name = str(name)
|
||||
language = BiblesResourcesDB.run_sql(
|
||||
'SELECT id, name, code FROM language WHERE name = ? OR code = ?', (name, name.lower()))
|
||||
if language:
|
||||
return {
|
||||
'id': language[0][0],
|
||||
'name': str(language[0][1]),
|
||||
'code': str(language[0][2])
|
||||
}
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_languages():
|
||||
"""
|
||||
Return a dict containing all languages with id, name and code.
|
||||
"""
|
||||
log.debug('BiblesResourcesDB.get_languages()')
|
||||
languages = BiblesResourcesDB.run_sql('SELECT id, name, code FROM language ORDER by name')
|
||||
if languages:
|
||||
return [{
|
||||
'id': language[0],
|
||||
'name': str(language[1]),
|
||||
'code': str(language[2])
|
||||
} for language in languages]
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_testament_reference():
|
||||
"""
|
||||
|
@ -252,7 +252,7 @@ class BGExtract(RegistryProperties):
|
||||
chapter=chapter,
|
||||
version=version)
|
||||
soup = get_soup_for_bible_ref(
|
||||
'http://legacy.biblegateway.com/passage/?{url}'.format(url=url_params),
|
||||
'http://biblegateway.com/passage/?{url}'.format(url=url_params),
|
||||
pre_parse_regex=r'<meta name.*?/>', pre_parse_substitute='')
|
||||
if not soup:
|
||||
return None
|
||||
@ -281,7 +281,7 @@ class BGExtract(RegistryProperties):
|
||||
"""
|
||||
log.debug('BGExtract.get_books_from_http("{version}")'.format(version=version))
|
||||
url_params = urllib.parse.urlencode({'action': 'getVersionInfo', 'vid': '{version}'.format(version=version)})
|
||||
reference_url = 'http://legacy.biblegateway.com/versions/?{url}#books'.format(url=url_params)
|
||||
reference_url = 'http://biblegateway.com/versions/?{url}#books'.format(url=url_params)
|
||||
page = get_web_page(reference_url)
|
||||
if not page:
|
||||
send_error_message('download')
|
||||
@ -312,7 +312,7 @@ class BGExtract(RegistryProperties):
|
||||
for book in content:
|
||||
book = book.find('td')
|
||||
if book:
|
||||
books.append(book.contents[0])
|
||||
books.append(book.contents[1])
|
||||
return books
|
||||
|
||||
def get_bibles_from_http(self):
|
||||
@ -322,11 +322,11 @@ class BGExtract(RegistryProperties):
|
||||
returns a list in the form [(biblename, biblekey, language_code)]
|
||||
"""
|
||||
log.debug('BGExtract.get_bibles_from_http')
|
||||
bible_url = 'https://legacy.biblegateway.com/versions/'
|
||||
bible_url = 'https://biblegateway.com/versions/'
|
||||
soup = get_soup_for_bible_ref(bible_url)
|
||||
if not soup:
|
||||
return None
|
||||
bible_select = soup.find('select', {'class': 'translation-dropdown'})
|
||||
bible_select = soup.find('select', {'class': 'search-translation-select'})
|
||||
if not bible_select:
|
||||
log.debug('No select tags found - did site change?')
|
||||
return None
|
||||
@ -532,28 +532,26 @@ class CWExtract(RegistryProperties):
|
||||
returns a list in the form [(biblename, biblekey, language_code)]
|
||||
"""
|
||||
log.debug('CWExtract.get_bibles_from_http')
|
||||
bible_url = 'http://www.biblestudytools.com/'
|
||||
bible_url = 'http://www.biblestudytools.com/bible-versions/'
|
||||
soup = get_soup_for_bible_ref(bible_url)
|
||||
if not soup:
|
||||
return None
|
||||
bible_select = soup.find('select')
|
||||
if not bible_select:
|
||||
log.debug('No select tags found - did site change?')
|
||||
return None
|
||||
option_tags = bible_select.find_all('option', {'class': 'log-translation'})
|
||||
if not option_tags:
|
||||
log.debug('No option tags found - did site change?')
|
||||
h4_tags = soup.find_all('h4', {'class': 'small-header'})
|
||||
if not h4_tags:
|
||||
log.debug('No h4 tags found - did site change?')
|
||||
return None
|
||||
bibles = []
|
||||
for ot in option_tags:
|
||||
tag_text = ot.get_text().strip()
|
||||
try:
|
||||
tag_value = ot['value']
|
||||
except KeyError:
|
||||
log.exception('No value attribute found - did site change?')
|
||||
for h4t in h4_tags:
|
||||
short_name = None
|
||||
if h4t.span:
|
||||
short_name = h4t.span.get_text().strip().lower()
|
||||
else:
|
||||
log.error('No span tag found - did site change?')
|
||||
return None
|
||||
if not tag_value:
|
||||
if not short_name:
|
||||
continue
|
||||
h4t.span.extract()
|
||||
tag_text = h4t.get_text().strip()
|
||||
# The names of non-english bibles has their language in parentheses at the end
|
||||
if tag_text.endswith(')'):
|
||||
language = tag_text[tag_text.rfind('(') + 1:-1]
|
||||
@ -561,12 +559,20 @@ class CWExtract(RegistryProperties):
|
||||
language_code = CROSSWALK_LANGUAGES[language]
|
||||
else:
|
||||
language_code = ''
|
||||
# ... except for the latin vulgate
|
||||
# ... except for those that don't...
|
||||
elif 'latin' in tag_text.lower():
|
||||
language_code = 'la'
|
||||
elif 'la biblia' in tag_text.lower() or 'nueva' in tag_text.lower():
|
||||
language_code = 'es'
|
||||
elif 'chinese' in tag_text.lower():
|
||||
language_code = 'zh'
|
||||
elif 'greek' in tag_text.lower():
|
||||
language_code = 'el'
|
||||
elif 'nova' in tag_text.lower():
|
||||
language_code = 'pt'
|
||||
else:
|
||||
language_code = 'en'
|
||||
bibles.append((tag_text, tag_value, language_code))
|
||||
bibles.append((tag_text, short_name, language_code))
|
||||
return bibles
|
||||
|
||||
|
||||
|
@ -23,8 +23,8 @@
|
||||
import logging
|
||||
import os
|
||||
|
||||
from openlp.core.common import RegistryProperties, AppLocation, Settings, translate, delete_file
|
||||
from openlp.plugins.bibles.lib import parse_reference, get_reference_separator, LanguageSelection
|
||||
from openlp.core.common import RegistryProperties, AppLocation, Settings, translate, delete_file, UiStrings
|
||||
from openlp.plugins.bibles.lib import parse_reference, LanguageSelection
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
|
||||
from .csvbible import CSVBible
|
||||
from .http import HTTPBible
|
||||
@ -267,42 +267,21 @@ class BibleManager(RegistryProperties):
|
||||
For second bible this is necessary.
|
||||
:param show_error:
|
||||
"""
|
||||
# If no bibles are installed, message is given.
|
||||
log.debug('BibleManager.get_verses("{bible}", "{verse}")'.format(bible=bible, verse=verse_text))
|
||||
if not bible:
|
||||
if show_error:
|
||||
self.main_window.information_message(
|
||||
translate('BiblesPlugin.BibleManager', 'No Bibles Available'),
|
||||
translate('BiblesPlugin.BibleManager', 'There are no Bibles currently installed. Please use the '
|
||||
'Import Wizard to install one or more Bibles.')
|
||||
)
|
||||
UiStrings().BibleNoBiblesTitle,
|
||||
UiStrings().BibleNoBibles)
|
||||
return None
|
||||
# Get the language for books.
|
||||
language_selection = self.get_language_selection(bible)
|
||||
ref_list = parse_reference(verse_text, self.db_cache[bible], language_selection, book_ref_id)
|
||||
if ref_list:
|
||||
return self.db_cache[bible].get_verses(ref_list, show_error)
|
||||
# If nothing is found. Message is given if this is not combined search. (defined in mediaitem.py)
|
||||
else:
|
||||
if show_error:
|
||||
reference_separators = {
|
||||
'verse': get_reference_separator('sep_v_display'),
|
||||
'range': get_reference_separator('sep_r_display'),
|
||||
'list': get_reference_separator('sep_l_display')}
|
||||
self.main_window.information_message(
|
||||
translate('BiblesPlugin.BibleManager', 'Scripture Reference Error'),
|
||||
translate('BiblesPlugin.BibleManager', 'Your scripture reference is either not supported by '
|
||||
'OpenLP or is invalid. Please make sure your reference '
|
||||
'conforms to one of the following patterns or consult the manual:\n\n'
|
||||
'Book Chapter\n'
|
||||
'Book Chapter%(range)sChapter\n'
|
||||
'Book Chapter%(verse)sVerse%(range)sVerse\n'
|
||||
'Book Chapter%(verse)sVerse%(range)sVerse%(list)sVerse'
|
||||
'%(range)sVerse\n'
|
||||
'Book Chapter%(verse)sVerse%(range)sVerse%(list)sChapter'
|
||||
'%(verse)sVerse%(range)sVerse\n'
|
||||
'Book Chapter%(verse)sVerse%(range)sChapter%(verse)sVerse',
|
||||
'Please pay attention to the appended "s" of the wildcards '
|
||||
'and refrain from translating the words inside the names in the brackets.')
|
||||
% reference_separators
|
||||
)
|
||||
return None
|
||||
|
||||
def get_language_selection(self, bible):
|
||||
@ -334,13 +313,11 @@ class BibleManager(RegistryProperties):
|
||||
:param text: The text to search for (unicode).
|
||||
"""
|
||||
log.debug('BibleManager.verse_search("{bible}", "{text}")'.format(bible=bible, text=text))
|
||||
# If no bibles are installed, message is given.
|
||||
if not bible:
|
||||
self.main_window.information_message(
|
||||
translate('BiblesPlugin.BibleManager', 'No Bibles Available'),
|
||||
translate('BiblesPlugin.BibleManager',
|
||||
'There are no Bibles currently installed. Please use the Import Wizard to install one or '
|
||||
'more Bibles.')
|
||||
)
|
||||
UiStrings().BibleNoBiblesTitle,
|
||||
UiStrings().BibleNoBibles)
|
||||
return None
|
||||
# Check if the bible or second_bible is a web bible.
|
||||
web_bible = self.db_cache[bible].get_object(BibleMeta, 'download_source')
|
||||
@ -348,20 +325,56 @@ class BibleManager(RegistryProperties):
|
||||
if second_bible:
|
||||
second_web_bible = self.db_cache[second_bible].get_object(BibleMeta, 'download_source')
|
||||
if web_bible or second_web_bible:
|
||||
# If either Bible is Web, cursor is reset to normal and message is given.
|
||||
self.application.set_normal_cursor()
|
||||
self.main_window.information_message(
|
||||
translate('BiblesPlugin.BibleManager', 'Web Bible cannot be used'),
|
||||
translate('BiblesPlugin.BibleManager', 'Text Search is not available with Web Bibles.')
|
||||
translate('BiblesPlugin.BibleManager', 'Web Bible cannot be used in Text Search'),
|
||||
translate('BiblesPlugin.BibleManager', 'Text Search is not available with Web Bibles.\n'
|
||||
'Please use the Scripture Reference Search instead.\n\n'
|
||||
'This means that the currently used Bible\nor Second Bible '
|
||||
'is installed as Web Bible.\n\n'
|
||||
'If you were trying to perform a Reference search\nin Combined '
|
||||
'Search, your reference is invalid.')
|
||||
)
|
||||
return None
|
||||
if text:
|
||||
# Shorter than 3 char searches break OpenLP with very long search times, thus they are blocked.
|
||||
if len(text) - text.count(' ') < 3:
|
||||
return None
|
||||
# Fetch the results from db. If no results are found, return None, no message is given for this.
|
||||
elif text:
|
||||
return self.db_cache[bible].verse_search(text)
|
||||
else:
|
||||
return None
|
||||
|
||||
def verse_search_while_typing(self, bible, second_bible, text):
|
||||
"""
|
||||
Does a verse search for the given bible and text.
|
||||
This is used during "Search while typing"
|
||||
It's the same thing as the normal text search, but it does not show the web Bible error.
|
||||
(It would result in the error popping every time a char is entered or removed)
|
||||
It also does not have a minimum text len, this is set in mediaitem.py
|
||||
|
||||
:param bible: The bible to search in (unicode).
|
||||
:param second_bible: The second bible (unicode). We do not search in this bible.
|
||||
:param text: The text to search for (unicode).
|
||||
"""
|
||||
# If no bibles are installed, message is given.
|
||||
if not bible:
|
||||
return None
|
||||
# Check if the bible or second_bible is a web bible.
|
||||
web_bible = self.db_cache[bible].get_object(BibleMeta, 'download_source')
|
||||
second_web_bible = ''
|
||||
if second_bible:
|
||||
second_web_bible = self.db_cache[second_bible].get_object(BibleMeta, 'download_source')
|
||||
if web_bible or second_web_bible:
|
||||
# If either Bible is Web, cursor is reset to normal and search ends w/o any message.
|
||||
self.check_search_result()
|
||||
self.application.set_normal_cursor()
|
||||
return None
|
||||
# Fetch the results from db. If no results are found, return None, no message is given for this.
|
||||
elif text:
|
||||
return self.db_cache[bible].verse_search(text)
|
||||
else:
|
||||
self.main_window.information_message(
|
||||
translate('BiblesPlugin.BibleManager', 'Scripture Reference Error'),
|
||||
translate('BiblesPlugin.BibleManager', 'You did not enter a search keyword.\nYou can separate '
|
||||
'different keywords by a space to search for all of your keywords and you can separate '
|
||||
'them by a comma to search for one of them.')
|
||||
)
|
||||
return None
|
||||
|
||||
def save_meta_data(self, bible, version, copyright, permissions, book_name_language=None):
|
||||
|
@ -35,6 +35,7 @@ from openlp.plugins.bibles.forms.editbibleform import EditBibleForm
|
||||
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, VerseReferenceList, get_reference_separator, \
|
||||
LanguageSelection, BibleStrings
|
||||
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
|
||||
import re
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -45,6 +46,7 @@ class BibleSearch(object):
|
||||
"""
|
||||
Reference = 1
|
||||
Text = 2
|
||||
Combined = 3
|
||||
|
||||
|
||||
class BibleMediaItem(MediaManagerItem):
|
||||
@ -56,6 +58,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
log.info('Bible Media Item loaded')
|
||||
|
||||
def __init__(self, parent, plugin):
|
||||
self.clear_icon = build_icon(':/bibles/bibles_search_clear.png')
|
||||
self.lock_icon = build_icon(':/bibles/bibles_search_lock.png')
|
||||
self.unlock_icon = build_icon(':/bibles/bibles_search_unlock.png')
|
||||
MediaManagerItem.__init__(self, parent, plugin)
|
||||
@ -157,10 +160,15 @@ class BibleMediaItem(MediaManagerItem):
|
||||
search_button_layout = QtWidgets.QHBoxLayout()
|
||||
search_button_layout.setObjectName(prefix + 'search_button_layout')
|
||||
search_button_layout.addStretch()
|
||||
# Note: If we use QPushButton instead of the QToolButton, the icon will be larger than the Lock icon.
|
||||
clear_button = QtWidgets.QToolButton(tab)
|
||||
clear_button.setIcon(self.clear_icon)
|
||||
clear_button.setObjectName(prefix + 'ClearButton')
|
||||
lock_button = QtWidgets.QToolButton(tab)
|
||||
lock_button.setIcon(self.unlock_icon)
|
||||
lock_button.setCheckable(True)
|
||||
lock_button.setObjectName(prefix + 'LockButton')
|
||||
search_button_layout.addWidget(clear_button)
|
||||
search_button_layout.addWidget(lock_button)
|
||||
search_button = QtWidgets.QPushButton(tab)
|
||||
search_button.setObjectName(prefix + 'SearchButton')
|
||||
@ -176,6 +184,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
setattr(self, prefix + 'SecondComboBox', second_combo_box)
|
||||
setattr(self, prefix + 'StyleLabel', style_label)
|
||||
setattr(self, prefix + 'StyleComboBox', style_combo_box)
|
||||
setattr(self, prefix + 'ClearButton', clear_button)
|
||||
setattr(self, prefix + 'LockButton', lock_button)
|
||||
setattr(self, prefix + 'SearchButtonLayout', search_button_layout)
|
||||
setattr(self, prefix + 'SearchButton', search_button)
|
||||
@ -245,11 +254,14 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.quickStyleComboBox.activated.connect(self.on_quick_style_combo_box_changed)
|
||||
self.advancedStyleComboBox.activated.connect(self.on_advanced_style_combo_box_changed)
|
||||
# Buttons
|
||||
self.advancedClearButton.clicked.connect(self.on_clear_button)
|
||||
self.quickClearButton.clicked.connect(self.on_clear_button)
|
||||
self.advancedSearchButton.clicked.connect(self.on_advanced_search_button)
|
||||
self.quickSearchButton.clicked.connect(self.on_quick_search_button)
|
||||
# Other stuff
|
||||
self.quick_search_edit.returnPressed.connect(self.on_quick_search_button)
|
||||
self.search_tab_bar.currentChanged.connect(self.on_search_tab_bar_current_changed)
|
||||
self.quick_search_edit.textChanged.connect(self.on_search_text_edit_changed)
|
||||
|
||||
def on_focus(self):
|
||||
if self.quickTab.isVisible():
|
||||
@ -286,6 +298,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.quickStyleComboBox.setItemText(LayoutStyle.VersePerSlide, UiStrings().VersePerSlide)
|
||||
self.quickStyleComboBox.setItemText(LayoutStyle.VersePerLine, UiStrings().VersePerLine)
|
||||
self.quickStyleComboBox.setItemText(LayoutStyle.Continuous, UiStrings().Continuous)
|
||||
self.quickClearButton.setToolTip(translate('BiblesPlugin.MediaItem', 'Clear the search results.'))
|
||||
self.quickLockButton.setToolTip(translate('BiblesPlugin.MediaItem',
|
||||
'Toggle to keep or clear the previous results.'))
|
||||
self.quickSearchButton.setText(UiStrings().Search)
|
||||
@ -300,6 +313,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.advancedStyleComboBox.setItemText(LayoutStyle.VersePerSlide, UiStrings().VersePerSlide)
|
||||
self.advancedStyleComboBox.setItemText(LayoutStyle.VersePerLine, UiStrings().VersePerLine)
|
||||
self.advancedStyleComboBox.setItemText(LayoutStyle.Continuous, UiStrings().Continuous)
|
||||
self.advancedClearButton.setToolTip(translate('BiblesPlugin.MediaItem', 'Clear the search results.'))
|
||||
self.advancedLockButton.setToolTip(translate('BiblesPlugin.MediaItem',
|
||||
'Toggle to keep or clear the previous results.'))
|
||||
self.advancedSearchButton.setText(UiStrings().Search)
|
||||
@ -309,6 +323,9 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.plugin.manager.media = self
|
||||
self.load_bibles()
|
||||
self.quick_search_edit.set_search_types([
|
||||
(BibleSearch.Combined, ':/bibles/bibles_search_combined.png',
|
||||
translate('BiblesPlugin.MediaItem', 'Text or Reference'),
|
||||
translate('BiblesPlugin.MediaItem', 'Text or Reference...')),
|
||||
(BibleSearch.Reference, ':/bibles/bibles_search_reference.png',
|
||||
translate('BiblesPlugin.MediaItem', 'Scripture Reference'),
|
||||
translate('BiblesPlugin.MediaItem', 'Search Scripture Reference...')),
|
||||
@ -424,18 +441,24 @@ class BibleMediaItem(MediaManagerItem):
|
||||
def update_auto_completer(self):
|
||||
"""
|
||||
This updates the bible book completion list for the search field. The completion depends on the bible. It is
|
||||
only updated when we are doing a reference search, otherwise the auto completion list is removed.
|
||||
only updated when we are doing reference or combined search, in text search the completion list is removed.
|
||||
"""
|
||||
log.debug('update_auto_completer')
|
||||
# Save the current search type to the configuration.
|
||||
# Save the current search type to the configuration. If setting for automatically resetting the search type to
|
||||
# Combined is enabled, use that otherwise use the currently selected search type.
|
||||
# Note: This setting requires a restart to take effect.
|
||||
if Settings().value(self.settings_section + '/reset to combined quick search'):
|
||||
Settings().setValue('{section}/last search type'.format(section=self.settings_section),
|
||||
BibleSearch.Combined)
|
||||
else:
|
||||
Settings().setValue('{section}/last search type'.format(section=self.settings_section),
|
||||
self.quick_search_edit.current_search_type())
|
||||
# Save the current bible to the configuration.
|
||||
Settings().setValue('{section}/quick bible'.format(section=self.settings_section),
|
||||
self.quickVersionComboBox.currentText())
|
||||
books = []
|
||||
# We have to do a 'Reference Search'.
|
||||
if self.quick_search_edit.current_search_type() == BibleSearch.Reference:
|
||||
# We have to do a 'Reference Search' (Or as part of Combined Search).
|
||||
if self.quick_search_edit.current_search_type() is not BibleSearch.Text:
|
||||
bibles = self.plugin.manager.get_bibles()
|
||||
bible = self.quickVersionComboBox.currentText()
|
||||
if bible:
|
||||
@ -525,7 +548,15 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.advancedTab.setVisible(True)
|
||||
self.advanced_book_combo_box.setFocus()
|
||||
|
||||
def on_clear_button(self):
|
||||
# Clear the list, then set the "No search Results" message, then clear the text field and give it focus.
|
||||
self.list_view.clear()
|
||||
self.check_search_result()
|
||||
self.quick_search_edit.clear()
|
||||
self.quick_search_edit.setFocus()
|
||||
|
||||
def on_lock_button_toggled(self, checked):
|
||||
self.quick_search_edit.setFocus()
|
||||
if checked:
|
||||
self.sender().setIcon(self.lock_icon)
|
||||
else:
|
||||
@ -652,33 +683,53 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.check_search_result()
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def on_quick_search_button(self):
|
||||
def on_quick_reference_search(self):
|
||||
"""
|
||||
Does a quick search and saves the search results. Quick search can either be "Reference Search" or
|
||||
"Text Search".
|
||||
We are doing a 'Reference Search'.
|
||||
This search is called on def on_quick_search_button by Quick Reference and Combined Searches.
|
||||
"""
|
||||
log.debug('Quick Search Button clicked')
|
||||
self.quickSearchButton.setEnabled(False)
|
||||
self.application.process_events()
|
||||
# Set Bibles to use the text input from Quick search field.
|
||||
bible = self.quickVersionComboBox.currentText()
|
||||
second_bible = self.quickSecondComboBox.currentText()
|
||||
"""
|
||||
Get input from field and replace 'A-Z + . ' with ''
|
||||
This will check if field has any '.' after A-Z and removes them. Eg. Gen. 1 = Ge 1 = Genesis 1
|
||||
If Book name has '.' after number. eg. 1. Genesis, the search fails without the dot, and vice versa.
|
||||
A better solution would be to make '.' optional in the search results. Current solution was easier to code.
|
||||
"""
|
||||
text = self.quick_search_edit.text()
|
||||
if self.quick_search_edit.current_search_type() == BibleSearch.Reference:
|
||||
# We are doing a 'Reference Search'.
|
||||
text = re.sub('\D[.]\s', ' ', text)
|
||||
# This is triggered on reference search, use the search from manager.py
|
||||
if self.quick_search_edit.current_search_type() != BibleSearch.Text:
|
||||
self.search_results = self.plugin.manager.get_verses(bible, text)
|
||||
if second_bible and self.search_results:
|
||||
self.second_search_results = \
|
||||
self.plugin.manager.get_verses(second_bible, text, self.search_results[0].book.book_reference_id)
|
||||
else:
|
||||
# We are doing a 'Text Search'.
|
||||
|
||||
def on_quick_text_search(self):
|
||||
"""
|
||||
We are doing a 'Text Search'.
|
||||
This search is called on def on_quick_search_button by Quick Text and Combined Searches.
|
||||
"""
|
||||
# Set Bibles to use the text input from Quick search field.
|
||||
bible = self.quickVersionComboBox.currentText()
|
||||
second_bible = self.quickSecondComboBox.currentText()
|
||||
text = self.quick_search_edit.text()
|
||||
# If Text search ends with "," OpenLP will crash, prevent this from happening by removing all ","s.
|
||||
text = re.sub('[,]', '', text)
|
||||
self.application.set_busy_cursor()
|
||||
# Get Bibles list
|
||||
bibles = self.plugin.manager.get_bibles()
|
||||
# Add results to "search_results"
|
||||
self.search_results = self.plugin.manager.verse_search(bible, second_bible, text)
|
||||
if second_bible and self.search_results:
|
||||
# new_search_results is needed to make sure 2nd bible contains all verses. (And counting them on error)
|
||||
text = []
|
||||
new_search_results = []
|
||||
count = 0
|
||||
passage_not_found = False
|
||||
# Search second bible for results of search_results to make sure everythigns there.
|
||||
# Count all the unfound passages.
|
||||
for verse in self.search_results:
|
||||
db_book = bibles[second_bible].get_book_by_book_ref_id(verse.book.book_reference_id)
|
||||
if not db_book:
|
||||
@ -690,15 +741,132 @@ class BibleMediaItem(MediaManagerItem):
|
||||
new_search_results.append(verse)
|
||||
text.append((verse.book.book_reference_id, verse.chapter, verse.verse, verse.verse))
|
||||
if passage_not_found:
|
||||
QtWidgets.QMessageBox.information(
|
||||
self, translate('BiblesPlugin.MediaItem', 'Information'),
|
||||
translate('BiblesPlugin.MediaItem',
|
||||
'The second Bible does not contain all the verses that are in the main Bible. '
|
||||
'Only verses found in both Bibles will be shown. {count:d} verses have not been '
|
||||
'included in the results.').format(count=count),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
|
||||
# This is for the 2nd Bible.
|
||||
self.main_window.information_message(
|
||||
translate('BiblesPlugin.MediaItem', 'Information'),
|
||||
translate('BiblesPlugin.MediaItem', 'The second Bible does not contain all the verses '
|
||||
'that are in the main Bible.\nOnly verses found in both Bibles'
|
||||
' will be shown.\n\n{count:d} verses have not been included '
|
||||
'in the results.').format(count=count))
|
||||
# Join the searches so only verses that are found on both Bibles are shown.
|
||||
self.search_results = new_search_results
|
||||
self.second_search_results = bibles[second_bible].get_verses(text)
|
||||
|
||||
def on_quick_text_search_while_typing(self):
|
||||
"""
|
||||
We are doing a 'Text Search' while typing
|
||||
Call the verse_search_while_typing from manager.py
|
||||
It does not show web bible errors while typing.
|
||||
(It would result in the error popping every time a char is entered or removed)
|
||||
"""
|
||||
# Set Bibles to use the text input from Quick search field.
|
||||
bible = self.quickVersionComboBox.currentText()
|
||||
second_bible = self.quickSecondComboBox.currentText()
|
||||
text = self.quick_search_edit.text()
|
||||
# If Text search ends with "," OpenLP will crash, prevent this from happening by removing all ","s.
|
||||
text = re.sub('[,]', '', text)
|
||||
self.application.set_busy_cursor()
|
||||
# Get Bibles list
|
||||
bibles = self.plugin.manager.get_bibles()
|
||||
# Add results to "search_results"
|
||||
self.search_results = self.plugin.manager.verse_search_while_typing(bible, second_bible, text)
|
||||
if second_bible and self.search_results:
|
||||
# new_search_results is needed to make sure 2nd bible contains all verses. (And counting them on error)
|
||||
text = []
|
||||
new_search_results = []
|
||||
count = 0
|
||||
passage_not_found = False
|
||||
# Search second bible for results of search_results to make sure everythigns there.
|
||||
# Count all the unfound passages. Even thou no error is shown, this needs to be done or
|
||||
# the code breaks later on.
|
||||
for verse in self.search_results:
|
||||
db_book = bibles[second_bible].get_book_by_book_ref_id(verse.book.book_reference_id)
|
||||
if not db_book:
|
||||
log.debug('Passage ("{versebookname}","{versechapter}","{verseverse}") not found in Second Bible'
|
||||
.format(versebookname=verse.book.name, versechapter='verse.chapter',
|
||||
verseverse=verse.verse))
|
||||
count += 1
|
||||
continue
|
||||
new_search_results.append(verse)
|
||||
text.append((verse.book.book_reference_id, verse.chapter, verse.verse, verse.verse))
|
||||
# Join the searches so only verses that are found on both Bibles are shown.
|
||||
self.search_results = new_search_results
|
||||
self.second_search_results = bibles[second_bible].get_verses(text)
|
||||
|
||||
def on_quick_search_button(self):
|
||||
"""
|
||||
This triggers the proper Quick search based on which search type is used.
|
||||
"Eg. "Reference Search", "Text Search" or "Combined search".
|
||||
"""
|
||||
log.debug('Quick Search Button clicked')
|
||||
self.quickSearchButton.setEnabled(False)
|
||||
self.application.process_events()
|
||||
bible = self.quickVersionComboBox.currentText()
|
||||
second_bible = self.quickSecondComboBox.currentText()
|
||||
text = self.quick_search_edit.text()
|
||||
if self.quick_search_edit.current_search_type() == BibleSearch.Reference:
|
||||
# We are doing a 'Reference Search'. (Get script from def on_quick_reference_search)
|
||||
self.on_quick_reference_search()
|
||||
# Get reference separators from settings.
|
||||
if not self.search_results:
|
||||
reference_separators = {
|
||||
'verse': get_reference_separator('sep_v_display'),
|
||||
'range': get_reference_separator('sep_r_display'),
|
||||
'list': get_reference_separator('sep_l_display')}
|
||||
self.main_window.information_message(
|
||||
translate('BiblesPlugin.BibleManager', 'Scripture Reference Error'),
|
||||
translate('BiblesPlugin.BibleManager', '<strong>OpenLP couldn’t find anything '
|
||||
'with your search.<br><br>'
|
||||
'Please make sure that your reference follows '
|
||||
'one of these patterns:</strong><br><br>%s'
|
||||
% UiStrings().BibleScriptureError % reference_separators))
|
||||
elif self.quick_search_edit.current_search_type() == BibleSearch.Text:
|
||||
# We are doing a 'Text Search'. (Get script from def on_quick_text_search)
|
||||
self.on_quick_text_search()
|
||||
if not self.search_results and len(text) - text.count(' ') < 3 and bible:
|
||||
self.main_window.information_message(
|
||||
UiStrings().BibleShortSearchTitle,
|
||||
UiStrings().BibleShortSearch)
|
||||
elif self.quick_search_edit.current_search_type() == BibleSearch.Combined:
|
||||
# We are doing a 'Combined search'. Starting with reference search.
|
||||
# Perform only if text contains any numbers
|
||||
if (char.isdigit() for char in text):
|
||||
self.on_quick_reference_search()
|
||||
"""
|
||||
If results are found, search will be finalized.
|
||||
This check needs to be here in order to avoid duplicate errors.
|
||||
If keyword is shorter than 3 (not including spaces), message is given. It's actually possible to find
|
||||
verses with less than 3 chars (Eg. G1 = Genesis 1) thus this error is not shown if any results are found.
|
||||
if no Bibles are installed, this message is not shown - "No bibles" message is shown instead.
|
||||
"""
|
||||
if not self.search_results and len(text) - text.count(' ') < 3 and bible:
|
||||
self.main_window.information_message(
|
||||
UiStrings().BibleShortSearchTitle,
|
||||
UiStrings().BibleShortSearch)
|
||||
if not self.search_results and len(text) - text.count(' ') > 2 and bible:
|
||||
# Text search starts here if no reference was found and keyword is longer than 2.
|
||||
# > 2 check is required in order to avoid duplicate error messages for short keywords.
|
||||
self.on_quick_text_search()
|
||||
if not self.search_results and not \
|
||||
Settings().value(self.settings_section + '/hide combined quick error'):
|
||||
self.application.set_normal_cursor()
|
||||
# Reference separators need to be defined both, in here and on reference search,
|
||||
# error won't work if they are left out from one.
|
||||
reference_separators = {
|
||||
'verse': get_reference_separator('sep_v_display'),
|
||||
'range': get_reference_separator('sep_r_display'),
|
||||
'list': get_reference_separator('sep_l_display')}
|
||||
self.main_window.information_message(translate('BiblesPlugin.BibleManager', 'Nothing found'),
|
||||
translate('BiblesPlugin.BibleManager',
|
||||
'<strong>OpenLP couldn’t find anything with your'
|
||||
' search.</strong><br><br>If you tried to search'
|
||||
' with Scripture Reference, please make<br> sure'
|
||||
' that your reference follows one of these'
|
||||
' patterns: <br><br>%s'
|
||||
% UiStrings().BibleScriptureError %
|
||||
reference_separators))
|
||||
# Finalizing the search
|
||||
# List is cleared if not locked, results are listed, button is set available, cursor is set to normal.
|
||||
if not self.quickLockButton.isChecked():
|
||||
self.list_view.clear()
|
||||
if self.list_view.count() != 0 and self.search_results:
|
||||
@ -709,6 +877,99 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.check_search_result()
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def on_quick_search_while_typing(self):
|
||||
"""
|
||||
This function is called when "Search as you type" is enabled for Bibles.
|
||||
It is basically the same thing as "on_quick_search_search" but all the error messages are removed.
|
||||
This also has increased min len for text search for performance reasons.
|
||||
For commented version, please visit def on_quick_search_button.
|
||||
"""
|
||||
bible = self.quickVersionComboBox.currentText()
|
||||
second_bible = self.quickSecondComboBox.currentText()
|
||||
text = self.quick_search_edit.text()
|
||||
if self.quick_search_edit.current_search_type() == BibleSearch.Combined:
|
||||
# If text has no numbers, auto search limit is min 8 characters for performance reasons.
|
||||
# If you change this value, also change it in biblestab.py (Count) in enabling search while typing.
|
||||
if (char.isdigit() for char in text) and len(text) > 2:
|
||||
self.on_quick_reference_search()
|
||||
if not self.search_results and len(text) > 7:
|
||||
self.on_quick_text_search_while_typing()
|
||||
elif self.quick_search_edit.current_search_type() == BibleSearch.Reference:
|
||||
self.on_quick_reference_search()
|
||||
elif self.quick_search_edit.current_search_type() == BibleSearch.Text:
|
||||
if len(text) > 7:
|
||||
self.on_quick_text_search_while_typing()
|
||||
if not self.quickLockButton.isChecked():
|
||||
self.list_view.clear()
|
||||
if self.list_view.count() != 0 and self.search_results:
|
||||
self.__check_second_bible(bible, second_bible)
|
||||
elif self.search_results:
|
||||
self.display_results(bible, second_bible)
|
||||
self.check_search_result()
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def on_search_text_edit_changed(self):
|
||||
"""
|
||||
If search automatically while typing is enabled, perform the search and list results when conditions are met.
|
||||
"""
|
||||
if Settings().value('bibles/is search while typing enabled'):
|
||||
text = self.quick_search_edit.text()
|
||||
"""
|
||||
Use Regex for finding space + number in reference search and space + 2 characters in text search.
|
||||
Also search for two characters (Searches require at least two sets of two characters)
|
||||
These are used to prevent bad search queries from starting. (Long/crashing queries)
|
||||
"""
|
||||
space_and_digit_reference = re.compile(' \d')
|
||||
two_chars_text = re.compile('\S\S')
|
||||
space_and_two_chars_text = re.compile(' \S\S')
|
||||
# Turn this into a format that may be used in if statement.
|
||||
count_space_digit_reference = space_and_digit_reference.findall(text)
|
||||
count_two_chars_text = two_chars_text.findall(text)
|
||||
count_spaces_two_chars_text = space_and_two_chars_text.findall(text)
|
||||
"""
|
||||
The Limit is required for setting the proper "No items found" message.
|
||||
"Limit" is also hard coded to on_quick_search_while_typing, it must be there to avoid bad search
|
||||
performance. Limit 8 = Text search, 3 = Reference search.
|
||||
"""
|
||||
limit = 8
|
||||
if self.quick_search_edit.current_search_type() == BibleSearch.Combined:
|
||||
if len(count_space_digit_reference) != 0:
|
||||
limit = 3
|
||||
elif self.quick_search_edit.current_search_type() == BibleSearch.Reference:
|
||||
limit = 3
|
||||
"""
|
||||
If text is empty, clear the list.
|
||||
else: Start by checking if the search is suitable for "Search while typing"
|
||||
"""
|
||||
if len(text) == 0:
|
||||
if not self.quickLockButton.isChecked():
|
||||
self.list_view.clear()
|
||||
self.check_search_result()
|
||||
else:
|
||||
if limit == 3 and (len(text) < limit or len(count_space_digit_reference) == 0):
|
||||
if not self.quickLockButton.isChecked():
|
||||
self.list_view.clear()
|
||||
self.check_search_result()
|
||||
elif (limit == 8 and (len(text) < limit or len(count_spaces_two_chars_text) == 0 or
|
||||
len(count_two_chars_text) < 2)):
|
||||
if not self.quickLockButton.isChecked():
|
||||
self.list_view.clear()
|
||||
self.check_search_result_search_while_typing_short()
|
||||
else:
|
||||
"""
|
||||
Start search if no chars are entered or deleted for 0.2 s
|
||||
If no Timer is set, Text search will break the search by sending repeative search Quaries on
|
||||
all chars. Use the self.on_quick_search_while_typing, this does not contain any error messages.
|
||||
"""
|
||||
self.search_timer = ()
|
||||
if self.search_timer:
|
||||
self.search_timer.stop()
|
||||
self.search_timer.deleteLater()
|
||||
self.search_timer = QtCore.QTimer()
|
||||
self.search_timer.timeout.connect(self.on_quick_search_while_typing)
|
||||
self.search_timer.setSingleShot(True)
|
||||
self.search_timer.start(200)
|
||||
|
||||
def display_results(self, bible, second_bible=''):
|
||||
"""
|
||||
Displays the search results in the media manager. All data needed for further action is saved for/in each row.
|
||||
|
@ -23,7 +23,7 @@
|
||||
import logging
|
||||
from lxml import etree
|
||||
|
||||
from openlp.core.common import translate, trace_error_handler
|
||||
from openlp.core.common import languages, translate, trace_error_handler
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
|
||||
@ -62,9 +62,11 @@ class OSISBible(BibleDB):
|
||||
namespace = {'ns': 'http://www.bibletechnologies.net/2003/OSIS/namespace'}
|
||||
# Find bible language
|
||||
language_id = None
|
||||
language = osis_bible_tree.xpath("//ns:osisText/@xml:lang", namespaces=namespace)
|
||||
if language:
|
||||
language_id = BiblesResourcesDB.get_language(language[0])
|
||||
lang = osis_bible_tree.xpath("//ns:osisText/@xml:lang", namespaces=namespace)
|
||||
if lang:
|
||||
language = languages.get_language(lang[0])
|
||||
if hasattr(language, 'id'):
|
||||
language_id = language.id
|
||||
# The language couldn't be detected, ask the user
|
||||
if not language_id:
|
||||
language_id = self.get_language(bible_name)
|
||||
|
@ -23,7 +23,7 @@
|
||||
import logging
|
||||
from pysword import modules
|
||||
|
||||
from openlp.core.common import translate
|
||||
from openlp.core.common import languages, translate
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||
|
||||
@ -57,9 +57,12 @@ class SwordBible(BibleDB):
|
||||
pysword_modules = modules.SwordModules(self.sword_path)
|
||||
pysword_module_json = pysword_modules.parse_modules()[self.sword_key]
|
||||
bible = pysword_modules.get_bible_from_module(self.sword_key)
|
||||
language_id = None
|
||||
language = pysword_module_json['lang']
|
||||
language = language[language.find('.') + 1:]
|
||||
language_id = BiblesResourcesDB.get_language(language)['id']
|
||||
language = languages.get_language(language)
|
||||
if hasattr(language, 'id'):
|
||||
language_id = language.id
|
||||
self.save_meta('language_id', language_id)
|
||||
books = bible.get_structure().get_books()
|
||||
# Count number of books
|
||||
|
@ -21,9 +21,9 @@
|
||||
###############################################################################
|
||||
|
||||
import logging
|
||||
from lxml import etree, objectify
|
||||
from lxml import etree
|
||||
|
||||
from openlp.core.common import translate
|
||||
from openlp.core.common import languages, translate
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||
|
||||
@ -62,7 +62,9 @@ class ZefaniaBible(BibleDB):
|
||||
language_id = None
|
||||
language = zefania_bible_tree.xpath("/XMLBIBLE/INFORMATION/language/text()")
|
||||
if language:
|
||||
language_id = BiblesResourcesDB.get_language(language[0])
|
||||
language = languages.get_language(language[0])
|
||||
if hasattr(language, 'id'):
|
||||
language_id = language.id
|
||||
# The language couldn't be detected, ask the user
|
||||
if not language_id:
|
||||
language_id = self.get_language(bible_name)
|
||||
|
Binary file not shown.
@ -46,7 +46,7 @@ class EasySlidesImport(SongImport):
|
||||
|
||||
def do_import(self):
|
||||
log.info('Importing EasySlides XML file {source}'.format(source=self.import_source))
|
||||
parser = etree.XMLParser(remove_blank_text=True)
|
||||
parser = etree.XMLParser(remove_blank_text=True, recover=True)
|
||||
parsed_file = etree.parse(self.import_source, parser)
|
||||
xml = etree.tostring(parsed_file).decode()
|
||||
song_xml = objectify.fromstring(xml)
|
||||
|
@ -73,6 +73,14 @@ class VideoPsalmImport(SongImport):
|
||||
processed_content += c
|
||||
c = next(file_content_it)
|
||||
processed_content += '"' + c
|
||||
# Remove control characters
|
||||
elif (c < chr(32)):
|
||||
processed_content += ' '
|
||||
# Handle escaped characters
|
||||
elif c == '\\':
|
||||
processed_content += c
|
||||
c = next(file_content_it)
|
||||
processed_content += c
|
||||
else:
|
||||
processed_content += c
|
||||
songbook = json.loads(processed_content.strip())
|
||||
|
@ -458,7 +458,7 @@ class OpenLyrics(object):
|
||||
self._add_tag_to_formatting(tag, tags_element)
|
||||
# Replace end tags.
|
||||
for tag in end_tags:
|
||||
text = text.replace('{/{tag}}}'.format(tag=tag), '</tag>')
|
||||
text = text.replace('{{{tag}}}'.format(tag=tag), '</tag>')
|
||||
# Replace \n with <br/>.
|
||||
text = text.replace('\n', '<br/>')
|
||||
element = etree.XML('<lines>{text}</lines>'.format(text=text))
|
||||
@ -643,7 +643,7 @@ class OpenLyrics(object):
|
||||
# Append text from tail and add formatting end tag.
|
||||
# TODO: Verify format() with template variables
|
||||
if element.tag == NSMAP % 'tag' and use_endtag:
|
||||
text += '{/{name}}}'.format(name=element.get('name'))
|
||||
text += '{{{name}}}'.format(name=element.get('name'))
|
||||
# Append text from tail.
|
||||
if element.tail:
|
||||
text += element.tail
|
||||
|
BIN
resources/images/bibles_search_clear.png
Normal file
BIN
resources/images/bibles_search_clear.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
BIN
resources/images/bibles_search_combined.png
Normal file
BIN
resources/images/bibles_search_combined.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
@ -30,9 +30,11 @@
|
||||
<file>image_new_group.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="bibles">
|
||||
<file>bibles_search_combined.png</file>
|
||||
<file>bibles_search_text.png</file>
|
||||
<file>bibles_search_reference.png</file>
|
||||
<file>bibles_upgrade_alert.png</file>
|
||||
<file>bibles_search_clear.png</file>
|
||||
<file>bibles_search_unlock.png</file>
|
||||
<file>bibles_search_lock.png</file>
|
||||
</qresource>
|
||||
|
@ -63,9 +63,10 @@ class OpenLPJobs(object):
|
||||
Branch_Windows_Interface = 'Branch-04b-Windows_Interface_Tests'
|
||||
Branch_PEP = 'Branch-05a-Code_Analysis'
|
||||
Branch_Coverage = 'Branch-05b-Test_Coverage'
|
||||
Branch_Pylint = 'Branch-05c-Code_Analysis2'
|
||||
|
||||
Jobs = [Branch_Pull, Branch_Functional, Branch_Interface, Branch_Windows_Functional, Branch_Windows_Interface,
|
||||
Branch_PEP, Branch_Coverage]
|
||||
Branch_PEP, Branch_Coverage, Branch_Pylint]
|
||||
|
||||
|
||||
class Colour(object):
|
||||
|
109
tests/functional/openlp_core_common/test_languages.py
Normal file
109
tests/functional/openlp_core_common/test_languages.py
Normal file
@ -0,0 +1,109 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 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 #
|
||||
###############################################################################
|
||||
"""
|
||||
Package to test the openlp.core.lib.languages package.
|
||||
"""
|
||||
from unittest import TestCase
|
||||
|
||||
from openlp.core.common import languages
|
||||
|
||||
|
||||
class TestLanguages(TestCase):
|
||||
|
||||
def languages_type_test(self):
|
||||
"""
|
||||
Test the languages variable type
|
||||
"""
|
||||
|
||||
# GIVEN: The languages module
|
||||
# WHEN: Accessing the languages variable
|
||||
# THEN: It should be of type list
|
||||
self.assertIsInstance(languages.languages, list, 'languages.languages should be of type list')
|
||||
|
||||
def language_selection_languages_type_test(self):
|
||||
"""
|
||||
Test the selection of a language
|
||||
"""
|
||||
|
||||
# GIVEN: A list of languages from the languages module
|
||||
# WHEN: Selecting the first item
|
||||
language = languages.languages[0]
|
||||
|
||||
# THEN: It should be an instance of the Language namedtuple
|
||||
self.assertIsInstance(language, languages.Language)
|
||||
self.assertEqual(language.id, 1)
|
||||
self.assertEqual(language.name, '(Afan) Oromo')
|
||||
self.assertEqual(language.code, 'om')
|
||||
|
||||
def get_language_name_test(self):
|
||||
"""
|
||||
Test get_language() when supplied with a language name.
|
||||
"""
|
||||
|
||||
# GIVEN: A language name, in capitals
|
||||
# WHEN: Calling get_language with it
|
||||
language = languages.get_language('YORUBA')
|
||||
|
||||
# THEN: The Language found using that name should be returned
|
||||
self.assertIsInstance(language, languages.Language)
|
||||
self.assertEqual(language.id, 137)
|
||||
self.assertEqual(language.name, 'Yoruba')
|
||||
self.assertEqual(language.code, 'yo')
|
||||
|
||||
def get_language_code_test(self):
|
||||
"""
|
||||
Test get_language() when supplied with a language code.
|
||||
"""
|
||||
|
||||
# GIVEN: A language code in capitals
|
||||
# WHEN: Calling get_language with it
|
||||
language = languages.get_language('IA')
|
||||
|
||||
# THEN: The Language found using that code should be returned
|
||||
self.assertIsInstance(language, languages.Language)
|
||||
self.assertEqual(language.id, 51)
|
||||
self.assertEqual(language.name, 'Interlingua')
|
||||
self.assertEqual(language.code, 'ia')
|
||||
|
||||
def get_language_invalid_test(self):
|
||||
"""
|
||||
Test get_language() when supplied with a string which is not a valid language name or code.
|
||||
"""
|
||||
|
||||
# GIVEN: A language code
|
||||
# WHEN: Calling get_language with it
|
||||
language = languages.get_language('qwerty')
|
||||
|
||||
# THEN: None should be returned
|
||||
self.assertIsNone(language)
|
||||
|
||||
def get_language_invalid__none_test(self):
|
||||
"""
|
||||
Test get_language() when supplied with a string which is not a valid language name or code.
|
||||
"""
|
||||
|
||||
# GIVEN: A language code
|
||||
# WHEN: Calling get_language with it
|
||||
language = languages.get_language(None)
|
||||
|
||||
# THEN: None should be returned
|
||||
self.assertIsNone(language)
|
@ -22,43 +22,82 @@
|
||||
"""
|
||||
Package to test the openlp.core.lib.theme package.
|
||||
"""
|
||||
from tests.functional import MagicMock, patch
|
||||
from unittest import TestCase
|
||||
import os
|
||||
|
||||
from openlp.core.lib.theme import ThemeXML
|
||||
|
||||
|
||||
class TestTheme(TestCase):
|
||||
class TestThemeXML(TestCase):
|
||||
"""
|
||||
Test the functions in the Theme module
|
||||
Test the ThemeXML class
|
||||
"""
|
||||
def setUp(self):
|
||||
"""
|
||||
Create the UI
|
||||
"""
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
"""
|
||||
Delete all the C++ objects at the end so that we don't have a segfault
|
||||
"""
|
||||
pass
|
||||
|
||||
def test_new_theme(self):
|
||||
"""
|
||||
Test the theme creation - basic test
|
||||
Test the ThemeXML constructor
|
||||
"""
|
||||
# GIVEN: A new theme
|
||||
|
||||
# WHEN: A theme is created
|
||||
# GIVEN: The ThemeXML class
|
||||
# WHEN: A theme object is created
|
||||
default_theme = ThemeXML()
|
||||
|
||||
# THEN: We should get some default behaviours
|
||||
self.assertTrue(default_theme.background_border_color == '#000000', 'The theme should have a black border')
|
||||
self.assertTrue(default_theme.background_type == 'solid', 'The theme should have a solid backgrounds')
|
||||
self.assertTrue(default_theme.display_vertical_align == 0,
|
||||
'The theme should have a display_vertical_align of 0')
|
||||
self.assertTrue(default_theme.font_footer_name == "Arial",
|
||||
'The theme should have a font_footer_name of Arial')
|
||||
self.assertTrue(default_theme.font_main_bold is False, 'The theme should have a font_main_bold of false')
|
||||
self.assertTrue(len(default_theme.__dict__) == 47, 'The theme should have 47 variables')
|
||||
# THEN: The default values should be correct
|
||||
self.assertEqual('#000000', default_theme.background_border_color,
|
||||
'background_border_color should be "#000000"')
|
||||
self.assertEqual('solid', default_theme.background_type, 'background_type should be "solid"')
|
||||
self.assertEqual(0, default_theme.display_vertical_align, 'display_vertical_align should be 0')
|
||||
self.assertEqual('Arial', default_theme.font_footer_name, 'font_footer_name should be "Arial"')
|
||||
self.assertFalse(default_theme.font_main_bold, 'font_main_bold should be False')
|
||||
self.assertEqual(47, len(default_theme.__dict__), 'The theme should have 47 attributes')
|
||||
|
||||
def test_expand_json(self):
|
||||
"""
|
||||
Test the expand_json method
|
||||
"""
|
||||
# GIVEN: A ThemeXML object and some JSON to "expand"
|
||||
theme = ThemeXML()
|
||||
theme_json = {
|
||||
'background': {
|
||||
'border_color': '#000000',
|
||||
'type': 'solid'
|
||||
},
|
||||
'display': {
|
||||
'vertical_align': 0
|
||||
},
|
||||
'font': {
|
||||
'footer': {
|
||||
'bold': False
|
||||
},
|
||||
'main': {
|
||||
'name': 'Arial'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# WHEN: ThemeXML.expand_json() is run
|
||||
theme.expand_json(theme_json)
|
||||
|
||||
# THEN: The attributes should be set on the object
|
||||
self.assertEqual('#000000', theme.background_border_color, 'background_border_color should be "#000000"')
|
||||
self.assertEqual('solid', theme.background_type, 'background_type should be "solid"')
|
||||
self.assertEqual(0, theme.display_vertical_align, 'display_vertical_align should be 0')
|
||||
self.assertFalse(theme.font_footer_bold, 'font_footer_bold should be False')
|
||||
self.assertEqual('Arial', theme.font_main_name, 'font_main_name should be "Arial"')
|
||||
|
||||
def test_extend_image_filename(self):
|
||||
"""
|
||||
Test the extend_image_filename method
|
||||
"""
|
||||
# GIVEN: A theme object
|
||||
theme = ThemeXML()
|
||||
theme.theme_name = 'MyBeautifulTheme '
|
||||
theme.background_filename = ' video.mp4'
|
||||
theme.background_type = 'video'
|
||||
path = os.path.expanduser('~')
|
||||
|
||||
# WHEN: ThemeXML.extend_image_filename is run
|
||||
theme.extend_image_filename(path)
|
||||
|
||||
# THEN: The filename of the background should be correct
|
||||
expected_filename = os.path.join(path, 'MyBeautifulTheme', 'video.mp4')
|
||||
self.assertEqual(expected_filename, theme.background_filename)
|
||||
self.assertEqual('MyBeautifulTheme', theme.theme_name)
|
||||
|
87
tests/functional/openlp_plugins/bibles/test_db.py
Normal file
87
tests/functional/openlp_plugins/bibles/test_db.py
Normal file
@ -0,0 +1,87 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 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 db submodule of the Bibles plugin.
|
||||
"""
|
||||
|
||||
from unittest import TestCase
|
||||
|
||||
from openlp.plugins.bibles.lib.db import BibleDB
|
||||
from tests.functional import MagicMock, patch
|
||||
|
||||
|
||||
class TestBibleDB(TestCase):
|
||||
"""
|
||||
Test the functions in the BibleDB class.
|
||||
"""
|
||||
|
||||
def test_get_language_canceled(self):
|
||||
"""
|
||||
Test the BibleDB.get_language method when the user rejects the dialog box
|
||||
"""
|
||||
# GIVEN: A mocked LanguageForm with an exec method which returns QtDialog.Rejected and an instance of BibleDB
|
||||
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'),\
|
||||
patch('openlp.plugins.bibles.forms.LanguageForm') as mocked_language_form:
|
||||
|
||||
# The integer value of QtDialog.Rejected is 0. Using the enumeration causes a seg fault for some reason
|
||||
mocked_language_form_instance = MagicMock(**{'exec.return_value': 0})
|
||||
mocked_language_form.return_value = mocked_language_form_instance
|
||||
mocked_parent = MagicMock()
|
||||
instance = BibleDB(mocked_parent)
|
||||
mocked_wizard = MagicMock()
|
||||
instance.wizard = mocked_wizard
|
||||
|
||||
# WHEN: Calling get_language()
|
||||
result = instance.get_language()
|
||||
|
||||
# THEN: get_language() should return False
|
||||
mocked_language_form.assert_called_once_with(mocked_wizard)
|
||||
mocked_language_form_instance.exec.assert_called_once_with(None)
|
||||
self.assertFalse(result, 'get_language() should return False if the user rejects the dialog box')
|
||||
|
||||
def test_get_language_accepted(self):
|
||||
"""
|
||||
Test the BibleDB.get_language method when the user accepts the dialog box
|
||||
"""
|
||||
# GIVEN: A mocked LanguageForm with an exec method which returns QtDialog.Accepted an instance of BibleDB and
|
||||
# a combobox with the selected item data as 10
|
||||
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'), \
|
||||
patch('openlp.plugins.bibles.lib.db.BibleDB.save_meta'), \
|
||||
patch('openlp.plugins.bibles.forms.LanguageForm') as mocked_language_form:
|
||||
|
||||
# The integer value of QtDialog.Accepted is 1. Using the enumeration causes a seg fault for some reason
|
||||
mocked_language_form_instance = MagicMock(**{'exec.return_value': 1,
|
||||
'language_combo_box.itemData.return_value': 10})
|
||||
mocked_language_form.return_value = mocked_language_form_instance
|
||||
mocked_parent = MagicMock()
|
||||
instance = BibleDB(mocked_parent)
|
||||
mocked_wizard = MagicMock()
|
||||
instance.wizard = mocked_wizard
|
||||
|
||||
# WHEN: Calling get_language()
|
||||
result = instance.get_language('Bible Name')
|
||||
|
||||
# THEN: get_language() should return the id of the selected language in the combo box
|
||||
mocked_language_form.assert_called_once_with(mocked_wizard)
|
||||
mocked_language_form_instance.exec.assert_called_once_with('Bible Name')
|
||||
self.assertEqual(result, 10, 'get_language() should return the id of the language the user has chosen when '
|
||||
'they accept the dialog box')
|
@ -23,6 +23,7 @@
|
||||
This module contains tests for the lib submodule of the Presentations plugin.
|
||||
"""
|
||||
from unittest import TestCase
|
||||
from openlp.core.common import Registry
|
||||
from openlp.plugins.bibles.lib.mediaitem import BibleMediaItem
|
||||
from tests.functional import MagicMock, patch
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
@ -41,6 +42,9 @@ class TestMediaItem(TestCase, TestMixin):
|
||||
patch('openlp.plugins.bibles.lib.mediaitem.BibleMediaItem.setup_item'):
|
||||
self.media_item = BibleMediaItem(None, MagicMock())
|
||||
self.setup_application()
|
||||
self.mocked_main_window = MagicMock()
|
||||
Registry.create()
|
||||
Registry().register('main_window', self.mocked_main_window)
|
||||
|
||||
def test_display_results_no_results(self):
|
||||
"""
|
||||
@ -109,3 +113,40 @@ class TestMediaItem(TestCase, TestMixin):
|
||||
mocked_list_view.selectAll.assert_called_once_with()
|
||||
self.assertEqual(self.media_item.search_results, {})
|
||||
self.assertEqual(self.media_item.second_search_results, {})
|
||||
|
||||
def on_quick_search_button_general_test(self):
|
||||
"""
|
||||
Test that general things, which should be called on all Quick searches are called.
|
||||
"""
|
||||
|
||||
# GIVEN: self.application as self.app, all the required functions
|
||||
Registry.create()
|
||||
Registry().register('application', self.app)
|
||||
self.media_item.quickSearchButton = MagicMock()
|
||||
self.app.process_events = MagicMock()
|
||||
self.media_item.quickVersionComboBox = MagicMock()
|
||||
self.media_item.quickVersionComboBox.currentText = MagicMock()
|
||||
self.media_item.quickSecondComboBox = MagicMock()
|
||||
self.media_item.quickSecondComboBox.currentText = MagicMock()
|
||||
self.media_item.quick_search_edit = MagicMock()
|
||||
self.media_item.quick_search_edit.text = MagicMock()
|
||||
self.media_item.quickLockButton = MagicMock()
|
||||
self.media_item.list_view = MagicMock()
|
||||
self.media_item.search_results = MagicMock()
|
||||
self.media_item.display_results = MagicMock()
|
||||
self.media_item.check_search_result = MagicMock()
|
||||
self.app.set_normal_cursor = MagicMock()
|
||||
|
||||
# WHEN: on_quick_search_button is called
|
||||
self.media_item.on_quick_search_button()
|
||||
|
||||
# THEN: Search should had been started and finalized properly
|
||||
self.assertEqual(1, self.app.process_events.call_count, 'Normal cursor should had been called once')
|
||||
self.assertEqual(1, self.media_item.quickVersionComboBox.currentText.call_count, 'Should had been called once')
|
||||
self.assertEqual(1, self.media_item.quickSecondComboBox.currentText.call_count, 'Should had been called once')
|
||||
self.assertEqual(1, self.media_item.quick_search_edit.text.call_count, 'Text edit Should had been called once')
|
||||
self.assertEqual(1, self.media_item.quickLockButton.isChecked.call_count, 'Lock Should had been called once')
|
||||
self.assertEqual(1, self.media_item.display_results.call_count, 'Display results Should had been called once')
|
||||
self.assertEqual(2, self.media_item.quickSearchButton.setEnabled.call_count, 'Disable and Enable the button')
|
||||
self.assertEqual(1, self.media_item.check_search_result.call_count, 'Check results Should had been called once')
|
||||
self.assertEqual(1, self.app.set_normal_cursor.call_count, 'Normal cursor should had been called once')
|
||||
|
@ -70,8 +70,8 @@ class TestSwordImport(TestCase):
|
||||
|
||||
@patch('openlp.plugins.bibles.lib.sword.SwordBible.application')
|
||||
@patch('openlp.plugins.bibles.lib.sword.modules')
|
||||
@patch('openlp.plugins.bibles.lib.db.BiblesResourcesDB')
|
||||
def test_simple_import(self, mocked_bible_res_db, mocked_pysword_modules, mocked_application):
|
||||
@patch('openlp.core.common.languages')
|
||||
def test_simple_import(self, mocked_languages, mocked_pysword_modules, mocked_application):
|
||||
"""
|
||||
Test that a simple SWORD import works
|
||||
"""
|
||||
@ -88,7 +88,7 @@ class TestSwordImport(TestCase):
|
||||
importer.create_verse = MagicMock()
|
||||
importer.create_book = MagicMock()
|
||||
importer.session = MagicMock()
|
||||
mocked_bible_res_db.get_language.return_value = 'Danish'
|
||||
mocked_languages.get_language.return_value = 'Danish'
|
||||
mocked_bible = MagicMock()
|
||||
mocked_genesis = MagicMock()
|
||||
mocked_genesis.name = 'Genesis'
|
||||
|
@ -43,3 +43,5 @@ class TestVideoPsalmFileImport(SongImportTestHelper):
|
||||
"""
|
||||
self.file_import(os.path.join(TEST_PATH, 'videopsalm-as-safe-a-stronghold.json'),
|
||||
self.load_external_result_data(os.path.join(TEST_PATH, 'as-safe-a-stronghold.json')))
|
||||
self.file_import(os.path.join(TEST_PATH, 'videopsalm-as-safe-a-stronghold2.json'),
|
||||
self.load_external_result_data(os.path.join(TEST_PATH, 'as-safe-a-stronghold2.json')))
|
||||
|
@ -50,7 +50,8 @@ class TestBibleHTTP(TestCase):
|
||||
books = handler.get_books_from_http('NIV')
|
||||
|
||||
# THEN: We should get back a valid service item
|
||||
assert len(books) == 66, 'The bible should not have had any books added or removed'
|
||||
self.assertEqual(len(books), 66, 'The bible should not have had any books added or removed')
|
||||
self.assertEqual(books[0], 'Genesis', 'The first bible book should be Genesis')
|
||||
|
||||
def test_bible_gateway_extract_books_support_redirect(self):
|
||||
"""
|
||||
@ -63,7 +64,7 @@ class TestBibleHTTP(TestCase):
|
||||
books = handler.get_books_from_http('DN1933')
|
||||
|
||||
# THEN: We should get back a valid service item
|
||||
assert len(books) == 66, 'This bible should have 66 books'
|
||||
self.assertEqual(len(books), 66, 'This bible should have 66 books')
|
||||
|
||||
def test_bible_gateway_extract_verse(self):
|
||||
"""
|
||||
@ -76,7 +77,8 @@ class TestBibleHTTP(TestCase):
|
||||
results = handler.get_bible_chapter('NIV', 'John', 3)
|
||||
|
||||
# THEN: We should get back a valid service item
|
||||
assert len(results.verse_list) == 36, 'The book of John should not have had any verses added or removed'
|
||||
self.assertEqual(len(results.verse_list), 36,
|
||||
'The book of John should not have had any verses added or removed')
|
||||
|
||||
def test_bible_gateway_extract_verse_nkjv(self):
|
||||
"""
|
||||
@ -89,7 +91,8 @@ class TestBibleHTTP(TestCase):
|
||||
results = handler.get_bible_chapter('NKJV', 'John', 3)
|
||||
|
||||
# THEN: We should get back a valid service item
|
||||
assert len(results.verse_list) == 36, 'The book of John should not have had any verses added or removed'
|
||||
self.assertEqual(len(results.verse_list), 36,
|
||||
'The book of John should not have had any verses added or removed')
|
||||
|
||||
def test_crosswalk_extract_books(self):
|
||||
"""
|
||||
@ -102,7 +105,7 @@ class TestBibleHTTP(TestCase):
|
||||
books = handler.get_books_from_http('niv')
|
||||
|
||||
# THEN: We should get back a valid service item
|
||||
assert len(books) == 66, 'The bible should not have had any books added or removed'
|
||||
self.assertEqual(len(books), 66, 'The bible should not have had any books added or removed')
|
||||
|
||||
def test_crosswalk_extract_verse(self):
|
||||
"""
|
||||
@ -115,7 +118,8 @@ class TestBibleHTTP(TestCase):
|
||||
results = handler.get_bible_chapter('niv', 'john', 3)
|
||||
|
||||
# THEN: We should get back a valid service item
|
||||
assert len(results.verse_list) == 36, 'The book of John should not have had any verses added or removed'
|
||||
self.assertEqual(len(results.verse_list), 36,
|
||||
'The book of John should not have had any verses added or removed')
|
||||
|
||||
def test_bibleserver_get_bibles(self):
|
||||
"""
|
||||
@ -144,9 +148,8 @@ class TestBibleHTTP(TestCase):
|
||||
|
||||
# THEN: The list should not be None, and some known bibles should be there
|
||||
self.assertIsNotNone(bibles)
|
||||
self.assertIn(('Holman Christian Standard Bible', 'HCSB', 'en'), bibles)
|
||||
self.assertIn(('Holman Christian Standard Bible (HCSB)', 'HCSB', 'en'), bibles)
|
||||
|
||||
@skip("Waiting for Crosswalk to fix their server")
|
||||
def test_crosswalk_get_bibles(self):
|
||||
"""
|
||||
Test getting list of bibles from Crosswalk.com
|
||||
|
35
tests/resources/videopsalmsongs/as-safe-a-stronghold2.json
Normal file
35
tests/resources/videopsalmsongs/as-safe-a-stronghold2.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"authors": [
|
||||
["Martin Luther", "words"],
|
||||
["Unknown", "music"]
|
||||
],
|
||||
"ccli_number": "12345",
|
||||
"comments": "This is\nthe first comment\nThis is\nthe second comment\nThis is\nthe third comment\n",
|
||||
"copyright": "Public Domain",
|
||||
"song_book_name": "SongBook1",
|
||||
"song_number": 0,
|
||||
"title": "A Safe Stronghold Our God is Still",
|
||||
"topics": [
|
||||
"tema1",
|
||||
"tema2"
|
||||
],
|
||||
"verse_order_list": [],
|
||||
"verses": [
|
||||
[
|
||||
"As safe a stronghold our God is still,\nA trusty shield and weapon;\nHe’ll help us clear from all the ill\nThat hath us now o’ertaken.\nThe ancient prince of hell\nHath risen with purpose fell;\nStrong mail of craft and power\nHe weareth in this hour;\nOn earth is not His fellow.",
|
||||
"v"
|
||||
],
|
||||
[
|
||||
"With \"force\" of arms we nothing can,\nFull soon were we down-ridden;\nBut for us fights \\ the proper Man,\nWhom God Himself hath bidden.\nAsk ye: Who is this same?\nChrist Jesus is His name,\nThe Lord Sabaoth’s Son;\nHe, and no other one,\nShall conquer in the battle.",
|
||||
"v"
|
||||
],
|
||||
[
|
||||
"And were this world all devils o’er,\nAnd watching to devour us,\nWe lay it not to heart so sore;\nNot they can overpower us.\nAnd let the prince of ill\nLook grim as e’er he will,\nHe harms us not a whit;\nFor why? his doom is writ;\nA word shall quickly slay him.",
|
||||
"v"
|
||||
],
|
||||
[
|
||||
"God’s word, for all their craft and force,\nOne moment will not linger,\nBut, spite of hell, shall have its course;\n’Tis written by His finger.\nAnd though they take our life,\nGoods, honour, children, wife,\nYet is their profit small:\nThese things shall vanish all;\nThe city of God remaineth.",
|
||||
"v"
|
||||
]
|
||||
]
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
{Abbreviation:"SB1",Copyright:"Public domain",Songs:[{ID:3,Composer:"Unknown",Author:"Martin Luther",Copyright:"Public
|
||||
Domain",Theme:"tema1
|
||||
tema2",CCLI:"12345",Alias:"A safe stronghold",Memo1:"This is
|
||||
the first comment
|
||||
",Memo2:"This is
|
||||
the second comment
|
||||
",Memo3:"This is
|
||||
the third comment
|
||||
",Reference:"reference",Guid:"jtCkrJdPIUOmECjaQylg/g",Verses:[{
|
||||
Text:"As safe a stronghold our God is still,
|
||||
A trusty shield and weapon;
|
||||
He’ll help us clear from all the ill
|
||||
That hath us now o’ertaken.
|
||||
The ancient prince of hell
|
||||
Hath risen with purpose fell;
|
||||
Strong mail of craft and power
|
||||
He weareth in this hour;
|
||||
On earth is not His fellow."},{ID:2,
|
||||
Text:"With \"force\" of arms we nothing can,
|
||||
Full soon were we down-ridden;
|
||||
But for us fights \\ the proper Man,
|
||||
Whom God Himself hath bidden.
|
||||
Ask ye: Who is this same?
|
||||
Christ Jesus is His name,
|
||||
The Lord Sabaoth’s Son;
|
||||
He, and no other one,
|
||||
Shall conquer in the battle."},{ID:3,
|
||||
Text:"And were this world all devils o’er,
|
||||
And watching to devour us,
|
||||
We lay it not to heart so sore;
|
||||
Not they can overpower us.
|
||||
And let the prince of ill
|
||||
Look grim as e’er he will,
|
||||
He harms us not a whit;
|
||||
For why? his doom is writ;
|
||||
A word shall quickly slay him."},{ID:4,
|
||||
Text:"God’s word, for all their craft and force,
|
||||
One moment will not linger,
|
||||
But, spite of hell, shall have its course;
|
||||
’Tis written by His finger.
|
||||
And though they take our life,
|
||||
Goods, honour, children, wife,
|
||||
Yet is their profit small:
|
||||
These things shall vanish all;
|
||||
The city of God remaineth."}],AudioFile:"282.mp3",IsAudioFileEnabled:1,
|
||||
Text:"A Safe Stronghold Our God is Still"}],Guid:"khiHU2blX0Kb41dGdbDLhA",VersionDate:"20121012000000",
|
||||
Text:"SongBook1"}
|
@ -23,8 +23,8 @@
|
||||
Package to test for proper bzr tags.
|
||||
"""
|
||||
import os
|
||||
import logging
|
||||
import platform
|
||||
import sys
|
||||
from unittest import TestCase, SkipTest
|
||||
|
||||
try:
|
||||
@ -46,9 +46,18 @@ class TestPylint(TestCase):
|
||||
"""
|
||||
Test for pylint errors
|
||||
"""
|
||||
# Test if this file is specified in the arguments, if not skip the test.
|
||||
in_argv = False
|
||||
for arg in sys.argv:
|
||||
if arg.endswith('test_pylint.py') or arg.endswith('test_pylint'):
|
||||
in_argv = True
|
||||
break
|
||||
if not in_argv:
|
||||
raise SkipTest('test_pylint.py not specified in arguments - skipping tests using pylint.')
|
||||
|
||||
# GIVEN: Some checks to disable and enable, and the pylint script
|
||||
disabled_checks = 'import-error,no-member'
|
||||
enabled_checks = 'missing-format-argument-key,unused-format-string-argument'
|
||||
enabled_checks = 'missing-format-argument-key,unused-format-string-argument,bad-format-string'
|
||||
if is_win() or 'arch' in platform.dist()[0].lower():
|
||||
pylint_script = 'pylint'
|
||||
else:
|
||||
@ -84,6 +93,9 @@ class TestPylint(TestCase):
|
||||
# Filter out PyQt related errors
|
||||
elif ('no-name-in-module' in line or 'no-member' in line) and 'PyQt5' in line:
|
||||
continue
|
||||
# Filter out distutils related errors
|
||||
elif 'distutils' in line:
|
||||
continue
|
||||
elif self._is_line_tolerated(line):
|
||||
continue
|
||||
else:
|
||||
|
Loading…
Reference in New Issue
Block a user