Fix bible reference search when text matches multiple books

Fixes: https://launchpad.net/bugs/1799005
This commit is contained in:
Phill 2019-07-29 21:13:41 +01:00
parent 2e8da5a79e
commit 603a6ff7d6
3 changed files with 44 additions and 45 deletions

View File

@ -327,11 +327,11 @@ def parse_reference(reference, bible, language_selection, book_ref_id=False):
log.debug('Matched reference {text}'.format(text=reference)) log.debug('Matched reference {text}'.format(text=reference))
book = match.group('book') book = match.group('book')
if not book_ref_id: if not book_ref_id:
book_ref_id = bible.get_book_ref_id_by_localised_name(book, language_selection) book_ref_ids = bible.get_book_ref_id_by_localised_name(book, language_selection)
elif not bible.get_book_by_book_ref_id(book_ref_id): elif not bible.get_book_by_book_ref_id(book_ref_id):
return [] return []
# We have not found the book so do not continue # We have not found the book so do not continue
if not book_ref_id: if not book_ref_ids:
return [] return []
ranges = match.group('ranges') ranges = match.group('ranges')
range_list = get_reference_match('range_separator').split(ranges) range_list = get_reference_match('range_separator').split(ranges)
@ -372,22 +372,23 @@ def parse_reference(reference, bible, language_selection, book_ref_id=False):
to_chapter = to_verse to_chapter = to_verse
to_verse = None to_verse = None
# Append references to the list # Append references to the list
if has_range: for book_ref_id in book_ref_ids:
if not from_verse: if has_range:
from_verse = 1 if not from_verse:
if not to_verse: from_verse = 1
to_verse = -1 if not to_verse:
if to_chapter and to_chapter > from_chapter: to_verse = -1
ref_list.append((book_ref_id, from_chapter, from_verse, -1)) if to_chapter and to_chapter > from_chapter:
for i in range(from_chapter + 1, to_chapter): ref_list.append((book_ref_id, from_chapter, from_verse, -1))
ref_list.append((book_ref_id, i, 1, -1)) for i in range(from_chapter + 1, to_chapter):
ref_list.append((book_ref_id, to_chapter, 1, to_verse)) ref_list.append((book_ref_id, i, 1, -1))
elif to_verse >= from_verse or to_verse == -1: ref_list.append((book_ref_id, to_chapter, 1, to_verse))
ref_list.append((book_ref_id, from_chapter, from_verse, to_verse)) elif to_verse >= from_verse or to_verse == -1:
elif from_verse: ref_list.append((book_ref_id, from_chapter, from_verse, to_verse))
ref_list.append((book_ref_id, from_chapter, from_verse, from_verse)) elif from_verse:
else: ref_list.append((book_ref_id, from_chapter, from_verse, from_verse))
ref_list.append((book_ref_id, from_chapter, 1, -1)) else:
ref_list.append((book_ref_id, from_chapter, 1, -1))
return ref_list return ref_list
else: else:
log.debug('Invalid reference: {text}'.format(text=reference)) log.debug('Invalid reference: {text}'.format(text=reference))

View File

