[cleanup] Fix invalid info dict fields (#17007)

Authored by: seproDev
This commit is contained in:
sepro 2026-06-22 00:48:47 +02:00 committed by GitHub
parent da99b21b2d
commit 98036ccd4f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 52 additions and 43 deletions

View File

@ -70,7 +70,7 @@ class AdobeTVVideoIE(InfoExtractor):
for fmt in fmts: for fmt in fmts:
fmt.update(traverse_obj(source, { fmt.update(traverse_obj(source, {
'duration': ('duration', {float_or_none(scale=1000)}), 'duration': ('duration', {float_or_none(scale=1000)}),
'filesize': ('kilobytes', {float_or_none(invscale=1000)}), 'filesize': ('kilobytes', {int_or_none(invscale=1000)}),
'format_id': (('format', 'label'), {str}, all, {lambda x: join_nonempty(*x)}), 'format_id': (('format', 'label'), {str}, all, {lambda x: join_nonempty(*x)}),
'height': ('height', {int_or_none}), 'height': ('height', {int_or_none}),
'tbr': ('bitrate', {int_or_none}), 'tbr': ('bitrate', {int_or_none}),

View File

@ -13,6 +13,7 @@ from ..utils import (
int_or_none, int_or_none,
orderedSet, orderedSet,
parse_iso8601, parse_iso8601,
str_or_none,
url_or_none, url_or_none,
urlencode_postdata, urlencode_postdata,
urljoin, urljoin,
@ -465,7 +466,7 @@ class AfreecaTVUserIE(AfreecaTVBaseIE):
for item in info['data']: for item in info['data']:
yield self.url_result( yield self.url_result(
f'https://vod.sooplive.com/player/{item["title_no"]}/', f'https://vod.sooplive.com/player/{item["title_no"]}/',
AfreecaTVIE, item['title_no'], item.get('title_name')) AfreecaTVIE, str_or_none(item['title_no']), item.get('title_name'))
def _real_extract(self, url): def _real_extract(self, url):
user_id, user_type = self._match_valid_url(url).group('id', 'slug_type') user_id, user_type = self._match_valid_url(url).group('id', 'slug_type')

View File

@ -155,7 +155,7 @@ class AluraCourseIE(AluraIE): # XXX: Do not subclass from concrete IE
'_type': 'url_transparent', '_type': 'url_transparent',
'id': self._match_id(video_url), 'id': self._match_id(video_url),
'url': video_url, 'url': video_url,
'id_key': self.ie_key(), 'ie_key': self.ie_key(),
'chapter': chapter, 'chapter': chapter,
'chapter_number': chapter_number, 'chapter_number': chapter_number,
} }

View File

@ -2,7 +2,7 @@ import random
import urllib.parse import urllib.parse
from .common import InfoExtractor from .common import InfoExtractor
from ..utils import ExtractorError, str_or_none, try_get from ..utils import ExtractorError, str_or_none, try_get, url_or_none
class AudiusBaseIE(InfoExtractor): class AudiusBaseIE(InfoExtractor):
@ -143,6 +143,8 @@ class AudiusIE(AudiusBaseIE):
thumbnails = [] thumbnails = []
if isinstance(artworks_data, dict): if isinstance(artworks_data, dict):
for quality_key, thumbnail_url in artworks_data.items(): for quality_key, thumbnail_url in artworks_data.items():
if not url_or_none(thumbnail_url):
continue
thumbnail = { thumbnail = {
'url': thumbnail_url, 'url': thumbnail_url,
} }

View File

@ -1398,7 +1398,9 @@ class BilibiliSpaceAudioIE(BilibiliSpaceBaseIE):
def get_entries(page_data): def get_entries(page_data):
# data is None when the playlist is empty # data is None when the playlist is empty
for entry in page_data.get('data') or []: for entry in page_data.get('data') or []:
yield self.url_result(f'https://www.bilibili.com/audio/au{entry["id"]}', BilibiliAudioIE, entry['id']) yield self.url_result(
f'https://www.bilibili.com/audio/au{entry["id"]}',
BilibiliAudioIE, str_or_none(entry['id']))
_, paged_list = self._extract_playlist(fetch_page, get_metadata, get_entries) _, paged_list = self._extract_playlist(fetch_page, get_metadata, get_entries)
return self.playlist_result(paged_list, playlist_id) return self.playlist_result(paged_list, playlist_id)

View File

@ -235,7 +235,7 @@ class ERRArhiivIE(InfoExtractor):
'title': 'Kontsertpalad: 255 | L. Beethoveni sonaat c-moll, "Pateetiline"', 'title': 'Kontsertpalad: 255 | L. Beethoveni sonaat c-moll, "Pateetiline"',
'description': 'md5:a70f4ff23c3618f3be63f704bccef063', 'description': 'md5:a70f4ff23c3618f3be63f704bccef063',
'series': 'Kontsertpalad', 'series': 'Kontsertpalad',
'episode_id': 255, 'episode_id': '255',
'timestamp': 1666152162, 'timestamp': 1666152162,
'upload_date': '20221019', 'upload_date': '20221019',
'release_year': 1970, 'release_year': 1970,
@ -282,7 +282,7 @@ class ERRArhiivIE(InfoExtractor):
'title': ('title', {str}), 'title': ('title', {str}),
'series': ('seriesTitle', {str}, filter), 'series': ('seriesTitle', {str}, filter),
'series_id': ('seriesId', {str}, filter), 'series_id': ('seriesId', {str}, filter),
'episode_id': ('episode', {int_or_none}), 'episode_id': ('episode', {str}, filter),
'description': ('synopsis', {str}, filter), 'description': ('synopsis', {str}, filter),
'timestamp': ('uploadDate', {parse_iso8601}), 'timestamp': ('uploadDate', {parse_iso8601}),
'modified_timestamp': ('dateModified', {parse_iso8601}), 'modified_timestamp': ('dateModified', {parse_iso8601}),

View File

@ -125,20 +125,20 @@ class IchinanaLiveClipIE(InfoExtractor):
formats = [] formats = []
if view_data.get('videoURL'): if view_data.get('videoURL'):
formats.append({ formats.append({
'id': 'video', 'format_id': 'video',
'url': view_data['videoURL'], 'url': view_data['videoURL'],
'quality': -1, 'quality': -1,
}) })
if view_data.get('transcodeURL'): if view_data.get('transcodeURL'):
formats.append({ formats.append({
'id': 'transcode', 'format_id': 'transcode',
'url': view_data['transcodeURL'], 'url': view_data['transcodeURL'],
'quality': -1, 'quality': -1,
}) })
if view_data.get('srcVideoURL'): if view_data.get('srcVideoURL'):
# highest quality # highest quality
formats.append({ formats.append({
'id': 'srcVideo', 'format_id': 'srcVideo',
'url': view_data['srcVideoURL'], 'url': view_data['srcVideoURL'],
'quality': 1, 'quality': 1,
}) })

View File

@ -1,5 +1,5 @@
from .common import InfoExtractor from .common import InfoExtractor
from ..utils import int_or_none, unified_timestamp, url_or_none from ..utils import int_or_none, str_or_none, unified_timestamp, url_or_none
from ..utils.traversal import traverse_obj from ..utils.traversal import traverse_obj
@ -83,7 +83,7 @@ class IdagioPlaylistBaseIE(InfoExtractor):
recording_id = track_data['recording']['id'] recording_id = track_data['recording']['id']
yield self.url_result( yield self.url_result(
f'https://app.idagio.com/recordings/{recording_id}?trackId={track_id}', f'https://app.idagio.com/recordings/{recording_id}?trackId={track_id}',
ie=IdagioTrackIE, video_id=track_id) ie=IdagioTrackIE, video_id=str_or_none(track_id))
def _real_extract(self, url): def _real_extract(self, url):
playlist_id = self._match_id(url) playlist_id = self._match_id(url)

View File

@ -13,6 +13,7 @@ from ..utils import (
merge_dicts, merge_dicts,
parse_duration, parse_duration,
smuggle_url, smuggle_url,
str_or_none,
try_get, try_get,
url_basename, url_basename,
url_or_none, url_or_none,
@ -247,7 +248,7 @@ class ITVBTCCIE(InfoExtractor):
for video in json_map: for video in json_map:
if not any(traverse_obj(video, ('data', attr)) == 'Brightcove' for attr in ('name', 'type')): if not any(traverse_obj(video, ('data', attr)) == 'Brightcove' for attr in ('name', 'type')):
continue continue
video_id = video['data']['id'] video_id = str_or_none(video['data']['id'])
account_id = video['data']['accountId'] account_id = video['data']['accountId']
player_id = video['data']['playerId'] player_id = video['data']['playerId']
entries.append(self.url_result( entries.append(self.url_result(

View File

@ -5,7 +5,6 @@ from ..utils import (
ExtractorError, ExtractorError,
clean_html, clean_html,
determine_ext, determine_ext,
float_or_none,
int_or_none, int_or_none,
str_or_none, str_or_none,
url_or_none, url_or_none,
@ -130,7 +129,7 @@ class LecturioIE(LecturioBaseIE):
f = { f = {
'url': file_url, 'url': file_url,
'format_id': label, 'format_id': label,
'filesize': float_or_none(filesize, invscale=1000), 'filesize': int_or_none(filesize, invscale=1000),
} }
if label: if label:
mobj = re.match(r'(\d+)p\s*\(([^)]+)\)', label) mobj = re.match(r'(\d+)p\s*\(([^)]+)\)', label)

View File

@ -658,7 +658,7 @@ class NetEaseMusicDjRadioIE(NetEaseMusicBaseIE):
entries.extend(self.url_result( entries.extend(self.url_result(
f'http://music.163.com/#/program?id={program["id"]}', NetEaseMusicProgramIE, f'http://music.163.com/#/program?id={program["id"]}', NetEaseMusicProgramIE,
program['id'], program.get('name')) for program in info['programs']) str_or_none(program['id']), program.get('name')) for program in info['programs'])
if not metainfo: if not metainfo:
metainfo = traverse_obj(info, ('programs', 0, 'radio', { metainfo = traverse_obj(info, ('programs', 0, 'radio', {
'title': ('name', {str}), 'title': ('name', {str}),

View File

@ -1686,7 +1686,7 @@ class PeerTubePlaylistIE(InfoExtractor):
'description': 'Diversas palestras do Richard Stallman no Brasil.', 'description': 'Diversas palestras do Richard Stallman no Brasil.',
'title': 'Richard Stallman no Brasil', 'title': 'Richard Stallman no Brasil',
'channel': 'debianbrazilteam', 'channel': 'debianbrazilteam',
'channel_id': 1522, 'channel_id': '1522',
'thumbnail': r're:https?://peertube\.debian\.social/lazy-static/thumbnails/.+\.jpg', 'thumbnail': r're:https?://peertube\.debian\.social/lazy-static/thumbnails/.+\.jpg',
'timestamp': 1599676222, 'timestamp': 1599676222,
'upload_date': '20200909', 'upload_date': '20200909',
@ -1698,7 +1698,7 @@ class PeerTubePlaylistIE(InfoExtractor):
'id': 'chocobozzz', 'id': 'chocobozzz',
'title': 'chocobozzz', 'title': 'chocobozzz',
'channel': 'chocobozzz', 'channel': 'chocobozzz',
'channel_id': 37855, 'channel_id': '37855',
'thumbnail': '', 'thumbnail': '',
'timestamp': 1553874564, 'timestamp': 1553874564,
'upload_date': '20190329', 'upload_date': '20190329',
@ -1710,7 +1710,7 @@ class PeerTubePlaylistIE(InfoExtractor):
'id': 'bf54d359-cfad-4935-9d45-9d6be93f63e8', 'id': 'bf54d359-cfad-4935-9d45-9d6be93f63e8',
'title': 'Les vidéos de Framasoft', 'title': 'Les vidéos de Framasoft',
'channel': 'framasoft', 'channel': 'framasoft',
'channel_id': 3, 'channel_id': '3',
'thumbnail': '', 'thumbnail': '',
'timestamp': 1519917377, 'timestamp': 1519917377,
'upload_date': '20180301', 'upload_date': '20180301',
@ -1720,9 +1720,10 @@ class PeerTubePlaylistIE(InfoExtractor):
'url': 'https://peertube2.cpy.re/c/blender_open_movies@video.blender.org/videos', 'url': 'https://peertube2.cpy.re/c/blender_open_movies@video.blender.org/videos',
'info_dict': { 'info_dict': {
'id': 'blender_open_movies@video.blender.org', 'id': 'blender_open_movies@video.blender.org',
'title': 'Official Blender Open Movies', 'title': 'Blender Open Movies',
'description': 'md5:3dfabff00857fe3896fb222eb2cb1b80',
'channel': 'blender', 'channel': 'blender',
'channel_id': 1926, 'channel_id': '1926',
'thumbnail': '', 'thumbnail': '',
'timestamp': 1540472902, 'timestamp': 1540472902,
'upload_date': '20181025', 'upload_date': '20181025',
@ -1756,7 +1757,7 @@ class PeerTubePlaylistIE(InfoExtractor):
playlist_description = info.get('description') playlist_description = info.get('description')
playlist_timestamp = unified_timestamp(info.get('createdAt')) playlist_timestamp = unified_timestamp(info.get('createdAt'))
channel = try_get(info, lambda x: x['ownerAccount']['name']) or info.get('displayName') channel = try_get(info, lambda x: x['ownerAccount']['name']) or info.get('displayName')
channel_id = try_get(info, lambda x: x['ownerAccount']['id']) or info.get('id') channel_id = str_or_none(try_get(info, lambda x: x['ownerAccount']['id']) or info.get('id'))
thumbnail = format_field(info, 'thumbnailPath', f'https://{host}%s') thumbnail = format_field(info, 'thumbnailPath', f'https://{host}%s')
entries = OnDemandPagedList(functools.partial( entries = OnDemandPagedList(functools.partial(

View File

@ -79,7 +79,6 @@ class QQMusicIE(QQMusicBaseIE):
'creators': ['ケーキ姫', 'JUMA'], 'creators': ['ケーキ姫', 'JUMA'],
'genres': ['Pop'], 'genres': ['Pop'],
'description': 'md5:b5261f3d595657ae561e9e6aee7eb7d9', 'description': 'md5:b5261f3d595657ae561e9e6aee7eb7d9',
'size': 4501244,
'thumbnail': r're:^https?://.*\.jpg(?:$|[#?])', 'thumbnail': r're:^https?://.*\.jpg(?:$|[#?])',
'subtitles': 'count:1', 'subtitles': 'count:1',
}, },
@ -113,7 +112,6 @@ class QQMusicIE(QQMusicBaseIE):
'creators': ['李季美'], 'creators': ['李季美'],
'genres': [], 'genres': [],
'description': 'md5:fc711212aa623b28534954dc4bd67385', 'description': 'md5:fc711212aa623b28534954dc4bd67385',
'size': 3535730,
'thumbnail': r're:^https?://.*\.jpg(?:$|[#?])', 'thumbnail': r're:^https?://.*\.jpg(?:$|[#?])',
}, },
}, { }, {
@ -191,7 +189,7 @@ class QQMusicIE(QQMusicBaseIE):
'url': urljoin('https://dl.stream.qqmusic.qq.com', media_info['purl']), 'url': urljoin('https://dl.stream.qqmusic.qq.com', media_info['purl']),
'format': format_id, 'format': format_id,
'format_id': format_id, 'format_id': format_id,
'size': traverse_obj(info_data, ('file', f'size_{format_id}', {int_or_none})), 'filesize': traverse_obj(info_data, ('file', f'size_{format_id}', {int_or_none})),
'quality': format_info.get('preference'), 'quality': format_info.get('preference'),
'abr': format_info.get('abr'), 'abr': format_info.get('abr'),
'ext': format_info.get('ext'), 'ext': format_info.get('ext'),
@ -261,7 +259,6 @@ class QQMusicSingerIE(QQMusicBaseIE):
'creators': ['桃几OvO'], 'creators': ['桃几OvO'],
'genres': ['Pop'], 'genres': ['Pop'],
'description': 'md5:4296005a04edcb5cdbe0889d5055a7ae', 'description': 'md5:4296005a04edcb5cdbe0889d5055a7ae',
'size': 3970822,
'thumbnail': r're:^https?://.*\.jpg(?:$|[#?])', 'thumbnail': r're:^https?://.*\.jpg(?:$|[#?])',
}, },
}], }],

View File

@ -7,6 +7,7 @@ from ..networking.exceptions import HTTPError
from ..utils import ( from ..utils import (
ExtractorError, ExtractorError,
dict_get, dict_get,
str_or_none,
strip_or_none, strip_or_none,
traverse_obj, traverse_obj,
try_get, try_get,
@ -80,7 +81,11 @@ class RCTIPlusIE(RCTIPlusBaseIE):
'timestamp': 1587561540, 'timestamp': 1587561540,
'upload_date': '20200422', 'upload_date': '20200422',
'series': 'iNews Malam', 'series': 'iNews Malam',
'channel': 'INews', 'channel': 'INEWS',
'channel_id': '4',
'thumbnail': 'https://static.rctiplus.id/media/2000/files/fta_rcti/Portrait/iNews_Malam/inews_malam_768x1152.jpg',
'categories': ['Hard News'],
'live_status': 'not_live',
}, },
}, { # Missed event/replay }, { # Missed event/replay
'url': 'https://www.rctiplus.com/missed-event/2507/mou-signing-ceremony-27-juli-2021-1400-wib', 'url': 'https://www.rctiplus.com/missed-event/2507/mou-signing-ceremony-27-juli-2021-1400-wib',
@ -117,12 +122,13 @@ class RCTIPlusIE(RCTIPlusBaseIE):
'url': 'https://www.rctiplus.com/live-event/1/rcti', 'url': 'https://www.rctiplus.com/live-event/1/rcti',
'info_dict': { 'info_dict': {
'id': 'v_lt1', 'id': 'v_lt1',
'title': 'RCTI', 'title': r're:RCTI \d{4}-\d{2}-\d{2} \d{2}:\d{2}',
'display_id': 'rcti', 'display_id': 'rcti',
'ext': 'mp4', 'ext': 'mp4',
'timestamp': 1546344000, 'timestamp': 1546344000,
'upload_date': '20190101', 'upload_date': '20190101',
'is_live': True, 'thumbnail': 'https://static.rctiplus.id/media/2000/files/fta_rcti/Channel_Logo/por-RCTI.png',
'live_status': 'is_live',
}, },
'params': { 'params': {
'skip_download': True, 'skip_download': True,
@ -207,7 +213,7 @@ class RCTIPlusIE(RCTIPlusBaseIE):
'season_number': video_meta.get('season'), 'season_number': video_meta.get('season'),
'episode_number': video_meta.get('episode'), 'episode_number': video_meta.get('episode'),
'channel': video_json.get('tv_name'), 'channel': video_json.get('tv_name'),
'channel_id': video_json.get('tv_id'), 'channel_id': str_or_none(video_json.get('tv_id')),
'formats': formats, 'formats': formats,
'thumbnails': thumbnails, 'thumbnails': thumbnails,
'is_live': video_type == 'live-event' and not is_upcoming, 'is_live': video_type == 'live-event' and not is_upcoming,

View File

@ -30,7 +30,7 @@ class RedGifsBaseIE(InfoExtractor):
quality = qualities(tuple(self._FORMATS.keys())) quality = qualities(tuple(self._FORMATS.keys()))
orig_height = int_or_none(gif_data.get('height')) orig_height = int_or_none(gif_data.get('height'))
aspect_ratio = try_get(gif_data, lambda x: orig_height / x['width']) aspect_ratio = try_get(gif_data, lambda x: x['width'] / orig_height)
formats = [] formats = []
for format_id, height in self._FORMATS.items(): for format_id, height in self._FORMATS.items():
@ -41,7 +41,7 @@ class RedGifsBaseIE(InfoExtractor):
formats.append({ formats.append({
'url': video_url, 'url': video_url,
'format_id': format_id, 'format_id': format_id,
'width': height * aspect_ratio if aspect_ratio else None, 'width': int_or_none(height * aspect_ratio) if aspect_ratio else None,
'height': height, 'height': height,
'quality': quality(format_id), 'quality': quality(format_id),
}) })

View File

@ -77,7 +77,7 @@ class Rule34VideoIE(InfoExtractor):
formats.append({ formats.append({
'url': url, 'url': url,
'ext': ext.lower(), 'ext': ext.lower(),
'quality': quality, 'quality': int_or_none(quality),
}) })
categories, creators, uploader, uploader_url = [None] * 4 categories, creators, uploader, uploader_url = [None] * 4

View File

@ -1,6 +1,6 @@
from .bunnycdn import BunnyCdnIE from .bunnycdn import BunnyCdnIE
from .common import InfoExtractor from .common import InfoExtractor
from ..utils import make_archive_id, try_get, unified_timestamp from ..utils import make_archive_id, str_or_none, try_get, unified_timestamp
class SovietsClosetBaseIE(InfoExtractor): class SovietsClosetBaseIE(InfoExtractor):
@ -182,7 +182,7 @@ class SovietsClosetPlaylistIE(SovietsClosetBaseIE):
entries = [{ entries = [{
**self.url_result(f'https://sovietscloset.com/video/{stream["id"]}', ie=SovietsClosetIE.ie_key()), **self.url_result(f'https://sovietscloset.com/video/{stream["id"]}', ie=SovietsClosetIE.ie_key()),
**self.video_meta( **self.video_meta(
video_id=stream['id'], game_name=game['name'], category_name=category.get('name'), video_id=str_or_none(stream['id']), game_name=game['name'], category_name=category.get('name'),
episode_number=i + 1, stream_date=stream.get('date')), episode_number=i + 1, stream_date=stream.get('date')),
} for i, stream in enumerate(category['streams'])] } for i, stream in enumerate(category['streams'])]

View File

@ -39,7 +39,7 @@ def _extract_episode(data, episode_id=None):
return { return {
'id': str(episode_id or data['episode_id']), 'id': str(episode_id or data['episode_id']),
'url': download_url, 'url': download_url,
'display_id': data.get('permalink'), 'display_id': str_or_none(data.get('permalink')),
'title': title, 'title': title,
'description': data.get('description'), 'description': data.get('description'),
'timestamp': unified_timestamp(data.get('published_at')), 'timestamp': unified_timestamp(data.get('published_at')),

View File

@ -105,7 +105,7 @@ class TeamTreeHouseIE(InfoExtractor):
'_type': 'url_transparent', '_type': 'url_transparent',
'id': self._match_id(page_url), 'id': self._match_id(page_url),
'url': page_url, 'url': page_url,
'id_key': self.ie_key(), 'ie_key': self.ie_key(),
} }
if extract_info: if extract_info:
entry.update(extract_info) entry.update(extract_info)

View File

@ -94,7 +94,7 @@ class WeiboBaseIE(InfoExtractor):
**parse_resolution(resolution), **parse_resolution(resolution),
**traverse_obj(media_info, ( **traverse_obj(media_info, (
'video_details', lambda _, v: v['label'].startswith(format_id), { 'video_details', lambda _, v: v['label'].startswith(format_id), {
'size': ('size', {int_or_none}), 'filesize': ('size', {int_or_none}),
'tbr': ('bitrate', {int_or_none}), 'tbr': ('bitrate', {int_or_none}),
}, },
), get_all=False), ), get_all=False),

View File

@ -36,11 +36,11 @@ class XimalayaIE(XimalayaBaseIE):
'thumbnail': r're:^https?://.*\.jpg', 'thumbnail': r're:^https?://.*\.jpg',
'thumbnails': [ 'thumbnails': [
{ {
'name': 'cover_url', 'id': 'cover_url',
'url': r're:^https?://.*\.jpg', 'url': r're:^https?://.*\.jpg',
}, },
{ {
'name': 'cover_url_142', 'id': 'cover_url_142',
'url': r're:^https?://.*\.jpg', 'url': r're:^https?://.*\.jpg',
'width': 180, 'width': 180,
'height': 180, 'height': 180,
@ -65,11 +65,11 @@ class XimalayaIE(XimalayaBaseIE):
'thumbnail': r're:^https?://.*\.jpg', 'thumbnail': r're:^https?://.*\.jpg',
'thumbnails': [ 'thumbnails': [
{ {
'name': 'cover_url', 'id': 'cover_url',
'url': r're:^https?://.*\.jpg', 'url': r're:^https?://.*\.jpg',
}, },
{ {
'name': 'cover_url_142', 'id': 'cover_url_142',
'url': r're:^https?://.*\.jpg', 'url': r're:^https?://.*\.jpg',
'width': 180, 'width': 180,
'height': 180, 'height': 180,
@ -172,7 +172,7 @@ class XimalayaIE(XimalayaBaseIE):
for k in audio_info: for k in audio_info:
# cover pics kyes like: cover_url', 'cover_url_142' # cover pics kyes like: cover_url', 'cover_url_142'
if k.startswith('cover_url'): if k.startswith('cover_url'):
thumbnail = {'name': k, 'url': audio_info[k]} thumbnail = {'id': k, 'url': audio_info[k]}
if k == 'cover_url_142': if k == 'cover_url_142':
thumbnail['width'] = 180 thumbnail['width'] = 180
thumbnail['height'] = 180 thumbnail['height'] = 180