Skip to content

Commit

Permalink
🪶: Refactor Code Expression (spotDL#1390)
Browse files Browse the repository at this point in the history
* 🪶: Refactor Code Expression (ritiek#1)

* 🪶: Refactor Code Expression

* 🪶: Refactor Code Expression

* 🪶: Refactor Code Expression

* Fix Linting Issue (Based on mypy & Flake8)

* Using Black to Reformat Projects ✨(ritiek#2)

* Revert Comments ✨ (ritiek#3)

Co-authored-by: Silverarmor <[email protected]>
Co-authored-by: Jakub Kot <[email protected]>
Co-authored-by: Peyton Creery <[email protected]>
  • Loading branch information
4 people authored Oct 3, 2021
1 parent dba2fcc commit 8bc2362
Show file tree
Hide file tree
Showing 13 changed files with 82 additions and 110 deletions.
9 changes: 3 additions & 6 deletions spotdl/download/downloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ async def download_song(self, song_object: SongObject) -> None:
audio_handler = YoutubeDL(
{
"format": ytdl_format,
"outtmpl": f"{str(temp_folder)}/%(id)s.%(ext)s",
"outtmpl": f"{temp_folder}/%(id)s.%(ext)s",
"quiet": True,
"no_warnings": True,
"logger": YTDLLogger(),
Expand Down Expand Up @@ -270,14 +270,11 @@ def _perform_audio_download(
# ! The actual download, if there is any error, it'll be here,
try:
data = audio_handler.extract_info(youtube_link)
downloaded_file_path = Path(temp_folder / f"{data['id']}.{data['ext']}")

return downloaded_file_path
except Exception as e: # noqa:E722
# ! This is equivalent to a failed download, we do nothing, the song remains on
# ! download_trackers download queue and all is well...
return Path(temp_folder / f"{data['id']}.{data['ext']}")
except Exception as e:
temp_files = Path(temp_folder).glob(f"{converted_file_name}.*")
for temp_file in temp_files:
temp_file.unlink()

raise e
6 changes: 2 additions & 4 deletions spotdl/download/embed_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@
"explicit": "rtng",
}

TAG_PRESET = {}
for key in M4A_TAG_PRESET.keys():
TAG_PRESET[key] = key
TAG_PRESET = {key: key for key in M4A_TAG_PRESET}


def _set_id3_mp3(converted_file_path: str, song_object: SongObject):
Expand Down Expand Up @@ -274,7 +272,7 @@ def _embed_cover(audio_file, song_object, encoding):

if encoding == "flac":
audio_file.add_picture(image)
elif encoding == "ogg" or encoding == "opus":
elif encoding in ["ogg", "opus"]:
# From the Mutagen docs (https://mutagen.readthedocs.io/en/latest/user/vcomment.html)
image_data = image.write()
encoded_data = base64.b64encode(image_data)
Expand Down
50 changes: 26 additions & 24 deletions spotdl/download/ffmpeg.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,38 @@ def has_correct_version(

output = "".join(process.communicate())

if skip_version_check is False:
result = re.search(r"ffmpeg version \w?(\d+\.)?(\d+)", output)

if result is not None:
version = result.group(0).replace("ffmpeg version ", "")

# remove all non numeric characters from string example: n4.3
version = re.sub(r"[a-zA-Z]", "", version)
# remove all non numeric characters from string example: n4.3
if skip_version_check:
return True

if float(version) < 4.2:
print(
f"Your FFmpeg installation is too old ({version}), please update to 4.2+\n",
file=sys.stderr,
)
return False
result = re.search(r"ffmpeg version \w?(\d+\.)?(\d+)", output)

return True
else:
# fallback to copyright date check
date_result = re.search(r"Copyright \(c\) \d\d\d\d\-\d\d\d\d", output)
# fallback to copyright date check
if result is not None:
version = result.group(0).replace("ffmpeg version ", "")

if date_result is not None:
date = date_result.group(0)
if "2021" in date or "2020" in date:
return True
# remove all non numeric characters from string example: n4.3
version = re.sub(r"[a-zA-Z]", "", version)

print("Your FFmpeg version couldn't be detected", file=sys.stderr)
if float(version) < 4.2:
print(
f"Your FFmpeg installation is too old ({version}), please update to 4.2+\n",
file=sys.stderr,
)
return False
else:

return True
else:
# fallback to copyright date check
date_result = re.search(r"Copyright \(c\) \d\d\d\d\-\d\d\d\d", output)

if date_result is not None:
date = date_result.group(0)
if "2021" in date or "2020" in date:
return True

print("Your FFmpeg version couldn't be detected", file=sys.stderr)
return False


async def convert(
Expand Down
10 changes: 5 additions & 5 deletions spotdl/download/progress_ui_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,7 @@ def print(self, *text, color="green"):
if self.quiet:
return

line = ""
for item in text:
line += str(item) + " "

line = "".join(str(item) + " " for item in text)
if color:
self._rich_progress_bar.console.print(f"[{color}]{line}")
else:
Expand Down Expand Up @@ -271,7 +268,10 @@ def notify_error(self, e, tb):
"""
self.update(message="Error " + self.status)

message = f"Error: {e}\tWhile {self.status}: {self.song_object.display_name}\n {str(tb)}"
message = (
f"Error: {e}\tWhile {self.status}: {self.song_object.display_name}\n {tb}"
)

self.parent.print(message, color="red")

def update(self, message=""):
Expand Down
5 changes: 1 addition & 4 deletions spotdl/download/tracking_file_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,7 @@ def backup_to_disk(self):
return None

# prepare datadumps of all songObj's yet to be downloaded
song_data_dumps = []

for song in self.song_list:
song_data_dumps.append(song.data_dump)
song_data_dumps = [song.data_dump for song in self.song_list]

# ! the default naming of a tracking file is $nameOfFirstSOng.spotdlTrackingFile,
# ! it needs a little fixing because of disallowed characters in file naming
Expand Down
5 changes: 1 addition & 4 deletions spotdl/parsers/query_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,7 @@ def get_youtube_meta_track(
)

song_name = raw_track_meta["name"]
contributing_artist = []
for artist in raw_track_meta["artists"]:
contributing_artist.append(artist["name"])

contributing_artist = [artist["name"] for artist in raw_track_meta["artists"]]
converted_file_name = SongObject.create_file_name(
song_name, [artist["name"] for artist in raw_track_meta["artists"]]
)
Expand Down
2 changes: 1 addition & 1 deletion spotdl/providers/metadata_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


def from_url(spotify_url: str):
if not ("open.spotify.com" in spotify_url and "track" in spotify_url):
if "open.spotify.com" not in spotify_url or "track" not in spotify_url:
raise Exception(f"passed URL is not that of a track: {spotify_url}")

# query spotify for song, artist, album details
Expand Down
27 changes: 12 additions & 15 deletions spotdl/providers/provider_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ def _match_percentage(str1: str, str2: str, score_cutoff: float = 0) -> float:
# ! we build new strings that contain only alphanumerical characters and spaces
# ! and return the partial_ratio of that
except: # noqa:E722
new_str1 = ""

for each_letter in str1:
if each_letter.isalnum() or each_letter.isspace():
new_str1 += each_letter

new_str2 = ""

for each_letter in str2:
if each_letter.isalnum() or each_letter.isspace():
new_str2 += each_letter
new_str1 = "".join(
each_letter
for each_letter in str1
if each_letter.isalnum() or each_letter.isspace()
)

new_str2 = "".join(
each_letter
for each_letter in str2
if each_letter.isalnum() or each_letter.isspace()
)

return fuzz.partial_ratio(new_str1, new_str2, score_cutoff=score_cutoff)

Expand All @@ -48,10 +48,7 @@ def _parse_duration(duration: str) -> float:
try:
# {(1, "s"), (60, "m"), (3600, "h")}
mapped_increments = zip([1, 60, 3600], reversed(duration.split(":")))
seconds = 0
for multiplier, time in mapped_increments:
seconds += multiplier * int(time)

seconds = sum(multiplier * int(time) for multiplier, time in mapped_increments)
return float(seconds)

# ! This usually occurs when the wrong string is mistaken for the duration
Expand Down
40 changes: 19 additions & 21 deletions spotdl/providers/ytm_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def search_and_get_best_match(
if (
isrc_result is not None
and "link" in isrc_result
and name_match is True
and name_match
and time_match > 90
):
return isrc_result["link"]
Expand Down Expand Up @@ -97,7 +97,7 @@ def search_and_get_best_match(
results = {**songs, **videos}

# No matches found
if len(results) == 0:
if not results:
return None

result_items = list(results.items())
Expand Down Expand Up @@ -142,12 +142,11 @@ def _order_ytm_results(

sentence_words = lower_song_name.replace("-", " ").split(" ")

common_word = False

# ! check for common word
for word in sentence_words:
if word != "" and word in lower_result_name:
common_word = True
common_word = any(
# ! check for common word
word != "" and word in lower_result_name
for word in sentence_words
)

# ! if there are no common words, skip result
if not common_word:
Expand Down Expand Up @@ -237,26 +236,25 @@ def _order_ytm_results(
time_match = 100 - non_match_value

if result["type"] == "song":
if album is not None:
if album is None:
# Don't add album_match to average_match if song_name == result and
# result album name != song_album_name
if (
_match_percentage(album.lower(), result["name"].lower()) > 95
and album.lower() != song_album_name.lower()
):
average_match = (artist_match + name_match + time_match) / 3
average_match = (artist_match + name_match + time_match) / 3
elif (
_match_percentage(album.lower(), result["name"].lower()) > 95
and album.lower() != song_album_name.lower()
):
average_match = (artist_match + name_match + time_match) / 3
# Add album to average_match if song_name == result album
# and result album name == song_album_name
else:
average_match = (
artist_match + album_match + name_match + time_match
) / 4
else:
average_match = (artist_match + name_match + time_match) / 3
# Don't add album_match to average_match if we don't have information about the album
# name in the metadata
average_match = (
artist_match + album_match + name_match + time_match
) / 4
else:
average_match = (artist_match + name_match + time_match) / 3
# Don't add album_match to average_match if we don't have information about the album
# name in the metadata

# the results along with the avg Match
links_with_match_value[result["link"]] = average_match
Expand Down
15 changes: 7 additions & 8 deletions spotdl/search/song_gatherer.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def from_spotify_url(
raise OSError(f"{converted_file_name} already downloaded")

# Get the song's downloadable audio link
if use_youtube is True:
if use_youtube:
print(f'Searching YouTube for "{display_name}"', end="\r")
youtube_link = yt_provider.search_and_get_best_match(
song_name, contributing_artists, duration, isrc
Expand Down Expand Up @@ -112,13 +112,12 @@ def from_search_term(
# return first result link or if no matches are found, raise Exception
if result is None or len(result.get("tracks", {}).get("items", [])) == 0:
raise Exception("No song matches found on Spotify")
else:
song_url = "http://open.spotify.com/track/" + result["tracks"]["items"][0]["id"]
try:
song = from_spotify_url(song_url, output_format, use_youtube)
return [song] if song.youtube_link is not None else []
except (LookupError, OSError, ValueError):
return []
song_url = "http://open.spotify.com/track/" + result["tracks"]["items"][0]["id"]
try:
song = from_spotify_url(song_url, output_format, use_youtube)
return [song] if song.youtube_link is not None else []
except (LookupError, OSError, ValueError):
return []


def from_album(
Expand Down
20 changes: 3 additions & 17 deletions spotdl/search/song_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ def __init__(
# Equals method
# for example song_obj1 == song_obj2
def __eq__(self, compared_song) -> bool:
if compared_song.data_dump == self.data_dump:
return True
else:
return False
return compared_song.data_dump == self.data_dump

# ================================
# === Interface Implementation ===
Expand Down Expand Up @@ -79,13 +76,7 @@ def contributing_artists(self) -> List[str]:
# $contributingArtists + songName.mp3, we would want to end up with
# 'Jetta, Mastubs - I'd love to change the world (Mastubs remix).mp3'
# as a song name, it's dumb.

contributingArtists = []

for artist in self._raw_track_meta["artists"]:
contributingArtists.append(artist["name"])

return contributingArtists
return [artist["name"] for artist in self._raw_track_meta["artists"]]

@property
def disc_number(self) -> int:
Expand Down Expand Up @@ -123,12 +114,7 @@ def album_artists(self) -> List[str]:
artist.
"""

albumArtists = []

for artist in self._raw_track_meta["album"]["artists"]:
albumArtists.append(artist["name"])

return albumArtists
return [artist["name"] for artist in self._raw_track_meta["album"]["artists"]]

@property
def album_release(self) -> str:
Expand Down
2 changes: 1 addition & 1 deletion tests/regressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

SONGS = {
"https://open.spotify.com/track/6CN3e26iQSj1N5lomh0mfO": "Eminem - Like Toy Soldiers.mp3",
"https://open.spotify.com/track/3bNv3VuUOKgrf5hu3YcuRo": "Adele - Someone Like You.mp3"
"https://open.spotify.com/track/3bNv3VuUOKgrf5hu3YcuRo": "Adele - Someone Like You.mp3",
}


Expand Down
1 change: 1 addition & 0 deletions tests/test_downloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ def test_download_long_name_song(setup):
with DownloadManager() as dm:
dm.download_single_song(song_obj)


def test_download_multiple_songs(pytestconfig, setup):
if not "--disable-vcr" in pytestconfig.invocation_params.args:
# this test is very similar to the other one, and the http request
Expand Down

0 comments on commit 8bc2362

Please sign in to comment.