@ -281,13 +281,14 @@ class BibleDB(Manager):
log.debug('BibleDB.get_book("{book}")'.format(book=book)) log.debug('BibleDB.get_book("{book}")'.format(book=book))
return self.get_object_filtered(Book, Book.name.like(book + '%')) return self.get_object_filtered(Book, Book.name.like(book + '%'))
def get_books(self): def get_books(self, book=None):
""" """
A wrapper so both local and web bibles have a get_books() method that A wrapper so both local and web bibles have a get_books() method that
manager can call. Used in the media manager advanced search tab. manager can call. Used in the media manager advanced search tab.
""" """
log.debug('BibleDB.get_books()') log.debug('BibleDB.get_books("{book}")'.format(book=book))
return self.get_all_objects(Book, order_by_ref=Book.id) filter = Book.name.like(book + '%') if book else None
return self.get_all_objects(Book, filter_clause=filter, order_by_ref=Book.id)
def get_book_by_book_ref_id(self, ref_id): def get_book_by_book_ref_id(self, ref_id):
""" """
@ -300,39 +301,34 @@ class BibleDB(Manager):
def get_book_ref_id_by_localised_name(self, book, language_selection): def get_book_ref_id_by_localised_name(self, book, language_selection):
""" """
Return the id of a named book. Return the ids of a matching named book.
:param book: The name of the book, according to the selected language. :param book: The name of the book, according to the selected language.
:param language_selection: The language selection the user has chosen in the settings section of the Bible. :param language_selection: The language selection the user has chosen in the settings section of the Bible.
:rtype: list[int]
""" """
log.debug('get_book_ref_id_by_localised_name("{book}", "{lang}")'.format(book=book, lang=language_selection)) log.debug('get_book_ref_id_by_localised_name("{book}", "{lang}")'.format(book=book, lang=language_selection))
from openlp.plugins.bibles.lib import LanguageSelection, BibleStrings from openlp.plugins.bibles.lib import LanguageSelection, BibleStrings
book_names = BibleStrings().BookNames book_names = BibleStrings().BookNames
# escape reserved characters # escape reserved characters
book_escaped = book
for character in RESERVED_CHARACTERS: for character in RESERVED_CHARACTERS:
book_escaped = book_escaped.replace(character, '\\' + character) book_escaped = book.replace(character, '\\' + character)
regex_book = re.compile('\\s*{book}\\s*'.format(book='\\s*'.join(book_escaped.split())), re.IGNORECASE) regex_book = re.compile('\\s*{book}\\s*'.format(book='\\s*'.join(book_escaped.split())), re.IGNORECASE)
if language_selection == LanguageSelection.Bible: if language_selection == LanguageSelection.Bible:
db_book = self.get_book(book) db_books = self.get_books(book)
if db_book: return [db_book.book_reference_id for db_book in db_books]
return db_book.book_reference_id else:
elif language_selection == LanguageSelection.Application: if language_selection == LanguageSelection.Application:
books = [key for key in list(book_names.keys()) if regex_book.match(str(book_names[key]))] books = [key for key in list(book_names.keys()) if regex_book.match(book_names[key])]
books = [_f for _f in map(BiblesResourcesDB.get_book, books) if _f] book_list = [_f for _f in map(BiblesResourcesDB.get_book, books) if _f]
for value in books: elif language_selection == LanguageSelection.English:
if self.get_book_by_book_ref_id(value['id']): books = BiblesResourcesDB.get_books_like(book)
return value['id'] if books:
elif language_selection == LanguageSelection.English: book_list = [value for value in books if regex_book.match(value['name'])]
books = BiblesResourcesDB.get_books_like(book) if not book_list:
if books: book_list = books
book_list = [value for value in books if regex_book.match(value['name'])] return [value['id'] for value in book_list if self.get_book_by_book_ref_id(value['id'])]
if not book_list: return []
book_list = books
for value in book_list:
if self.get_book_by_book_ref_id(value['id']):
return value['id']
return False
def get_verses(self, reference_list, show_error=True): def get_verses(self, reference_list, show_error=True):
""" """

View File

@ -240,8 +240,10 @@ class BibleManager(LogMixin, RegistryProperties):
book=book, book=book,
chapter=chapter)) chapter=chapter))
language_selection = self.get_language_selection(bible) language_selection = self.get_language_selection(bible)
book_ref_id = self.db_cache[bible].get_book_ref_id_by_localised_name(book, language_selection) book_ref_ids = self.db_cache[bible].get_book_ref_id_by_localised_name(book, language_selection)
return self.db_cache[bible].get_verse_count(book_ref_id, chapter) if book_ref_ids:
return self.db_cache[bible].get_verse_count(book_ref_ids[0], chapter)
return 0
def get_verse_count_by_book_ref_id(self, bible, book_ref_id, chapter): def get_verse_count_by_book_ref_id(self, bible, book_ref_id, chapter):
""" """