Skip to content

Commit

Permalink
Fix search error caused by YouTube Music update (closes #121)
Browse files Browse the repository at this point in the history
  • Loading branch information
sigma67 committed Dec 16, 2020
1 parent cf6596c commit 37111d3
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 21 deletions.
45 changes: 31 additions & 14 deletions ytmusicapi/parsers/browsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ def __init__(self, language):
@i18n
def parse_search_results(self, results, resultType=None):
search_results = []
default_offset = (not resultType) * 2
for result in results:
data = result['musicResponsiveListItemRenderer']
search_result = {}
default = not resultType
if not resultType:
resultType = get_item_text(data, 1).lower()
result_types = ['artist', 'playlist', 'song', 'video']
Expand All @@ -40,27 +40,44 @@ def parse_search_results(self, results, resultType=None):
elif resultType in ['album']:
search_result['title'] = get_item_text(data, 0)
search_result['type'] = get_item_text(data, 1)
search_result['artist'] = get_item_text(data, 2)
search_result['year'] = get_item_text(data, 3)
search_result['artist'] = get_item_text(data, 1, 2)
search_result['year'] = get_item_text(data, 1, 4)

elif resultType in ['playlist']:
search_result['title'] = get_item_text(data, 0)
search_result['author'] = get_item_text(data, 1 + default)
search_result['itemCount'] = get_item_text(data, 2 + default).split(' ')[0]
search_result['author'] = get_item_text(data, 1, default_offset)
search_result['itemCount'] = get_item_text(data, 1,
default_offset + 2).split(' ')[0]

elif resultType in ['song']:
search_result['artists'] = parse_song_artists(data, 1 + default)
hasAlbum = len(data['flexColumns']) == 4 + default
if hasAlbum:
search_result['album'] = parse_song_album(data, 2 + default)
search_result['duration'] = get_item_text(data, 2 + hasAlbum + default)
toggle_menu = find_object_by_key(nav(data, MENU_ITEMS), 'toggleMenuServiceItemRenderer')
runs = get_flex_column_item(data, 1)['text']['runs']
# determine the number of artists
last_artist_index = default_offset
try:
last_artist_index = next(
len(runs) - i - 1 for i, run in enumerate(reversed(runs))
if 'navigationEndpoint' in run
and nav(run, NAVIGATION_BROWSE_ID).startswith('UC'))
except StopIteration: # if single artist is missing the browseId
pass

search_result['artists'] = parse_song_artists_runs(
runs[default_offset:last_artist_index + 1])

if len(runs) - last_artist_index == 5: # has album
search_result['album'] = {
'name': runs[last_artist_index + 2]['text'],
'id': nav(runs[last_artist_index + 2], NAVIGATION_BROWSE_ID)
}
search_result['duration'] = runs[-1]['text']
toggle_menu = find_object_by_key(nav(data, MENU_ITEMS),
'toggleMenuServiceItemRenderer')
search_result['feedbackTokens'] = parse_song_menu_tokens(toggle_menu)

elif resultType in ['video']:
search_result['artist'] = get_item_text(data, 1 + default)
search_result['views'] = get_item_text(data, 2 + default).split(' ')[0]
search_result['duration'] = get_item_text(data, 3 + default)
search_result['artist'] = get_item_text(data, 1, 0 + default_offset)
search_result['views'] = get_item_text(data, 1, 2 + default_offset).split(' ')[0]
search_result['duration'] = get_item_text(data, 1, 4 + default_offset)

elif resultType in ['upload']:
search_result['title'] = get_item_text(data, 0)
Expand Down
16 changes: 9 additions & 7 deletions ytmusicapi/parsers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ def parse_song_artists(data, index):
flex_item = get_flex_column_item(data, index)
if not flex_item:
return None
else:
return parse_song_artists_runs(flex_item['text']['runs'])


def parse_song_artists_runs(runs):
artists = []
for j in range(int(len(flex_item['text']['runs']) / 2) + 1):
for j in range(int(len(runs) / 2) + 1):
artists.append({
'name': get_item_text(data, index, j * 2),
'id': get_browse_id(flex_item, j * 2)
'name': runs[j * 2]['text'],
'id': nav(runs[j * 2], NAVIGATION_BROWSE_ID, True)
})

return artists
Expand All @@ -34,10 +39,7 @@ def parse_song_menu_tokens(item):
elif service_type == "LIBRARY_REMOVE": # swap if already in library
library_add_token, library_remove_token = library_remove_token, library_add_token

return {
'add': library_add_token,
'remove': library_remove_token
}
return {'add': library_add_token, 'remove': library_remove_token}


def get_item_text(item, index, run_index=0, none_if_absent=False):
Expand Down

0 comments on commit 37111d3

Please sign in to comment.