In a song, replace apostrophes with an empty string instead of a space. This allows the searcher to find words containing "it's" and "Lord's" should they type "its" or "Lords" (and vice versa).

Also reinstate the setting of search_lyrics by clean_song.

bzr-revno: 1612
This commit is contained in:
Jonathan Corwin 2011-06-04 17:07:42 +01:00
commit 9230fbb116
3 changed files with 30 additions and 15 deletions

View File

@ -92,7 +92,7 @@ class MediaManagerItem(QtGui.QWidget):
"""
QtGui.QWidget.__init__(self, parent)
self.hide()
self.whitespace = re.compile(r'\W+', re.UNICODE)
self.whitespace = re.compile(r'[\W_]+', re.UNICODE)
self.plugin = plugin
visible_title = self.plugin.getString(StringContent.VisibleName)
self.title = unicode(visible_title[u'title'])

View File

@ -32,6 +32,9 @@ from openlp.core.lib import translate
from db import Author
from ui import SongStrings
WHITESPACE = re.compile(r'[\W_]+', re.UNICODE)
APOSTROPHE = re.compile(u'[\'`ʻ]', re.UNICODE)
class VerseType(object):
"""
VerseType provides an enumeration for the tags that may be associated
@ -246,6 +249,12 @@ def retrieve_windows_encoding(recommendation=None):
return None
return filter(lambda item: item[1] == choice[0], encodings)[0][0]
def clean_string(string):
"""
Strips punctuation from the passed string to assist searching
"""
return WHITESPACE.sub(u' ', APOSTROPHE.sub(u'', string)).lower()
def clean_song(manager, song):
"""
Cleans the search title, rebuilds the search lyrics, adds a default author
@ -262,9 +271,8 @@ def clean_song(manager, song):
if song.alternate_title is None:
song.alternate_title = u''
song.alternate_title = song.alternate_title.strip()
whitespace = re.compile(r'\W+', re.UNICODE)
song.search_title = (whitespace.sub(u' ', song.title).strip() + u'@' +
whitespace.sub(u' ', song.alternate_title).strip()).strip().lower()
song.search_title = clean_string(song.title) + u'@' + \
clean_string(song.alternate_title)
# Only do this, if we the song is a 1.9.4 song (or older).
if song.lyrics.find(u'<lyrics language="en">') != -1:
# Remove the old "language" attribute from lyrics tag (prior to 1.9.5).
@ -273,8 +281,8 @@ def clean_song(manager, song):
song.lyrics = song.lyrics.replace(
u'<lyrics language="en">', u'<lyrics>')
verses = SongXML().get_verses(song.lyrics)
lyrics = u' '.join([whitespace.sub(u' ', verse[1]) for verse in verses])
song.search_lyrics = lyrics.lower()
song.search_lyrics = u' '.join([clean_string(verse[1])
for verse in verses])
# We need a new and clean SongXML instance.
sxml = SongXML()
# Rebuild the song's verses, to remove any wrong verse names (for
@ -316,6 +324,11 @@ def clean_song(manager, song):
if order not in compare_order:
song.verse_order = u''
break
else:
verses = SongXML().get_verses(song.lyrics)
song.search_lyrics = u' '.join([clean_string(verse[1])
for verse in verses])
# The song does not have any author, add one.
if not song.authors:
name = SongStrings.AuthorUnknown

View File

@ -38,7 +38,8 @@ from openlp.core.lib.searchedit import SearchEdit
from openlp.core.lib.ui import UiStrings
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
SongImportForm, SongExportForm
from openlp.plugins.songs.lib import OpenLyrics, SongXML, VerseType
from openlp.plugins.songs.lib import OpenLyrics, SongXML, VerseType, \
clean_string
from openlp.plugins.songs.lib.db import Author, Song
from openlp.plugins.songs.lib.ui import SongStrings
@ -181,13 +182,14 @@ class SongMediaItem(MediaManagerItem):
elif search_type == SongSearch.Titles:
log.debug(u'Titles Search')
search_results = self.plugin.manager.get_all_objects(Song,
Song.search_title.like(u'%' + self.whitespace.sub(u' ',
search_keywords.lower()) + u'%'))
Song.search_title.like(u'%' + clean_string(search_keywords) +
u'%'))
self.displayResultsSong(search_results)
elif search_type == SongSearch.Lyrics:
log.debug(u'Lyrics Search')
search_results = self.plugin.manager.get_all_objects(Song,
Song.search_lyrics.like(u'%' + search_keywords.lower() + u'%'))
Song.search_lyrics.like(u'%' + clean_string(search_keywords) +
u'%'))
self.displayResultsSong(search_results)
elif search_type == SongSearch.Authors:
log.debug(u'Authors Search')
@ -198,16 +200,16 @@ class SongMediaItem(MediaManagerItem):
elif search_type == SongSearch.Themes:
log.debug(u'Theme Search')
search_results = self.plugin.manager.get_all_objects(Song,
Song.theme_name.like(u'%' + self.whitespace.sub(u' ',
search_keywords) + u'%'))
Song.theme_name.like(u'%' + search_keywords + u'%'))
self.displayResultsSong(search_results)
self.check_search_result()
def searchEntire(self, search_keywords):
return self.plugin.manager.get_all_objects(Song,
or_(Song.search_title.like(u'%' + self.whitespace.sub(u' ',
search_keywords.lower()) + u'%'),
Song.search_lyrics.like(u'%' + search_keywords.lower() + u'%'),
or_(Song.search_title.like(u'%' + clean_string(search_keywords)
+ u'%'),
Song.search_lyrics.like(u'%' + clean_string(search_keywords)
+ u'%'),
Song.comments.like(u'%' + search_keywords.lower() + u'%')))
def onSongListLoad(self):