adding latest rework

This commit is contained in:
dtomlinson
2020-03-05 18:50:21 +00:00
parent 14da065144
commit 36686c668d
2 changed files with 132 additions and 195 deletions

View File

@@ -62,14 +62,6 @@ class LyricsConcreteBuilder(ABC):
def browse_releases(self) -> dict: def browse_releases(self) -> dict:
pass pass
@abstractstaticmethod
def get_album_info_list(self) -> list:
pass
@abstractstaticmethod
def paginate_results(self) -> list:
pass
@abstractmethod @abstractmethod
def __init__(self) -> None: def __init__(self) -> None:
pass pass
@@ -94,10 +86,6 @@ class LyricsConcreteBuilder(ABC):
def get_top_five_results(self) -> None: def get_top_five_results(self) -> None:
pass pass
@abstractmethod
def do_search_albums(self) -> None:
pass
class LyricsBuilder(LyricsConcreteBuilder): class LyricsBuilder(LyricsConcreteBuilder):
"""docstring for LyricsBuilder""" """docstring for LyricsBuilder"""
@@ -176,36 +164,36 @@ class LyricsBuilder(LyricsConcreteBuilder):
) )
return releases return releases
@staticmethod # @staticmethod
def get_album_info_list( # def get_album_info_list(
album_info_list: list, album_tracker: set, releases: addict.Dict # album_info_list: list, album_tracker: set, releases: addict.Dict
) -> list: # ) -> list:
for i in releases['release-list']: # for i in releases['release-list']:
_throwaway_dict = addict.Dict() # _throwaway_dict = addict.Dict()
_throwaway_dict.album = i.title # _throwaway_dict.album = i.title
_throwaway_dict.year = i.date.split('-')[0] # _throwaway_dict.year = i.date.split('-')[0]
_throwaway_dict.tracks = [ # _throwaway_dict.tracks = [
j.recording.title for j in i['medium-list'][0]['track-list'] # j.recording.title for j in i['medium-list'][0]['track-list']
] # ]
if i.title not in album_tracker: # if i.title not in album_tracker:
album_tracker.add(i.title) # album_tracker.add(i.title)
album_info_list.append(_throwaway_dict) # album_info_list.append(_throwaway_dict)
else: # else:
pass # pass
return album_info_list, album_tracker # return album_info_list, album_tracker
@staticmethod # @staticmethod
def paginate_results( # def paginate_results(
releases: addict.Dict, duplicated_tracks: list # releases: addict.Dict, duplicated_tracks: list
) -> List: # ) -> List:
tracks = [ # tracks = [
j.recording.title # j.recording.title
for i in releases['release-list'] # for i in releases['release-list']
for j in i['medium-list'][0]['track-list'] # for j in i['medium-list'][0]['track-list']
] # ]
for i in itertools.chain(tracks): # for i in itertools.chain(tracks):
duplicated_tracks.append(i) # duplicated_tracks.append(i)
return duplicated_tracks # return duplicated_tracks
def __init__(self) -> None: def __init__(self) -> None:
self.reset() self.reset()
@@ -247,85 +235,112 @@ class LyricsBuilder(LyricsConcreteBuilder):
) )
return self return self
def do_search_albums(self) -> None: def find_all_albums(self) -> None:
album_info_list = list()
album_tracker = set()
duplicated_tracks = list()
limit, offset, page = (100, 0, 1) limit, offset, page = (100, 0, 1)
raw_releases = self.browse_releases( resp_0 = addict.Dict(
artist_id=self.artist_id, musicbrainzngs.browse_release_groups(
limit=limit, artist=self.artist_id, release_type=['album'], limit=limit
release_type=['album'], )
offset=offset,
includes=['recordings'],
) )
releases = addict.Dict(raw_releases) total_releases = resp_0['release-group-count']
response_releases = len(resp_0['release-group-list'])
# print(total_releases)
# print(response_releases)
# import json with click.progressbar(
# import os length=total_releases,
# with open(f'{os.getcwd()}/output.json', 'w+') as file: label=f'Searching Musicbrainz for all albums from {self.artist}',
# json.dump(releases, file, indent=4, sort_keys=True)
# raise SystemExit
duplicated_tracks = self.paginate_results(releases, duplicated_tracks)
# Get album info list
album_info_list, album_tracker = self.get_album_info_list(
album_info_list, album_tracker, releases
)
bar_count = len(releases['release-list'])
previous_bar_count = 0
with PieSpinner(
f'Finding all tracks in all albums for {self.artist}'
'from Musicbrainz '
) as bar: ) as bar:
while bar_count != previous_bar_count:
release_group_ids = addict.Dict(
(i.id, i.title)
for i in resp_0['release-group-list']
if i.type == 'Album'
)
bar.update(response_releases)
while response_releases > 0:
# Get next page
offset += limit offset += limit
page += 1 page += 1
# Get next page
raw_page_releases = self.browse_releases(
artist_id=self.artist_id,
limit=limit,
release_type=['album'],
offset=offset,
includes=['recordings'],
)
page_releases = addict.Dict(raw_page_releases)
# Update list resp_1 = addict.Dict(
duplicated_tracks = self.paginate_results( musicbrainzngs.browse_release_groups(
page_releases, duplicated_tracks artist=self.artist_id,
release_type=['album'],
limit=limit,
offset=offset,
)
)
response_releases = len(resp_1['release-group-list'])
release_group_ids = addict.Dict(
**release_group_ids,
**addict.Dict(
(i.id, i.title)
for i in resp_1['release-group-list']
if i.type == 'Album'
),
)
bar.update(response_releases)
self.release_group_ids = release_group_ids
click.echo(f'Found {len(release_group_ids)} albums for {self.artist}.')
del (resp_0, resp_1)
return self
def find_all_tracks(self) -> None:
self.all_albums = list()
total_albums = len(self.release_group_ids)
with click.progressbar(
length=total_albums,
label=(
'Searching Musicbrainz for all songs in all albums for '
f'{self.artist}'),
) as bar:
for id, alb in self.release_group_ids.items():
resp_0 = addict.Dict(
musicbrainzngs.browse_releases(
release_group=id,
release_type=['album'],
includes=['recordings'],
limit=100,
)
) )
# Update album info list album_track_count = [
( i['medium-list'][0]['track-count']
album_info_list, for i in resp_0['release-list']
album_tracker, ]
) = self.get_album_info_list(
album_info_list, album_tracker, releases max_track_pos = album_track_count.index(max(album_track_count))
album_tracks = resp_0['release-list'][max_track_pos]
album_year = resp_0['release-list'][max_track_pos].date.split(
'-'
)[0]
album_tracks = addict.Dict(
(
alb + f' [{album_year}]',
[
i.recording.title
for i in resp_0['release-list'][max_track_pos][
'medium-list'
][0]['track-list']
],
)
) )
previous_bar_count = bar_count bar.update(1)
bar_count += len(page_releases['release-list'])
bar.next()
total_releases_count = bar_count
tracks = set(duplicated_tracks) self.all_albums.append(album_tracks)
click.echo(
f'Musicbrainz found {len(tracks)} unique tracks in '
f'{total_releases_count} releases for {self.artist}'
)
# Set properties
self.all_tracks = tracks
self.all_albums_with_tracks = album_info_list
pprint(self.all_albums_with_tracks)
return self return self
@@ -362,7 +377,7 @@ class LyricsClickDirector:
_position = [] _position = []
click.echo( click.echo(
f'Musicbrainz found several results for ' f'Musicbrainz found several results for '
f'{self.builder.artist[0]}. Which artist/group do you want?', f'{self.builder.artist[0]}. Which artist/group do you want?'
) )
for i, j in zip(self.builder._top_five_results, range(1, 6)): for i, j in zip(self.builder._top_five_results, range(1, 6)):
click.echo( click.echo(
@@ -377,13 +392,17 @@ class LyricsClickDirector:
type=click.IntRange( type=click.IntRange(
1, len(self.builder._top_five_results) 1, len(self.builder._top_five_results)
), ),
), )
) )
choice = _position[chosen - 1] choice = _position[chosen - 1]
click.echo(f'You chose {self.builder._sort_names.get(choice)}') click.echo(f'You chose {self.builder._sort_names.get(choice)}')
self._artist = self.builder._sort_names.get(choice).split('|')[0] self._artist = self.builder._sort_names.get(choice).split('|')[0]
self._artist_id = choice self._artist_id = choice
# Set artist and artistID on builder + product
self.builder.artist_id = self._artist_id
self.builder.artist = self._artist
elif artist_meta is None: elif artist_meta is None:
click.echo( click.echo(
f'Musicbrainz did not find any results for ' f'Musicbrainz did not find any results for '
@@ -392,15 +411,6 @@ class LyricsClickDirector:
) )
raise SystemExit() raise SystemExit()
def _search_for_all_tracks(self) -> None:
self.builder.do_search_albums()
pprint(self.builder._product.all_tracks)
# pprint(self.builder._product.all_albums_with_tracks)
def _set_artist_id_on_product(self) -> None:
self.builder.artist_id = self._artist_id
self.builder.artist = self._artist
@dataclass @dataclass
class Lyrics: class Lyrics:

