Repository: beetbox/beets

Issue:
lyrics: Try searching for song title component preceding : to strip subtitles
### Problem

The lyrics plugin fails to find the lyrics for titles that have a "subtitle" for example:
The musicbrainz artist - album - title
Nightwish - Endless Forms Most Beautiful - The Greatest Show on Earth: Chapter I) Four Point Six / Chapter II) Life / Chapter III) The Toolmaker / Chapter IV) The Understanding / Chapter V) Sea-Worn Driftwood
musicbrainz page for this song: https://musicbrainz.org/recording/42854595-599c-438d-b3f5-0be264d41ccb

Corresponds to lyricwiki title:
Nightwish - Endless Forms Most Beautiful - The Greatest Show on Earth
Lyricwiki page: http://lyrics.wikia.com/wiki/Nightwish:The_Greatest_Show_On_Earth

Basically, everything after the ":" needs to be dropped before searching.

This also applies to Pink Floyd - Atom Heart Mother - Atom Heart Mother: a) Father’s Shout / b) Breast Milky / c) Mother Fore / d) Funky Dung / e) Mind Your Throats Please / f) Remergence
Running this command in verbose (`-vv`) mode:

``` sh
$ beet -vv lyrics -f albumartist:Nightwish album:Endless title:Greatest
```

Led to this problem:

```

user configuration: /home/user/.config/beets/config.yaml
data directory: /home/user/.config/beets
plugin paths: /home/user/.beets/beets-setlister/beetsplug
Sending event: pluginload
lyrics: Disabling google source: no API key configured.
inline: adding item field multidisc
inline: adding item field lmultidisc
artresizer: method is (2, (6, 8, 9))
thumbnails: using IM to write metadata
thumbnails: using GIO to compute URIs
library database: /home/geoff/.config/beets/library.db
library directory: /home/geoff/Music
Sending event: library_opened
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:The_Greatest_Show_On_Earth%3A_Chapter_I%29_Four_Point_Six_/_Chapter_Ii%29_Life_/_Chapter_Iii%29_The_Toolmaker_/_Chapter_Iv%29_The_Understanding_/_Chapter_V%29_Sea-Worn_Driftwood (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/The-Greatest-Show-On-Earth%3A-Chapter-I%29-Four-Point-Six-/-Chapter-Ii%29-Life-/-Chapter-Iii%29-The-Toolmaker-/-Chapter-Iv%29-The-Understanding-/-Chapter-V%29-Sea-Worn-Driftwood (404)
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:The_Greatest_Show_On_Earth%3A_Chapter_I%29_Four_Point_Six (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/The-Greatest-Show-On-Earth%3A-Chapter-I%29-Four-Point-Six (404)
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:Chapter_Ii%29_Life (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/Chapter-Ii%29-Life (404)
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:Chapter_Iii%29_The_Toolmaker (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/Chapter-Iii%29-The-Toolmaker (404)
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:Chapter_Iv%29_The_Understanding (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/Chapter-Iv%29-The-Understanding (404)
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:Chapter_V%29_Sea-Worn_Driftwood (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/Chapter-V%29-Sea-Worn-Driftwood (404)
lyrics: lyrics not found: Nightwish - Endless Forms Most Beautiful - 11. The Greatest Show on Earth: Chapter I) Four Point Six / Chapter II) Life / Chapter III) The Toolmaker / Chapter IV) The Understanding / Chapter V) Sea-Worn Driftwood (24:01)
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:The_Greatest_Show_On_Earth%3A_Chapter_I%29_Four_Point_Six_/_Chapter_Ii%29_Life_/_Chapter_Iii%29_The_Toolmaker_/_Chapter_Iv%29_The_Understanding_/_Chapter_V%29_Sea-Worn_Driftwood (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/The-Greatest-Show-On-Earth%3A-Chapter-I%29-Four-Point-Six-/-Chapter-Ii%29-Life-/-Chapter-Iii%29-The-Toolmaker-/-Chapter-Iv%29-The-Understanding-/-Chapter-V%29-Sea-Worn-Driftwood (404)
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:The_Greatest_Show_On_Earth%3A_Chapter_I%29_Four_Point_Six (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/The-Greatest-Show-On-Earth%3A-Chapter-I%29-Four-Point-Six (404)
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:Chapter_Ii%29_Life (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/Chapter-Ii%29-Life (404)
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:Chapter_Iii%29_The_Toolmaker (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/Chapter-Iii%29-The-Toolmaker (404)
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:Chapter_Iv%29_The_Understanding (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/Chapter-Iv%29-The-Understanding (404)
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:Chapter_V%29_Sea-Worn_Driftwood (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/Chapter-V%29-Sea-Worn-Driftwood (404)
lyrics: lyrics not found: Nightwish - Endless Forms Most Beautiful - 11. The Greatest Show on Earth: Chapter I) Four Point Six / Chapter II) Life / Chapter III) The Toolmaker / Chapter IV) The Understanding / Chapter V) Sea-Worn Driftwood (24:08)
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:The_Greatest_Show_On_Earth%3A_Chapter_I%29_Four_Point_Six_/_Chapter_Ii%29_Life_/_Chapter_Iii%29_The_Toolmaker_/_Chapter_Iv%29_The_Understanding_/_Chapter_V%29_Sea-Worn_Driftwood (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/The-Greatest-Show-On-Earth%3A-Chapter-I%29-Four-Point-Six-/-Chapter-Ii%29-Life-/-Chapter-Iii%29-The-Toolmaker-/-Chapter-Iv%29-The-Understanding-/-Chapter-V%29-Sea-Worn-Driftwood (404)
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:The_Greatest_Show_On_Earth%3A_Chapter_I%29_Four_Point_Six (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/The-Greatest-Show-On-Earth%3A-Chapter-I%29-Four-Point-Six (404)
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:Chapter_Ii%29_Life (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/Chapter-Ii%29-Life (404)
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:Chapter_Iii%29_The_Toolmaker (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/Chapter-Iii%29-The-Toolmaker (404)
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:Chapter_Iv%29_The_Understanding (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/Chapter-Iv%29-The-Understanding (404)
lyrics: failed to fetch: http://lyrics.wikia.com/Nightwish:Chapter_V%29_Sea-Worn_Driftwood (404)
lyrics: failed to fetch: https://www.musixmatch.com/lyrics/Nightwish/Chapter-V%29-Sea-Worn-Driftwood (404)
lyrics: lyrics not found: Nightwish - Endless Forms Most Beautiful - 09. The Greatest Show on Earth: Chapter I) Four Point Six / Chapter II) Life / Chapter III) The Toolmaker / Chapter IV) The Understanding / Chapter V) Sea-Worn Driftwood (23:36)
Sending event: cli_exit
```

