Skip to content

Commit

Permalink
Add types to lyrics fetch methods
Browse files Browse the repository at this point in the history
  • Loading branch information
snejus committed Sep 28, 2024
1 parent 12a1bd4 commit 149c7ef
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 36 deletions.
65 changes: 31 additions & 34 deletions beetsplug/lyrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,20 @@
from contextlib import contextmanager
from functools import cached_property
from html import unescape
from typing import Any, ClassVar, Iterator
from typing import TYPE_CHECKING, Any, ClassVar, Iterator
from urllib.parse import urlparse

import requests
from typing_extensions import TypedDict
from unidecode import unidecode

import beets
from beets import plugins, ui
from beets.autotag.hooks import string_dist

if TYPE_CHECKING:
from beets.library import Item

try:
from bs4 import BeautifulSoup

Expand All @@ -47,11 +54,6 @@
except ImportError:
HAS_LANGDETECT = False


import beets
from beets import plugins, ui
from beets.autotag.hooks import string_dist

BREAK_RE = re.compile(r"\n?\s*<br([\s|/][^>]*)*>\s*\n?", re.I)
USER_AGENT = f"beets/{beets.__version__}"

Expand Down Expand Up @@ -268,7 +270,9 @@ def __init__(self, config, log):
self._log = log
self.config = config

def fetch(self, artist, title, album=None, length=None):
def fetch(
self, artist: str, title: str, album: str, length: float
) -> str | None:
raise NotImplementedError


Expand Down Expand Up @@ -318,11 +322,7 @@ def pick_lyrics(
return min(data, key=lambda item: cls.get_rank(target_duration, item))

def fetch(
self,
artist: str,
title: str,
album: str | None = None,
length: float = 0.0,
self, artist: str, title: str, album: str, length: float
) -> str | None:
"""Fetch lyrics for the given artist, title, and album."""
params = {
Expand Down Expand Up @@ -369,7 +369,7 @@ def build_url(self, artist, title):
self._encode(title.title()),
)

def fetch(self, artist, title, album=None, length=None):
def fetch(self, artist: str, title: str, *_) -> str | None:
url = self.build_url(artist, title)

html = self.fetch_text(url)
Expand Down Expand Up @@ -411,7 +411,7 @@ def __init__(self, config, log):
self.api_key = config["genius_api_key"].as_str()
self.headers = {"Authorization": f"Bearer {self.api_key}"}

def fetch(self, artist, title, album=None, length=None):
def fetch(self, artist: str, title: str, *_) -> str | None:
"""Fetch lyrics from genius.com
Because genius doesn't allow accessing lyrics via the api,
Expand Down Expand Up @@ -512,7 +512,7 @@ def build_url(self, artist, title):
urllib.parse.quote_plus(unidecode(artistitle))
)

def fetch(self, artist, title, album=None, length=None):
def fetch(self, artist: str, title: str, *_) -> str | None:
search_results = self.fetch_text(self.build_url(title, artist))
song_page_url = self.parse_search_results(search_results)
if not song_page_url:
Expand Down Expand Up @@ -695,7 +695,7 @@ def is_page_candidate(self, url_link, url_title, title, artist):
ratio = difflib.SequenceMatcher(None, song_title, title).ratio()
return ratio >= typo_ratio

def fetch(self, artist, title, album=None, length=None):
def fetch(self, artist: str, title: str, *_) -> str | None:
query = f"{artist} {title}"
url = "https://www.googleapis.com/customsearch/v1?key=%s&cx=%s&q=%s" % (
self.api_key,
Expand Down Expand Up @@ -868,10 +868,7 @@ def func(lib, opts, args):
for item in items:
if not opts.local_only and not self.config["local"]:
self.fetch_item_lyrics(
lib,
item,
write,
opts.force_refetch or self.config["force"],
item, write, opts.force_refetch or self.config["force"]
)
if item.lyrics:
if opts.printlyr:
Expand Down Expand Up @@ -965,7 +962,7 @@ def imported(self, session, task):
session.lib, item, False, self.config["force"]
)

def fetch_item_lyrics(self, lib, item, write, force):
def fetch_item_lyrics(self, item: Item, write: bool, force: bool) -> None:
"""Fetch and store lyrics for a single item. If ``write``, then the
lyrics will also be written to the file itself.
"""
Expand All @@ -975,17 +972,17 @@ def fetch_item_lyrics(self, lib, item, write, force):
return

lyrics = None
album = item.album
length = round(item.length)
for artist, titles in search_pairs(item):
lyrics = [
self.get_lyrics(artist, title, album=album, length=length)
for title in titles
album, length = item.album, item.length
lyrics_matches = [
[
lyrics
for t in titles
if (lyrics := self.get_lyrics(artist, t, album, length))
]
if any(lyrics):
break
for artist, titles in search_pairs(item)
]

lyrics = "\n\n---\n\n".join(filter(None, lyrics))
lyrics = "\n\n---\n\n".join(next(filter(None, lyrics_matches), []))

if lyrics:
self.info("Lyrics found: {}", item)
Expand All @@ -1010,18 +1007,18 @@ def fetch_item_lyrics(self, lib, item, write, force):
item.try_write()
item.store()

def get_lyrics(self, artist, title, album=None, length=None):
def get_lyrics(self, artist: str, title: str, *args) -> str | None:
"""Fetch lyrics, trying each source in turn. Return a string or
None if no lyrics were found.
"""
self.debug("Fetching lyrics for {} - {}", artist, title)
for backend in self.backends.values():
with backend.handle_request():
if lyrics := backend.fetch(
artist, title, album=album, length=length
):
if lyrics := backend.fetch(artist, title, *args):
return lyrics

return None

def append_translation(self, text, to_lang):
from xml.etree import ElementTree

Expand Down
4 changes: 2 additions & 2 deletions test/plugins/test_lyrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ def test_backend_source(self, backend):
databases.
"""
title = "Lady Madonna"
res = backend.fetch("The Beatles", title)
res = backend.fetch("The Beatles", title, "", 0.0)
assert PHRASE_BY_TITLE[title] in res.lower()


Expand All @@ -235,7 +235,7 @@ def test_error_handling(
requests_mock.get(lyrics.LRCLib.base_url, **request_kwargs)

plugin = lyrics.LyricsPlugin()
assert plugin.get_lyrics("", "") is None
assert plugin.get_lyrics("", "", "", 0.0) is None
assert caplog.messages
last_log = caplog.messages[-1]
assert last_log
Expand Down

0 comments on commit 149c7ef

Please sign in to comment.