From 603a6ff7d646b74fe84eda2a0bf36bbd8aab947d Mon Sep 17 00:00:00 2001 From: Phill Date: Mon, 29 Jul 2019 21:13:41 +0100 Subject: [PATCH] Fix bible reference search when text matches multiple books Fixes: https://launchpad.net/bugs/1799005 --- openlp/plugins/bibles/lib/__init__.py | 37 ++++++++++----------- openlp/plugins/bibles/lib/db.py | 46 ++++++++++++--------------- openlp/plugins/bibles/lib/manager.py | 6 ++-- 3 files changed, 44 insertions(+), 45 deletions(-) diff --git a/openlp/plugins/bibles/lib/__init__.py b/openlp/plugins/bibles/lib/__init__.py index 6045476a4..e6f6620c1 100644 --- a/openlp/plugins/bibles/lib/__init__.py +++ b/openlp/plugins/bibles/lib/__init__.py @@ -327,11 +327,11 @@ def parse_reference(reference, bible, language_selection, book_ref_id=False): log.debug('Matched reference {text}'.format(text=reference)) book = match.group('book') 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): return [] # We have not found the book so do not continue - if not book_ref_id: + if not book_ref_ids: return [] ranges = match.group('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_verse = None # Append references to the list - if has_range: - if not from_verse: - from_verse = 1 - if not to_verse: - to_verse = -1 - if to_chapter and to_chapter > from_chapter: - ref_list.append((book_ref_id, from_chapter, from_verse, -1)) - for i in range(from_chapter + 1, to_chapter): - ref_list.append((book_ref_id, i, 1, -1)) - ref_list.append((book_ref_id, to_chapter, 1, to_verse)) - elif to_verse >= from_verse or to_verse == -1: - ref_list.append((book_ref_id, from_chapter, from_verse, to_verse)) - elif from_verse: - ref_list.append((book_ref_id, from_chapter, from_verse, from_verse)) - else: - ref_list.append((book_ref_id, from_chapter, 1, -1)) + for book_ref_id in book_ref_ids: + if has_range: + if not from_verse: + from_verse = 1 + if not to_verse: + to_verse = -1 + if to_chapter and to_chapter > from_chapter: + ref_list.append((book_ref_id, from_chapter, from_verse, -1)) + for i in range(from_chapter + 1, to_chapter): + ref_list.append((book_ref_id, i, 1, -1)) + ref_list.append((book_ref_id, to_chapter, 1, to_verse)) + elif to_verse >= from_verse or to_verse == -1: + ref_list.append((book_ref_id, from_chapter, from_verse, to_verse)) + elif from_verse: + ref_list.append((book_ref_id, from_chapter, from_verse, from_verse)) + else: + ref_list.append((book_ref_id, from_chapter, 1, -1)) return ref_list else: log.debug('Invalid reference: {text}'.format(text=reference)) diff --git a/openlp/plugins/bibles/lib/db.py b/openlp/plugins/bibles/lib/db.py index 3f48ca7b2..ce14641e5 100644 --- a/openlp/plugins/bibles/lib/db.py +++ b/openlp/plugins/bibles/lib/db.py @@ -281,13 +281,14 @@ class BibleDB(Manager): log.debug('BibleDB.get_book("{book}")'.format(book=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 manager can call. Used in the media manager advanced search tab. """ - log.debug('BibleDB.get_books()') - return self.get_all_objects(Book, order_by_ref=Book.id) + log.debug('BibleDB.get_books("{book}")'.format(book=book)) + 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): """ @@ -300,39 +301,34 @@ class BibleDB(Manager): 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 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)) from openlp.plugins.bibles.lib import LanguageSelection, BibleStrings book_names = BibleStrings().BookNames # escape reserved characters - book_escaped = book 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) if language_selection == LanguageSelection.Bible: - db_book = self.get_book(book) - if db_book: - return db_book.book_reference_id - elif language_selection == LanguageSelection.Application: - books = [key for key in list(book_names.keys()) if regex_book.match(str(book_names[key]))] - books = [_f for _f in map(BiblesResourcesDB.get_book, books) if _f] - for value in books: - if self.get_book_by_book_ref_id(value['id']): - return value['id'] - elif language_selection == LanguageSelection.English: - books = BiblesResourcesDB.get_books_like(book) - if books: - book_list = [value for value in books if regex_book.match(value['name'])] - if not book_list: - book_list = books - for value in book_list: - if self.get_book_by_book_ref_id(value['id']): - return value['id'] - return False + db_books = self.get_books(book) + return [db_book.book_reference_id for db_book in db_books] + else: + if language_selection == LanguageSelection.Application: + books = [key for key in list(book_names.keys()) if regex_book.match(book_names[key])] + book_list = [_f for _f in map(BiblesResourcesDB.get_book, books) if _f] + elif language_selection == LanguageSelection.English: + books = BiblesResourcesDB.get_books_like(book) + if books: + book_list = [value for value in books if regex_book.match(value['name'])] + if not book_list: + book_list = books + return [value['id'] for value in book_list if self.get_book_by_book_ref_id(value['id'])] + return [] def get_verses(self, reference_list, show_error=True): """ diff --git a/openlp/plugins/bibles/lib/manager.py b/openlp/plugins/bibles/lib/manager.py index 53926d78b..44d18b92d 100644 --- a/openlp/plugins/bibles/lib/manager.py +++ b/openlp/plugins/bibles/lib/manager.py @@ -240,8 +240,10 @@ class BibleManager(LogMixin, RegistryProperties): book=book, chapter=chapter)) language_selection = self.get_language_selection(bible) - book_ref_id = 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) + book_ref_ids = self.db_cache[bible].get_book_ref_id_by_localised_name(book, language_selection) + 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): """