mirror of
https://github.com/KevinMidboe/spotify-downloader.git
synced 2025-10-29 18:00:15 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64d54d7943 | ||
|
|
85c12a91ef | ||
|
|
9795d7e9b8 | ||
|
|
bbe43da191 |
@@ -8,6 +8,14 @@ The release dates mentioned follow the format `DD-MM-YYYY`.
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [2.0.3] (Hotfix Release) - 18-05-2020
|
||||||
|
### Fixed
|
||||||
|
- Genius would sometimes return invalid lyrics. Retry a few times in such a case.
|
||||||
|
|
||||||
|
## [2.0.2] (Hotfix Release) - 18-05-2020
|
||||||
|
### Fixed
|
||||||
|
- Skipping tracks with `-m` would crash.
|
||||||
|
|
||||||
## [2.0.1] (Hotfix Release) - 18-05-2020
|
## [2.0.1] (Hotfix Release) - 18-05-2020
|
||||||
### Fixed
|
### Fixed
|
||||||
- `-o m4a` would always fail.
|
- `-o m4a` would always fail.
|
||||||
|
|||||||
@@ -48,14 +48,12 @@ class Genius(LyricBase):
|
|||||||
else:
|
else:
|
||||||
return response.read()
|
return response.read()
|
||||||
|
|
||||||
def _get_lyrics_text(self, html):
|
def _get_lyrics_text(self, paragraph):
|
||||||
"""
|
"""
|
||||||
Extracts and returns the lyric content from the provided HTML.
|
Extracts and returns the lyric content from the provided HTML.
|
||||||
"""
|
"""
|
||||||
soup = BeautifulSoup(html, "html.parser")
|
if paragraph:
|
||||||
lyrics_paragraph = soup.find("p")
|
return paragraph.get_text()
|
||||||
if lyrics_paragraph:
|
|
||||||
return lyrics_paragraph.get_text()
|
|
||||||
else:
|
else:
|
||||||
raise LyricsNotFoundError(
|
raise LyricsNotFoundError(
|
||||||
"The lyrics for this track are yet to be released on Genius."
|
"The lyrics for this track are yet to be released on Genius."
|
||||||
@@ -81,6 +79,7 @@ class Genius(LyricBase):
|
|||||||
"""
|
"""
|
||||||
encoded_query = urllib.request.quote(query.replace(" ", "+"))
|
encoded_query = urllib.request.quote(query.replace(" ", "+"))
|
||||||
search_url = self.base_search_url + encoded_query
|
search_url = self.base_search_url + encoded_query
|
||||||
|
logger.debug('Fetching Genius search results from "{}".'.format(search_url))
|
||||||
metadata = self._fetch_search_page(search_url)
|
metadata = self._fetch_search_page(search_url)
|
||||||
|
|
||||||
lyric_url = None
|
lyric_url = None
|
||||||
@@ -105,6 +104,7 @@ class Genius(LyricBase):
|
|||||||
Returns the lyric string for the track best matching the
|
Returns the lyric string for the track best matching the
|
||||||
given query.
|
given query.
|
||||||
"""
|
"""
|
||||||
|
logger.debug('Fetching lyrics for the search query on "{}".'.format(query))
|
||||||
try:
|
try:
|
||||||
lyric_url = self.best_matching_lyric_url_from_query(query)
|
lyric_url = self.best_matching_lyric_url_from_query(query)
|
||||||
except LyricsNotFoundError:
|
except LyricsNotFoundError:
|
||||||
@@ -123,11 +123,29 @@ class Genius(LyricBase):
|
|||||||
lyric_url = self.guess_lyric_url_from_artist_and_track(artist, track)
|
lyric_url = self.guess_lyric_url_from_artist_and_track(artist, track)
|
||||||
return self.from_url(lyric_url, linesep, timeout)
|
return self.from_url(lyric_url, linesep, timeout)
|
||||||
|
|
||||||
def from_url(self, url, linesep="\n", timeout=None):
|
def from_url(self, url, linesep="\n", retries=5, timeout=None):
|
||||||
"""
|
"""
|
||||||
Returns the lyric string for the given URL.
|
Returns the lyric string for the given URL.
|
||||||
"""
|
"""
|
||||||
|
logger.debug('Fetching lyric text from "{}".'.format(url))
|
||||||
lyric_html_page = self._fetch_url_page(url, timeout=timeout)
|
lyric_html_page = self._fetch_url_page(url, timeout=timeout)
|
||||||
lyrics = self._get_lyrics_text(lyric_html_page)
|
soup = BeautifulSoup(lyric_html_page, "html.parser")
|
||||||
|
paragraph = soup.find("p")
|
||||||
|
# If <p> has a class (like <p class="bla">), then we got an invalid
|
||||||
|
# response. Retry in such a case.
|
||||||
|
invalid_response = paragraph.get("class") is not None
|
||||||
|
to_retry = retries > 0 and invalid_response
|
||||||
|
if to_retry:
|
||||||
|
logger.debug(
|
||||||
|
"Retrying since Genius returned invalid response for search "
|
||||||
|
"results. Retries left: {retries}.".format(retries=retries)
|
||||||
|
)
|
||||||
|
return self.from_url(url, linesep=linesep, retries=retries-1, timeout=timeout)
|
||||||
|
|
||||||
|
if invalid_response:
|
||||||
|
raise LyricsNotFoundError(
|
||||||
|
'Genius returned invalid response for the search URL "{}".'.format(url)
|
||||||
|
)
|
||||||
|
lyrics = self._get_lyrics_text(paragraph)
|
||||||
return lyrics.replace("\n", linesep)
|
return lyrics.replace("\n", linesep)
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class YouTubeSearch:
|
|||||||
quoted_query = urllib.request.quote(query)
|
quoted_query = urllib.request.quote(query)
|
||||||
return self.base_search_url.format(quoted_query)
|
return self.base_search_url.format(quoted_query)
|
||||||
|
|
||||||
def _fetch_response_html(self, url, retries=5):
|
def _fetch_response_html(self, url):
|
||||||
response = urllib.request.urlopen(url)
|
response = urllib.request.urlopen(url)
|
||||||
soup = BeautifulSoup(response.read(), "html.parser")
|
soup = BeautifulSoup(response.read(), "html.parser")
|
||||||
return soup
|
return soup
|
||||||
@@ -119,12 +119,11 @@ class YouTubeSearch:
|
|||||||
videos = self._fetch_search_results(html, limit=limit)
|
videos = self._fetch_search_results(html, limit=limit)
|
||||||
to_retry = retries > 0 and self._is_server_side_invalid_response(videos, html)
|
to_retry = retries > 0 and self._is_server_side_invalid_response(videos, html)
|
||||||
if to_retry:
|
if to_retry:
|
||||||
retries -= 1
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Retrying since YouTube returned invalid response for search "
|
"Retrying since YouTube returned invalid response for search "
|
||||||
"results. Retries left: {retries}.".format(retries=retries)
|
"results. Retries left: {retries}.".format(retries=retries)
|
||||||
)
|
)
|
||||||
return self.search(query, limit=limit, retries=retries)
|
return self.search(query, limit=limit, retries=retries-1)
|
||||||
return YouTubeVideos(videos)
|
return YouTubeVideos(videos)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ class MetadataSearch:
|
|||||||
if video is None:
|
if video is None:
|
||||||
raise NoYouTubeVideoMatchError(
|
raise NoYouTubeVideoMatchError(
|
||||||
'No matching videos found on YouTube for the search query "{}".'.format(
|
'No matching videos found on YouTube for the search query "{}".'.format(
|
||||||
search_query
|
query
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return video
|
return video
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
__version__ = "2.0.1"
|
__version__ = "2.0.3"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user