Here's a link to the music files that trigger the bug (if relevant): 
### Setup
- OS: Linux
- Python version: 
- beets version: 1.3.19
- Turning off plugins made problem go away (yes/no): no



Discussion:
Thanks for the detailed documentation! Seems like a good idea to try searching for the pre-colon part of the title.


Resolving patch:
diff --git a/beetsplug/lyrics.py b/beetsplug/lyrics.py
--- a/beetsplug/lyrics.py
+++ b/beetsplug/lyrics.py
@@ -25,8 +25,8 @@
 import requests
 import unicodedata
 import warnings
-from six.moves import urllib
 import six
+from six.moves import urllib
 
 try:
     from bs4 import SoupStrainer, BeautifulSoup
@@ -144,29 +144,32 @@ def search_pairs(item):
     The method also tries to split multiple titles separated with `/`.
     """
 
+    def generate_alternatives(string, patterns):
+        """Generate string alternatives by extracting first matching group for
+           each given pattern."""
+        alternatives = [string]
+        for pattern in patterns:
+            match = re.search(pattern, string, re.IGNORECASE)
+            if match:
+                alternatives.append(match.group(1))
+        return alternatives
+
     title, artist = item.title, item.artist
-    titles = [title]
-    artists = [artist]
-
-    # Remove any featuring artists from the artists name
-    pattern = r"(.*?) {0}".format(plugins.feat_tokens())
-    match = re.search(pattern, artist, re.IGNORECASE)
-    if match:
-        artists.append(match.group(1))
-
-    # Remove a parenthesized suffix from a title string. Common
-    # examples include (live), (remix), and (acoustic).
-    pattern = r"(.+?)\s+[(].*[)]$"
-    match = re.search(pattern, title, re.IGNORECASE)
-    if match:
-        titles.append(match.group(1))
-
-    # Remove any featuring artists from the title
-    pattern = r"(.*?) {0}".format(plugins.feat_tokens(for_artist=False))
-    for title in titles[:]:
-        match = re.search(pattern, title, re.IGNORECASE)
-        if match:
-            titles.append(match.group(1))
+
+    patterns = [
+        # Remove any featuring artists from the artists name
+        r"(.*?) {0}".format(plugins.feat_tokens())]
+    artists = generate_alternatives(artist, patterns)
+
+    patterns = [
+        # Remove a parenthesized suffix from a title string. Common
+        # examples include (live), (remix), and (acoustic).
+        r"(.+?)\s+[(].*[)]$",
+        # Remove any featuring artists from the title
+        r"(.*?) {0}".format(plugins.feat_tokens(for_artist=False)),
+        # Remove part of title after colon ':' for songs with subtitles
+        r"(.+?)\s*:.*"]
+    titles = generate_alternatives(title, patterns)
 
     # Check for a dual song (e.g. Pink Floyd - Speak to Me / Breathe)
     # and each of them.


Test patch:
diff --git a/test/test_lyrics.py b/test/test_lyrics.py
--- a/test/test_lyrics.py
+++ b/test/test_lyrics.py
@@ -84,6 +84,10 @@ def test_search_artist(self):
         self.assertIn(('Alice', ['song']),
                       lyrics.search_pairs(item))
 
+        item = Item(artist='Alice and Bob', title='song')
+        self.assertEqual(('Alice and Bob', ['song']),
+                         list(lyrics.search_pairs(item))[0])
+
     def test_search_pairs_multi_titles(self):
         item = Item(title='1 / 2', artist='A')
         self.assertIn(('A', ['1 / 2']), lyrics.search_pairs(item))
@@ -118,6 +122,10 @@ def test_search_pairs_titles(self):
         self.assertNotIn(('A', ['Song']), lyrics.search_pairs(item))
         self.assertIn(('A', ['Song and B']), lyrics.search_pairs(item))
 
+        item = Item(title='Song: B', artist='A')
+        self.assertIn(('A', ['Song']), lyrics.search_pairs(item))
+        self.assertIn(('A', ['Song: B']), lyrics.search_pairs(item))
+
     def test_remove_credits(self):
         self.assertEqual(
             lyrics.remove_credits("""It's close to midnight