View File

@@ -1,79 +1,14 @@
from pprint import pprint # from pprint import pprint
from typing import Union from typing import Union
import click import click
import musicbrainzngs # import musicbrainzngs
from musicbrainzapi.cli.cli import pass_environment from musicbrainzapi.cli.cli import pass_environment
from musicbrainzapi.api import authenticate # from musicbrainzapi.api import authenticate
from musicbrainzapi.api.command_builders import lyrics from musicbrainzapi.api.command_builders import lyrics
class LyricsInfo:
"""docstring for LyricsInfo"""
def __init__(self, artist: str, country: str = None) -> None:
authenticate.set_useragent()
self.artist = artist
self.country = country
super().__init__()
def _search_artist(self) -> None:
self.artists = musicbrainzngs.search_artists(
artist=self.artist, country=self.country
)
# pprint(self.artists['artist-list'])
if self.artists.get('artist-count') == 0:
self.chosen_artist = 'Null'
# Get all results
self.sort_names = dict(
(i.get('id'), f'{i.get("sort-name")} | {i.get("disambiguation")}')
if i.get('disambiguation') is not None
else (i.get('id'), f'{i.get("sort-name")}')
for i in self.artists['artist-list']
)
# Get accuracy scores
self._accuracy_scores = dict(
(i.get('id'), int(i.get('ext:score', '0')))
for i in self.artists['artist-list']
)
# pprint(self._accuracy_scores)
# Get top 5 results
self.top_five_results = dict(
(i, self._accuracy_scores.get(i))
for i in sorted(
self._accuracy_scores,
key=self._accuracy_scores.get,
reverse=True,
)[0:5]
)
# pprint(self.top_five_results)
# Check for 100% match
self.chosen_artist = None
for i, j in self.top_five_results.items():
self.chosen_artist = 'Multiple' if j <= 100 else None
return self
class CommandUtility:
"""docstring for CommandUtility"""
def get_multiple_options(option: tuple):
for i in option:
pass
# @click.argument('path', required=False, type=click.Path(resolve_path=True)) # @click.argument('path', required=False, type=click.Path(resolve_path=True))
# @click.command(short_help='a test command') # @click.command(short_help='a test command')
@click.option( @click.option(
@@ -100,18 +35,10 @@ def cli(ctx, artist: str, country: Union[str, None]) -> None:
""" """
Search for lyrics of an Artist/Group. Search for lyrics of an Artist/Group.
""" """
# print(artist)
director = lyrics.LyricsClickDirector() director = lyrics.LyricsClickDirector()
builder = lyrics.LyricsBuilder() builder = lyrics.LyricsBuilder()
director.builder = builder director.builder = builder
director._get_initial_artists(artist, country) director._get_initial_artists(artist, country)
director._confirm_final_artist() director._confirm_final_artist()
director._set_artist_id_on_product() director.builder.find_all_albums()
director._search_for_all_tracks() director.builder.find_all_tracks()
# builder.do_filter_albums_official()
# builder.do_search_album_tracks()
if __name__ == '__main__':
# LyricsInfo('Queenifie')._search_artist()
LyricsInfo('Que')._search_artist()