Agregada integracion a cache de recordings
Fue un leseo la parte de recordings_of_release, pero ya esta esa parte Me faltan un par de recordings no mas :3
This commit is contained in:
@@ -62,6 +62,37 @@ def load_release_group_cover_art(release_group):
|
|||||||
_log.info('Cover art de release group %s almacenado en cache', mbid)
|
_log.info('Cover art de release group %s almacenado en cache', mbid)
|
||||||
|
|
||||||
|
|
||||||
|
@django_rq.job
|
||||||
|
def load_entities_of_recording(recording):
|
||||||
|
"""Carga en cache una recording y sus releases
|
||||||
|
|
||||||
|
Este difiere del resto e intenta obtener su padre, release, porque cargar recording como tal
|
||||||
|
no da tanto valor como hacer lo contrario, se aprovecha mejor las requests usadas
|
||||||
|
"""
|
||||||
|
mbid = recording
|
||||||
|
if isinstance(recording, dict):
|
||||||
|
mbid = recording.get('id')
|
||||||
|
|
||||||
|
with get_redis_connection() as redis:
|
||||||
|
if f'recording:{mbid}' not in redis:
|
||||||
|
# La única forma de agregar en cache una recording es a través de su release
|
||||||
|
# por lo que si ya esta guardada, su release lo estará
|
||||||
|
return
|
||||||
|
|
||||||
|
offset = 0
|
||||||
|
while True:
|
||||||
|
releases = mb.browse_releases({'recording': mbid},
|
||||||
|
includes=['recordings', 'artists'],
|
||||||
|
limit=100, offset=offset)
|
||||||
|
|
||||||
|
for release in releases:
|
||||||
|
load_entities_of_release.delay(release.get('id'))
|
||||||
|
|
||||||
|
offset += 100
|
||||||
|
if offset > releases.get('release-count'):
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
@django_rq.job
|
@django_rq.job
|
||||||
def load_entities_of_release(release):
|
def load_entities_of_release(release):
|
||||||
"""Carga en cache una release y sus entidades relacionadas"""
|
"""Carga en cache una release y sus entidades relacionadas"""
|
||||||
@@ -94,6 +125,7 @@ def load_entities_of_release(release):
|
|||||||
# o menos me lo voy a saltar, lo único que interesa de la track es su orden dentro de su
|
# o menos me lo voy a saltar, lo único que interesa de la track es su orden dentro de su
|
||||||
# media
|
# media
|
||||||
medias = release.get('media', [])
|
medias = release.get('media', [])
|
||||||
|
redis.set(f'release:{mbid}:media:count', len(medias))
|
||||||
for raw_media in medias:
|
for raw_media in medias:
|
||||||
media = {
|
media = {
|
||||||
'format': raw_media.get('format'),
|
'format': raw_media.get('format'),
|
||||||
@@ -102,11 +134,12 @@ def load_entities_of_release(release):
|
|||||||
}
|
}
|
||||||
redis.zadd(f'release:{mbid}:media', {json.dumps(media): media['position']})
|
redis.zadd(f'release:{mbid}:media', {json.dumps(media): media['position']})
|
||||||
for track in raw_media.get('tracks', []):
|
for track in raw_media.get('tracks', []):
|
||||||
recording_key = f'release:{mbid}:{media.get("position")}:recordings'
|
recording_key = f'release:{mbid}:media:{media.get("position")}:recordings'
|
||||||
recording = track.get('recording')
|
recording = track.get('recording')
|
||||||
redis.zadd(recording_key, {recording.get('id'): track.get("position")})
|
recording_id = recording.get('id')
|
||||||
redis.set(f'recording:{mbid}', json.dumps(recording))
|
redis.zadd(recording_key, {recording_id: track.get("position")})
|
||||||
redis.set(f'recording:{mbid}:release', mbid)
|
redis.set(f'recording:{recording_id}', json.dumps(recording))
|
||||||
|
redis.set(f'recording:{recording_id}:release', mbid)
|
||||||
|
|
||||||
|
|
||||||
@django_rq.job
|
@django_rq.job
|
||||||
|
|||||||
@@ -120,6 +120,18 @@ def map_release(mb_release, cover_art=None):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def map_media(mb_media):
|
||||||
|
"""Transforma una instancia de media dentro de una release a una util para mis propósitos"""
|
||||||
|
media = {
|
||||||
|
'format': mb_media.get('format'),
|
||||||
|
'position': mb_media.get('position'),
|
||||||
|
'track_count': mb_media.get('track_count'),
|
||||||
|
'recordings': [track.get('recording') for track in mb_media.get('tracks')]
|
||||||
|
}
|
||||||
|
|
||||||
|
return media
|
||||||
|
|
||||||
|
|
||||||
def map_recording(mb_recording):
|
def map_recording(mb_recording):
|
||||||
"""Mapea el modelo de recording entregado por musicbrainz a uno propio"""
|
"""Mapea el modelo de recording entregado por musicbrainz a uno propio"""
|
||||||
return {
|
return {
|
||||||
@@ -341,32 +353,58 @@ def get_artist_of_release(mbid, limit, page):
|
|||||||
|
|
||||||
|
|
||||||
def get_recording(mbid):
|
def get_recording(mbid):
|
||||||
"""Obtiene una grabación incluyendo a su artista"""
|
"""Obtiene una grabación"""
|
||||||
mb_recording = mb.get_recording_by_mbid(mbid)
|
|
||||||
|
with get_redis_connection() as redis:
|
||||||
|
mb_recording = redis.get(f'recording:{mbid}')
|
||||||
if mb_recording is None:
|
if mb_recording is None:
|
||||||
mb_recording = mb.get_recording_by_mbid(mbid)
|
mb_recording = mb.get_recording_by_mbid(mbid)
|
||||||
else:
|
else:
|
||||||
mb_recording = json.loads(mb_recording)
|
mb_recording = json.loads(mb_recording)
|
||||||
|
|
||||||
if 'error' in mb_recording:
|
if 'error' in mb_recording:
|
||||||
return mb_recording
|
return mb_recording
|
||||||
|
|
||||||
recording = map_recording(mb_recording)
|
jobs.load_entities_of_recording.delay(mbid)
|
||||||
|
|
||||||
return recording
|
return map_recording(mb_recording)
|
||||||
|
|
||||||
|
|
||||||
def get_recordings_of_release(mbid, limit, page):
|
def get_recordings_of_release(mbid):
|
||||||
"""Obtiene las grabaciones de una release incluyendo los creditos a su artista"""
|
"""Obtiene las grabaciones de una release
|
||||||
mb_recordings = mb.browse_recordings(params={'release': mbid}, includes=['artist-credits'],
|
|
||||||
limit=limit, offset=limit * (page - 1))
|
|
||||||
|
|
||||||
if 'error' in mb_recordings:
|
Realmente no existen grabaciones para este caso de uso, si no, media, el cual representa
|
||||||
return mb_recordings
|
los medios físicos en los que esta una grabación, asi que se entrega una lista de medias con sus
|
||||||
|
grabaciones acopladas, todo ordenado y con indexes de orden
|
||||||
|
"""
|
||||||
|
|
||||||
return {
|
medias = []
|
||||||
'paginate': paginate(mb_recordings.get('recording_count', 0), limit, page),
|
|
||||||
'recordings': [map_recording(recording) for recording in mb_recordings['recordings']]
|
with get_redis_connection() as redis:
|
||||||
}
|
medias_key = f'release:{mbid}:media'
|
||||||
|
count = redis.get(f'{medias_key}:count')
|
||||||
|
if count and redis.zcard(medias_key) == int(count):
|
||||||
|
medias = [json.loads(media) for media in redis.zrange(medias_key, 0, -1)]
|
||||||
|
for media in medias:
|
||||||
|
recordings_key = f'{medias_key}:{media.get("position")}:recordings'
|
||||||
|
recordings_id = redis.zrange(recordings_key, 0, -1)
|
||||||
|
media['recordings'] = []
|
||||||
|
for recording_id in recordings_id:
|
||||||
|
media['recordings'].append(json.loads(redis.get(f'recording:{recording_id}')))
|
||||||
|
|
||||||
|
if len(medias) == 0:
|
||||||
|
# Si es que no habían medias cargadas en cache, puede ser que la release nunca se alla
|
||||||
|
# cargado.
|
||||||
|
jobs.load_entities_of_release.delay(mbid)
|
||||||
|
|
||||||
|
mb_release = mb.get_release_by_mbid(mbid, ['recordings'])
|
||||||
|
|
||||||
|
if 'error' in mb_release:
|
||||||
|
return mb_release
|
||||||
|
|
||||||
|
medias = [map_media(media) for media in mb_release.get('media', [])]
|
||||||
|
|
||||||
|
return {'medias': medias}
|
||||||
|
|
||||||
|
|
||||||
def get_release_of_recording(mbid, limit, page):
|
def get_release_of_recording(mbid, limit, page):
|
||||||
|
|||||||
@@ -152,15 +152,8 @@ def search_recording(request):
|
|||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def get_recordings_of_release(request, mbid):
|
def get_recordings_of_release(request, mbid):
|
||||||
""" Obtiene las recordings de una release dada su mbid
|
""" Obtiene las recordings de una release dada su mbid"""
|
||||||
|
return Response(medium.get_recordings_of_release(mbid))
|
||||||
Como los datos son paginables la query puede contener per_page y page para definir cuantos
|
|
||||||
elementos mostrar por pagina y que pagina mostrar.
|
|
||||||
"""
|
|
||||||
limit = int(request.GET.get('per_page', 100))
|
|
||||||
page = int(request.GET.get('page', 1))
|
|
||||||
|
|
||||||
return Response(medium.get_recordings_of_release(mbid, limit, page))
|
|
||||||
|
|
||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
|
|||||||
Reference in New Issue
Block a user