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)
|
||||
|
||||
|
||||
@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
|
||||
def load_entities_of_release(release):
|
||||
"""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
|
||||
# media
|
||||
medias = release.get('media', [])
|
||||
redis.set(f'release:{mbid}:media:count', len(medias))
|
||||
for raw_media in medias:
|
||||
media = {
|
||||
'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']})
|
||||
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')
|
||||
redis.zadd(recording_key, {recording.get('id'): track.get("position")})
|
||||
redis.set(f'recording:{mbid}', json.dumps(recording))
|
||||
redis.set(f'recording:{mbid}:release', mbid)
|
||||
recording_id = recording.get('id')
|
||||
redis.zadd(recording_key, {recording_id: track.get("position")})
|
||||
redis.set(f'recording:{recording_id}', json.dumps(recording))
|
||||
redis.set(f'recording:{recording_id}:release', mbid)
|
||||
|
||||
|
||||
@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):
|
||||
"""Mapea el modelo de recording entregado por musicbrainz a uno propio"""
|
||||
return {
|
||||
@@ -341,32 +353,58 @@ def get_artist_of_release(mbid, limit, page):
|
||||
|
||||
|
||||
def get_recording(mbid):
|
||||
"""Obtiene una grabación incluyendo a su artista"""
|
||||
mb_recording = mb.get_recording_by_mbid(mbid)
|
||||
if mb_recording is None:
|
||||
mb_recording = mb.get_recording_by_mbid(mbid)
|
||||
else:
|
||||
mb_recording = json.loads(mb_recording)
|
||||
if 'error' in mb_recording:
|
||||
return mb_recording
|
||||
"""Obtiene una grabación"""
|
||||
|
||||
recording = map_recording(mb_recording)
|
||||
with get_redis_connection() as redis:
|
||||
mb_recording = redis.get(f'recording:{mbid}')
|
||||
if mb_recording is None:
|
||||
mb_recording = mb.get_recording_by_mbid(mbid)
|
||||
else:
|
||||
mb_recording = json.loads(mb_recording)
|
||||
|
||||
return recording
|
||||
if 'error' in mb_recording:
|
||||
return mb_recording
|
||||
|
||||
jobs.load_entities_of_recording.delay(mbid)
|
||||
|
||||
return map_recording(mb_recording)
|
||||
|
||||
|
||||
def get_recordings_of_release(mbid, limit, page):
|
||||
"""Obtiene las grabaciones de una release incluyendo los creditos a su artista"""
|
||||
mb_recordings = mb.browse_recordings(params={'release': mbid}, includes=['artist-credits'],
|
||||
limit=limit, offset=limit * (page - 1))
|
||||
def get_recordings_of_release(mbid):
|
||||
"""Obtiene las grabaciones de una release
|
||||
|
||||
if 'error' in mb_recordings:
|
||||
return mb_recordings
|
||||
Realmente no existen grabaciones para este caso de uso, si no, media, el cual representa
|
||||
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 {
|
||||
'paginate': paginate(mb_recordings.get('recording_count', 0), limit, page),
|
||||
'recordings': [map_recording(recording) for recording in mb_recordings['recordings']]
|
||||
}
|
||||
medias = []
|
||||
|
||||
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):
|
||||
|
||||
@@ -152,15 +152,8 @@ def search_recording(request):
|
||||
|
||||
@api_view(['GET'])
|
||||
def get_recordings_of_release(request, mbid):
|
||||
""" Obtiene las recordings de una release dada su 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))
|
||||
""" Obtiene las recordings de una release dada su mbid"""
|
||||
return Response(medium.get_recordings_of_release(mbid))
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
|
||||
Reference in New Issue
Block a user