Cambios para satisfacer a pylint
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
|
"""Configuración de la aplicación"""
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
class FetcherConfig(AppConfig):
|
class FetcherConfig(AppConfig):
|
||||||
|
"""Solo es necesario definir el nombre de la aplicación"""
|
||||||
name = 'fetcher'
|
name = 'fetcher'
|
||||||
|
|||||||
@@ -1,13 +1,22 @@
|
|||||||
|
"""
|
||||||
|
Mediador entre musicbrainz y las urls
|
||||||
|
Su objetivo es modificar los datos que entrega musicbrainz para que sean
|
||||||
|
correspondientes con lo que debe entregar la api, se encarga de casos como
|
||||||
|
traducción.
|
||||||
|
"""
|
||||||
|
from math import ceil
|
||||||
|
from country_list import countries_for_language
|
||||||
|
from utils import parallel_map
|
||||||
import fetcher.musicbrainz as mb
|
import fetcher.musicbrainz as mb
|
||||||
from utils import pretty_print_json, parallel_map
|
|
||||||
|
|
||||||
|
|
||||||
def full_country_name(country_code):
|
def full_country_name(country_code):
|
||||||
from country_list import countries_for_language
|
"""Obtiene el nombre de un pais en español dado su codigo de pais"""
|
||||||
return dict(countries_for_language('es')).get(country_code, country_code)
|
return dict(countries_for_language('es')).get(country_code, country_code)
|
||||||
|
|
||||||
|
|
||||||
def translate_artist_type(artist_type):
|
def translate_artist_type(artist_type):
|
||||||
|
"""Traduce los tipos de artista a español"""
|
||||||
translation = {
|
translation = {
|
||||||
'Person': 'Persona',
|
'Person': 'Persona',
|
||||||
'Group': 'Grupo',
|
'Group': 'Grupo',
|
||||||
@@ -20,6 +29,7 @@ def translate_artist_type(artist_type):
|
|||||||
|
|
||||||
|
|
||||||
def map_artist(mb_artist):
|
def map_artist(mb_artist):
|
||||||
|
"""Mapea el modelo de artista entregado por musicbrainz a uno propio"""
|
||||||
artist = {
|
artist = {
|
||||||
'id': mb_artist.get('id'),
|
'id': mb_artist.get('id'),
|
||||||
'name': mb_artist.get('name'),
|
'name': mb_artist.get('name'),
|
||||||
@@ -34,6 +44,7 @@ def map_artist(mb_artist):
|
|||||||
|
|
||||||
|
|
||||||
def map_artist_credit(mb_artist_credit):
|
def map_artist_credit(mb_artist_credit):
|
||||||
|
"""Mapea el modelo de credito a artista entregado por musicbrainz a uno propio"""
|
||||||
return {
|
return {
|
||||||
'id': mb_artist_credit.get('artist').get('id'),
|
'id': mb_artist_credit.get('artist').get('id'),
|
||||||
'name': mb_artist_credit.get('artist').get('name'),
|
'name': mb_artist_credit.get('artist').get('name'),
|
||||||
@@ -43,6 +54,7 @@ def map_artist_credit(mb_artist_credit):
|
|||||||
|
|
||||||
|
|
||||||
def map_disc(mb_disc):
|
def map_disc(mb_disc):
|
||||||
|
"""Mapea el modelo de disco entregado por musicbrainz a uno propio"""
|
||||||
disc = {
|
disc = {
|
||||||
'id': mb_disc.get('id'),
|
'id': mb_disc.get('id'),
|
||||||
'title': mb_disc.get('title'),
|
'title': mb_disc.get('title'),
|
||||||
@@ -60,6 +72,7 @@ def map_disc(mb_disc):
|
|||||||
|
|
||||||
|
|
||||||
def map_release(mb_release):
|
def map_release(mb_release):
|
||||||
|
"""Mapea el modelo de release entregado por musicbrainz a uno propio"""
|
||||||
return {
|
return {
|
||||||
'id': mb_release.get('id'),
|
'id': mb_release.get('id'),
|
||||||
'title': mb_release.get('title'),
|
'title': mb_release.get('title'),
|
||||||
@@ -73,6 +86,7 @@ def map_release(mb_release):
|
|||||||
|
|
||||||
|
|
||||||
def map_recording(mb_recording):
|
def map_recording(mb_recording):
|
||||||
|
"""Mapea el modelo de recording entregado por musicbrainz a uno propio"""
|
||||||
return {
|
return {
|
||||||
'id': mb_recording.get('id'),
|
'id': mb_recording.get('id'),
|
||||||
'title': mb_recording.get('title'),
|
'title': mb_recording.get('title'),
|
||||||
@@ -83,6 +97,7 @@ def map_recording(mb_recording):
|
|||||||
|
|
||||||
|
|
||||||
def map_coverart(mb_cover):
|
def map_coverart(mb_cover):
|
||||||
|
"""Mapea el modelo de coverart entregado por musicbrainz a uno propio"""
|
||||||
return {
|
return {
|
||||||
'image': mb_cover.get('image'),
|
'image': mb_cover.get('image'),
|
||||||
'1200': mb_cover.get('thumbnails', {}).get('1200'),
|
'1200': mb_cover.get('thumbnails', {}).get('1200'),
|
||||||
@@ -94,7 +109,9 @@ def map_coverart(mb_cover):
|
|||||||
|
|
||||||
|
|
||||||
def find_best_cover(mb_covers):
|
def find_best_cover(mb_covers):
|
||||||
only_aproved_front = [x for x in mb_covers.get('images') if x.get('approved', False) and x.get('front', False) and not x.get('back', False)]
|
"""Intenta obtener la cover art mas apropiada a partir de una lista de estas"""
|
||||||
|
only_aproved_front = [x for x in mb_covers.get('images') if x.get('approved', False)
|
||||||
|
and x.get('front', False) and not x.get('back', False)]
|
||||||
if len(only_aproved_front) > 0:
|
if len(only_aproved_front) > 0:
|
||||||
return only_aproved_front[0]
|
return only_aproved_front[0]
|
||||||
|
|
||||||
@@ -106,7 +123,8 @@ def find_best_cover(mb_covers):
|
|||||||
|
|
||||||
|
|
||||||
def paginate(count, limit, page):
|
def paginate(count, limit, page):
|
||||||
from math import ceil
|
"""Crea un modelo de paginado a partir de la cantidad de elementos, el limite de elementos y la
|
||||||
|
pagina actual"""
|
||||||
return {
|
return {
|
||||||
'total': count,
|
'total': count,
|
||||||
'current_page': page,
|
'current_page': page,
|
||||||
@@ -116,6 +134,7 @@ def paginate(count, limit, page):
|
|||||||
|
|
||||||
|
|
||||||
def get_artist(mbid):
|
def get_artist(mbid):
|
||||||
|
"""Obtiene un artista desde musicbrainz incluyendo sus tags"""
|
||||||
mb_artist = mb.get_artist_by_mbid(mbid, includes=['tags'])
|
mb_artist = mb.get_artist_by_mbid(mbid, includes=['tags'])
|
||||||
|
|
||||||
if 'error' in mb_artist:
|
if 'error' in mb_artist:
|
||||||
@@ -125,6 +144,7 @@ def get_artist(mbid):
|
|||||||
|
|
||||||
|
|
||||||
def get_disc(mbid):
|
def get_disc(mbid):
|
||||||
|
"""Obtiene un disco desde musicbrainz incluyendo sus artistas"""
|
||||||
mb_disc = mb.get_release_group_by_mbid(mbid, includes=['artists'])
|
mb_disc = mb.get_release_group_by_mbid(mbid, includes=['artists'])
|
||||||
if 'error' in mb_disc:
|
if 'error' in mb_disc:
|
||||||
return mb_disc
|
return mb_disc
|
||||||
@@ -133,7 +153,9 @@ def get_disc(mbid):
|
|||||||
|
|
||||||
|
|
||||||
def get_discs_of_artist(mbid, limit, page):
|
def get_discs_of_artist(mbid, limit, page):
|
||||||
mb_discs = mb.browse_release_groups(params={'artist': mbid}, includes=['artist-credits'], limit=limit, offset=limit * (page - 1))
|
"""Obtiene los discos de un artista desde musicbrainz incluyendo los creditos al artista"""
|
||||||
|
mb_discs = mb.browse_release_groups(params={'artist': mbid}, includes=['artist-credits'],
|
||||||
|
limit=limit, offset=limit * (page - 1))
|
||||||
if 'error' in mb_discs:
|
if 'error' in mb_discs:
|
||||||
return mb_discs
|
return mb_discs
|
||||||
|
|
||||||
@@ -144,6 +166,7 @@ def get_discs_of_artist(mbid, limit, page):
|
|||||||
|
|
||||||
|
|
||||||
def get_artist_of_disc(mbid, limit, page):
|
def get_artist_of_disc(mbid, limit, page):
|
||||||
|
"""Obtiene el artista de un disco"""
|
||||||
mb_artists = mb.browse_artists(params={'disc': mbid}, limit=limit, offset=limit * (page - 1))
|
mb_artists = mb.browse_artists(params={'disc': mbid}, limit=limit, offset=limit * (page - 1))
|
||||||
if 'error' in mb_artists:
|
if 'error' in mb_artists:
|
||||||
return mb_artists
|
return mb_artists
|
||||||
@@ -155,6 +178,7 @@ def get_artist_of_disc(mbid, limit, page):
|
|||||||
|
|
||||||
|
|
||||||
def get_release(mbid):
|
def get_release(mbid):
|
||||||
|
"""Obtiene una release desde musicbrainz incluyendo sus artistas"""
|
||||||
mb_release = mb.get_release_by_mbid(mbid, includes=['artists'])
|
mb_release = mb.get_release_by_mbid(mbid, includes=['artists'])
|
||||||
if 'error' in mb_release:
|
if 'error' in mb_release:
|
||||||
return mb_release
|
return mb_release
|
||||||
@@ -163,7 +187,9 @@ def get_release(mbid):
|
|||||||
|
|
||||||
|
|
||||||
def get_releases_of_disc(mbid, limit, page):
|
def get_releases_of_disc(mbid, limit, page):
|
||||||
mb_releases = mb.browse_releases(params={'release-group': mbid}, includes=['artist-credits'], limit=limit, offset=limit * (page - 1))
|
"""Obtiene las releases de un disco desde musicbrainz incluyendo los creditos a su artistas"""
|
||||||
|
mb_releases = mb.browse_releases(params={'release-group': mbid}, includes=['artist-credits'],
|
||||||
|
limit=limit, offset=limit * (page - 1))
|
||||||
if 'error' in mb_releases:
|
if 'error' in mb_releases:
|
||||||
return mb_releases
|
return mb_releases
|
||||||
|
|
||||||
@@ -174,6 +200,7 @@ def get_releases_of_disc(mbid, limit, page):
|
|||||||
|
|
||||||
|
|
||||||
def get_artist_of_release(mbid, limit, page):
|
def get_artist_of_release(mbid, limit, page):
|
||||||
|
"""Obtiene el artista de una release"""
|
||||||
mb_artists = mb.browse_artists(params={'release': mbid}, limit=limit, offset=limit * (page - 1))
|
mb_artists = mb.browse_artists(params={'release': mbid}, limit=limit, offset=limit * (page - 1))
|
||||||
if 'error' in mb_artists:
|
if 'error' in mb_artists:
|
||||||
return mb_artists
|
return mb_artists
|
||||||
@@ -185,6 +212,7 @@ def get_artist_of_release(mbid, limit, page):
|
|||||||
|
|
||||||
|
|
||||||
def get_recording(mbid):
|
def get_recording(mbid):
|
||||||
|
"""Obtiene una grabacion incluyendo a su artista"""
|
||||||
mb_recording = mb.get_recording_by_mbid(mbid, includes=['artists'])
|
mb_recording = mb.get_recording_by_mbid(mbid, includes=['artists'])
|
||||||
if 'error' in mb_recording:
|
if 'error' in mb_recording:
|
||||||
return mb_recording
|
return mb_recording
|
||||||
@@ -193,18 +221,22 @@ def get_recording(mbid):
|
|||||||
|
|
||||||
|
|
||||||
def get_recordings_of_release(mbid, limit, page):
|
def get_recordings_of_release(mbid, limit, page):
|
||||||
mb_recordings = mb.browse_recordings(params={'release': mbid}, includes=['artist-credits'], limit=limit, offset=limit * (page - 1))
|
"""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))
|
||||||
if 'error' in mb_recordings:
|
if 'error' in mb_recordings:
|
||||||
return mb_recordings
|
return mb_recordings
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'paginate': paginate(mb_recordings.get('recording_count', 0), limit, page),
|
'paginate': paginate(mb_recordings.get('recording_count', 0), limit, page),
|
||||||
'recordings': parallel_map(mb_recordings['recordings'], map_recording())
|
'recordings': parallel_map(mb_recordings['recordings'], map_recording)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_release_of_recording(mbid, limit, page):
|
def get_release_of_recording(mbid, limit, page):
|
||||||
mb_releases = mb.browse_releases(params={'recording': mbid}, includes=['artists-credits'], limit=limit, offset=limit * (page - 1))
|
"""Obtiene la release de una grabacion incluyendo los creditos a su artista"""
|
||||||
|
mb_releases = mb.browse_releases(params={'recording': mbid}, includes=['artists-credits'],
|
||||||
|
limit=limit, offset=limit * (page - 1))
|
||||||
if 'error' in mb_releases:
|
if 'error' in mb_releases:
|
||||||
return mb_releases
|
return mb_releases
|
||||||
|
|
||||||
@@ -215,7 +247,9 @@ def get_release_of_recording(mbid, limit, page):
|
|||||||
|
|
||||||
|
|
||||||
def get_artist_of_recording(mbid, limit, page):
|
def get_artist_of_recording(mbid, limit, page):
|
||||||
mb_artists = mb.browse_artists(params={'recording': mbid}, limit=limit, offset=limit * (page - 1))
|
"""Obtiene el artista de una grabacion"""
|
||||||
|
mb_artists = mb.browse_artists(params={'recording': mbid}, limit=limit,
|
||||||
|
offset=limit * (page - 1))
|
||||||
if 'error' in mb_artists:
|
if 'error' in mb_artists:
|
||||||
return mb_artists
|
return mb_artists
|
||||||
|
|
||||||
@@ -226,6 +260,7 @@ def get_artist_of_recording(mbid, limit, page):
|
|||||||
|
|
||||||
|
|
||||||
def get_cover_art_disc(mbid):
|
def get_cover_art_disc(mbid):
|
||||||
|
"""Obtiene el cover art de un disco"""
|
||||||
mb_covers = mb.get_release_group_cover_art(mbid)
|
mb_covers = mb.get_release_group_cover_art(mbid)
|
||||||
if 'error' in mb_covers:
|
if 'error' in mb_covers:
|
||||||
return None
|
return None
|
||||||
@@ -237,6 +272,7 @@ def get_cover_art_disc(mbid):
|
|||||||
|
|
||||||
|
|
||||||
def get_cover_art_release(mbid):
|
def get_cover_art_release(mbid):
|
||||||
|
"""Obtiene el cover art de una release"""
|
||||||
mb_covers = mb.get_release_cover_art(mbid)
|
mb_covers = mb.get_release_cover_art(mbid)
|
||||||
if 'error' in mb_covers:
|
if 'error' in mb_covers:
|
||||||
return None
|
return None
|
||||||
@@ -248,6 +284,7 @@ def get_cover_art_release(mbid):
|
|||||||
|
|
||||||
|
|
||||||
def get_cover_art_recording(mbid):
|
def get_cover_art_recording(mbid):
|
||||||
|
"""Obtiene el cover art de una grabacion"""
|
||||||
release = get_release_of_recording(mbid, limit=1, page=1)
|
release = get_release_of_recording(mbid, limit=1, page=1)
|
||||||
if 'error' in release:
|
if 'error' in release:
|
||||||
return None
|
return None
|
||||||
@@ -256,6 +293,7 @@ def get_cover_art_recording(mbid):
|
|||||||
|
|
||||||
|
|
||||||
def search_artist(query, limit, page):
|
def search_artist(query, limit, page):
|
||||||
|
"""Busca un artista dada una query"""
|
||||||
mb_artists = mb.search_artist(query=query, limit=limit, offset=limit * (page - 1))
|
mb_artists = mb.search_artist(query=query, limit=limit, offset=limit * (page - 1))
|
||||||
if 'error' in mb_artists:
|
if 'error' in mb_artists:
|
||||||
return mb_artists
|
return mb_artists
|
||||||
@@ -267,7 +305,9 @@ def search_artist(query, limit, page):
|
|||||||
|
|
||||||
|
|
||||||
def search_disc(query, limit, page):
|
def search_disc(query, limit, page):
|
||||||
mb_discs = mb.search_release_group(query=query, includes=['artist'], limit=limit, offset=limit * (page - 1))
|
"""Busca un disco dada una query"""
|
||||||
|
mb_discs = mb.search_release_group(query=query, includes=['artist'], limit=limit,
|
||||||
|
offset=limit * (page - 1))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'paginate': paginate(mb_discs['count'], limit, page),
|
'paginate': paginate(mb_discs['count'], limit, page),
|
||||||
@@ -276,7 +316,9 @@ def search_disc(query, limit, page):
|
|||||||
|
|
||||||
|
|
||||||
def search_release(query, limit, page):
|
def search_release(query, limit, page):
|
||||||
mb_releases = mb.search_release(query=query, includes=['artist'], limit=limit, offset=limit * (page - 1))
|
"""Busca una release dada una query"""
|
||||||
|
mb_releases = mb.search_release(query=query, includes=['artist'], limit=limit,
|
||||||
|
offset=limit * (page - 1))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'paginate': paginate(mb_releases['count'], limit, page),
|
'paginate': paginate(mb_releases['count'], limit, page),
|
||||||
@@ -285,11 +327,11 @@ def search_release(query, limit, page):
|
|||||||
|
|
||||||
|
|
||||||
def search_recording(query, limit, page):
|
def search_recording(query, limit, page):
|
||||||
mb_recording = mb.search_recording(query=query, includes=['artist'], limit=limit, offset=limit * (page - 1))
|
"""Busca una grabacion dada una query"""
|
||||||
|
mb_recording = mb.search_recording(query=query, includes=['artist'], limit=limit,
|
||||||
|
offset=limit * (page - 1))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'paginate': paginate(mb_recording['count'], limit, page),
|
'paginate': paginate(mb_recording['count'], limit, page),
|
||||||
'recordings': parallel_map(mb_recording['recordings'], map_recording)
|
'recordings': parallel_map(mb_recording['recordings'], map_recording)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
"""
|
"""
|
||||||
Modulo que se encarga de realizar requests a musicbrainz, mayormente devuelve el resultado que musicbrainz entrega
|
Modulo que se encarga de realizar requests a musicbrainz, mayormente devuelve el resultado que
|
||||||
exceptuando los errores.
|
musicbrainz entrega exceptuando los errores.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from urllib.parse import quote, urlencode
|
||||||
import logging
|
import logging
|
||||||
import requests
|
import requests
|
||||||
from ratelimit import limits, sleep_and_retry
|
from ratelimit import limits, sleep_and_retry
|
||||||
from urllib.parse import quote, urlencode
|
|
||||||
|
|
||||||
from utils import replace_key, sanitize_keys, pretty_print_json
|
from utils import sanitize_keys
|
||||||
from utils.cache import Cache as cache
|
from utils.cache import Cache as cache
|
||||||
|
|
||||||
_headers = {'accept': 'application/json', 'user-agent': 'MusicList/1.0 (danielcortes.xyz)'}
|
HEADERS = {'accept': 'application/json', 'user-agent': 'MusicList/1.0 (danielcortes.xyz)'}
|
||||||
_mb_host = 'https://musicbrainz.org/ws/2'
|
MB_HOST = 'https://musicbrainz.org/ws/2'
|
||||||
_ca_host = 'http://coverartarchive.org'
|
CA_HOST = 'http://coverartarchive.org'
|
||||||
|
|
||||||
_log = logging.getLogger(__name__)
|
_log = logging.getLogger(__name__)
|
||||||
_log.addHandler(logging.NullHandler())
|
_log.addHandler(logging.NullHandler())
|
||||||
@@ -29,10 +29,10 @@ def _do_request(url):
|
|||||||
if not url:
|
if not url:
|
||||||
raise ValueError('URL cant be empty')
|
raise ValueError('URL cant be empty')
|
||||||
|
|
||||||
_log.info(f'Doing request to "{url}" with headers {_headers}')
|
_log.info('Doing request to "%s" with headers %s', url, HEADERS)
|
||||||
response = requests.get(url, headers=_headers)
|
response = requests.get(url, headers=HEADERS)
|
||||||
|
|
||||||
_log.info(f'Request returned with status code {response.status_code}')
|
_log.info('Request returned with status code %s', response.status_code)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@@ -52,17 +52,17 @@ def _do_request_mb(url):
|
|||||||
:return: The dictionary with the response or the status and his an error message
|
:return: The dictionary with the response or the status and his an error message
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not _headers['user-agent']:
|
if not HEADERS['user-agent']:
|
||||||
raise ValueError('User Agent isn\'t set')
|
raise ValueError('User Agent isn\'t set')
|
||||||
|
|
||||||
r = _do_request(url)
|
response = _do_request(url)
|
||||||
|
|
||||||
if r.status_code == 200:
|
if response.status_code == 200:
|
||||||
response = r.json(object_hook=sanitize_keys)
|
response = response.json(object_hook=sanitize_keys)
|
||||||
elif r.status_code == 500:
|
elif response.status_code == 500:
|
||||||
response = {'status': r.status_code, 'error': f'Error del servidor'}
|
response = {'status': response.status_code, 'error': 'Error del servidor'}
|
||||||
else:
|
else:
|
||||||
response = {'status': r.status_code, 'error': r.json()['error']}
|
response = {'status': response.status_code, 'error': response.json()['error']}
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@@ -79,25 +79,25 @@ def _do_request_ca(url):
|
|||||||
:raises ValueError when user-agent isn't set
|
:raises ValueError when user-agent isn't set
|
||||||
:return: The dictionary with the response or the status and his an error message
|
:return: The dictionary with the response or the status and his an error message
|
||||||
"""
|
"""
|
||||||
if not _headers['user-agent']:
|
if not HEADERS['user-agent']:
|
||||||
raise ValueError('User Agent isn\'t set')
|
raise ValueError('User Agent isn\'t set')
|
||||||
|
|
||||||
r = _do_request(url)
|
response = _do_request(url)
|
||||||
|
|
||||||
if r.status_code == 200:
|
if response.status_code == 200:
|
||||||
response = r.json(object_hook=sanitize_keys)
|
response = response.json(object_hook=sanitize_keys)
|
||||||
elif r.status_code == 500:
|
elif response.status_code == 500:
|
||||||
response = {'status': r.status_code, 'error': f'Error del servidor'}
|
response = {'status': response.status_code, 'error': 'Error del servidor'}
|
||||||
elif r.status_code == 400:
|
elif response.status_code == 400:
|
||||||
response = {'status': r.status_code, 'error': f'El mbid es invalido'}
|
response = {'status': response.status_code, 'error': 'El mbid es invalido'}
|
||||||
elif r.status_code == 404:
|
elif response.status_code == 404:
|
||||||
response = {'status': r.status_code, 'error': f'No encontrado'}
|
response = {'status': response.status_code, 'error': 'No encontrado'}
|
||||||
elif r.status_code == 405:
|
elif response.status_code == 405:
|
||||||
response = {'status': r.status_code, 'error': f'Metodo erroneo'}
|
response = {'status': response.status_code, 'error': 'Metodo erroneo'}
|
||||||
elif r.status_code == 503:
|
elif response.status_code == 503:
|
||||||
response = {'status': r.status_code, 'error': f'Rate limit exedido'}
|
response = {'status': response.status_code, 'error': 'Rate limit exedido'}
|
||||||
else:
|
else:
|
||||||
response = {'status': r.status_code, 'error': r.json()['error']}
|
response = {'status': response.status_code, 'error': response.json()['error']}
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@@ -114,14 +114,14 @@ def _get(entity_type, mbid, includes=None):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if includes is None:
|
if includes is None:
|
||||||
_log.info(f'Getting {entity_type} of mbid {mbid}')
|
_log.info('Getting %s of mbid %s', entity_type, mbid)
|
||||||
|
|
||||||
return _do_request_mb(f'{_mb_host}/{entity_type}/{mbid}')
|
return _do_request_mb(f'{MB_HOST}/{entity_type}/{mbid}')
|
||||||
else:
|
|
||||||
_log.info(f'Getting {entity_type} of mbid {mbid} including {includes}')
|
|
||||||
_includes = quote('+'.join(includes))
|
|
||||||
|
|
||||||
return _do_request_mb(f'{_mb_host}/{entity_type}/{mbid}?inc={_includes}')
|
_log.info('Getting %s of mbid %s including %s', entity_type, mbid, includes)
|
||||||
|
_includes = quote('+'.join(includes))
|
||||||
|
|
||||||
|
return _do_request_mb(f'{MB_HOST}/{entity_type}/{mbid}?inc={_includes}')
|
||||||
|
|
||||||
|
|
||||||
def _search(entity_type, query, includes=None, limit=25, offset=0):
|
def _search(entity_type, query, includes=None, limit=25, offset=0):
|
||||||
@@ -136,7 +136,8 @@ def _search(entity_type, query, includes=None, limit=25, offset=0):
|
|||||||
:rtype: dict
|
:rtype: dict
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_log.info(f'Searching {entity_type} with query "{query}" at offset {offset} with limit of {limit} with includes {includes}')
|
_log.info('Searching %s with query "%s" at offset %s with limit of %s with includes %s',
|
||||||
|
entity_type, query, offset, limit, includes)
|
||||||
|
|
||||||
if limit >= 0 and offset >= 0:
|
if limit >= 0 and offset >= 0:
|
||||||
_query = {'query': query, 'limit': limit, 'offset': offset}
|
_query = {'query': query, 'limit': limit, 'offset': offset}
|
||||||
@@ -146,7 +147,7 @@ def _search(entity_type, query, includes=None, limit=25, offset=0):
|
|||||||
if includes is not None:
|
if includes is not None:
|
||||||
_query['inc'] = '+'.join(includes)
|
_query['inc'] = '+'.join(includes)
|
||||||
|
|
||||||
return _do_request_mb(f'{_mb_host}/{entity_type}/?{urlencode(_query)}')
|
return _do_request_mb(f'{MB_HOST}/{entity_type}/?{urlencode(_query)}')
|
||||||
|
|
||||||
|
|
||||||
def _browse(entity_type, params, includes=None, limit=25, offset=0):
|
def _browse(entity_type, params, includes=None, limit=25, offset=0):
|
||||||
@@ -168,13 +169,15 @@ def _browse(entity_type, params, includes=None, limit=25, offset=0):
|
|||||||
raise ValueError('Params must be a dictionary')
|
raise ValueError('Params must be a dictionary')
|
||||||
|
|
||||||
if includes is None:
|
if includes is None:
|
||||||
_log.info(f'Browsing {entity_type} with parameters {params} at offset {offset} with limit of {limit}')
|
_log.info('Browsing %s with parameters %s at offset %s with limit of %s',
|
||||||
|
entity_type, params, offset, limit)
|
||||||
_query = urlencode({**params, 'limit': limit, 'offset': offset})
|
_query = urlencode({**params, 'limit': limit, 'offset': offset})
|
||||||
else:
|
else:
|
||||||
_log.info(f'Browsing {entity_type} with parameters {params} including {includes} at offset {offset} with limit of {limit}')
|
_log.info('Browsing %s with parameters %s including %s at offset %s with limit of %s',
|
||||||
|
entity_type, params, includes, offset, limit)
|
||||||
_query = urlencode({**params, 'inc': '+'.join(includes), 'limit': limit, 'offset': offset})
|
_query = urlencode({**params, 'inc': '+'.join(includes), 'limit': limit, 'offset': offset})
|
||||||
|
|
||||||
return _do_request_mb(f'{_mb_host}/{entity_type}?{_query}')
|
return _do_request_mb(f'{MB_HOST}/{entity_type}?{_query}')
|
||||||
|
|
||||||
|
|
||||||
def _ca(entity_type, mbid):
|
def _ca(entity_type, mbid):
|
||||||
@@ -186,9 +189,9 @@ def _ca(entity_type, mbid):
|
|||||||
:return: The url of the cover art
|
:return: The url of the cover art
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_log.info(f'Obtaining the cover art of the entity with type {entity_type} and mbid {mbid}')
|
_log.info('Obtaining the cover art of the entity with type %s and mbid %s', entity_type, mbid)
|
||||||
|
|
||||||
_url = f'{_ca_host}/{entity_type}/{mbid}'
|
_url = f'{CA_HOST}/{entity_type}/{mbid}'
|
||||||
|
|
||||||
return _do_request_ca(_url)
|
return _do_request_ca(_url)
|
||||||
|
|
||||||
@@ -287,7 +290,7 @@ def search_recording(query, includes=None, limit=25, offset=0):
|
|||||||
:param int offset: Offset of the search for paging purposes
|
:param int offset: Offset of the search for paging purposes
|
||||||
:return: dictionary with the response
|
:return: dictionary with the response
|
||||||
"""
|
"""
|
||||||
return _search('recording', query, includes,limit, offset)
|
return _search('recording', query, includes, limit, offset)
|
||||||
|
|
||||||
|
|
||||||
@cache
|
@cache
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
import redis
|
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
from fetcher import musicbrainz
|
|
||||||
|
|
||||||
|
|
||||||
class MusicBrainzTestCase(TestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
redis.Redis().flushall()
|
|
||||||
|
|
||||||
def test_can_do_basic_request(self):
|
|
||||||
artist_url = 'https://musicbrainz.org/ws/2/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab'
|
|
||||||
musicbrainz._do_request_mb(artist_url)
|
|
||||||
|
|
||||||
def test_do_request_response_format(self):
|
|
||||||
artist_url = 'https://musicbrainz.org/ws/2/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab'
|
|
||||||
response = musicbrainz._do_request_mb(artist_url)
|
|
||||||
self.assertIsInstance(response, dict)
|
|
||||||
self.assertEquals(response['status'], 200)
|
|
||||||
self.assertIsInstance(response['response'], dict)
|
|
||||||
|
|
||||||
def test_do_request_input_validation(self):
|
|
||||||
artist_url = 'https://musicbrainz.org/ws/2/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab'
|
|
||||||
self.assertRaises(ValueError, musicbrainz._do_request_mb, None)
|
|
||||||
self.assertRaises(ValueError, musicbrainz._do_request_mb, '')
|
|
||||||
musicbrainz._headers['user-agent'] = None
|
|
||||||
self.assertRaises(ValueError, musicbrainz._do_request_mb, artist_url)
|
|
||||||
|
|
||||||
def test_cache(self):
|
|
||||||
def fun():
|
|
||||||
return {}
|
|
||||||
|
|
||||||
musicbrainz.cache(fun)()
|
|
||||||
self.assertTrue(redis.Redis().keys('*') is not None)
|
|
||||||
self.assertEquals(musicbrainz.cache(fun)(), {})
|
|
||||||
|
|
||||||
redis.Redis().set('fun, [[], {}]', '{"test": true}')
|
|
||||||
self.assertEquals(musicbrainz.cache(fun)(), {"test": True})
|
|
||||||
|
|
||||||
def fun(a, b):
|
|
||||||
return {}
|
|
||||||
|
|
||||||
musicbrainz.cache(fun)('word', [''])
|
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
"""
|
||||||
|
Definición de urls de fetcher
|
||||||
|
"""
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
|
|||||||
101
fetcher/views.py
101
fetcher/views.py
@@ -1,12 +1,21 @@
|
|||||||
import logging
|
"""
|
||||||
|
Modulo que define las vistas de la aplicacion
|
||||||
|
"""
|
||||||
from rest_framework.decorators import api_view
|
from rest_framework.decorators import api_view
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from . import musicbrainz as mb, medium
|
from . import medium
|
||||||
|
|
||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def search_artist(request):
|
def search_artist(request):
|
||||||
|
"""Busca un artista
|
||||||
|
|
||||||
|
Se espera que la request contenga al menos la query y opcionalmente puede incluir
|
||||||
|
per_page y page para paginar los datos
|
||||||
|
|
||||||
|
En caso que no alla query se retornara un error
|
||||||
|
"""
|
||||||
limit = int(request.GET.get('per_page', 10))
|
limit = int(request.GET.get('per_page', 10))
|
||||||
page = int(request.GET.get('page', 1))
|
page = int(request.GET.get('page', 1))
|
||||||
|
|
||||||
@@ -18,17 +27,27 @@ def search_artist(request):
|
|||||||
|
|
||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def get_artist(request, mbid):
|
def get_artist(_, mbid):
|
||||||
|
""" Obtiene un artista dado su mbid"""
|
||||||
return Response(medium.get_artist(mbid))
|
return Response(medium.get_artist(mbid))
|
||||||
|
|
||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def get_disc(request, mbid):
|
def get_disc(_, mbid):
|
||||||
|
"""Obtiene un disco dado su mbid"""
|
||||||
return Response(medium.get_disc(mbid))
|
return Response(medium.get_disc(mbid))
|
||||||
|
|
||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def search_disc(request):
|
def search_disc(request):
|
||||||
|
"""Busca un disco
|
||||||
|
|
||||||
|
Se espera que la request contenga al menos la query y opcionalmente puede incluir
|
||||||
|
per_page y page para paginar los datos
|
||||||
|
|
||||||
|
En caso que no alla query se retornara un error
|
||||||
|
"""
|
||||||
|
|
||||||
limit = int(request.GET.get('per_page', 10))
|
limit = int(request.GET.get('per_page', 10))
|
||||||
page = int(request.GET.get('page', 1))
|
page = int(request.GET.get('page', 1))
|
||||||
|
|
||||||
@@ -41,6 +60,11 @@ def search_disc(request):
|
|||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def get_discs_of_artist(request, mbid):
|
def get_discs_of_artist(request, mbid):
|
||||||
|
""" Obtiene los discos de un artista dado el mbid del artista
|
||||||
|
|
||||||
|
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', 10))
|
limit = int(request.GET.get('per_page', 10))
|
||||||
page = int(request.GET.get('page', 1))
|
page = int(request.GET.get('page', 1))
|
||||||
|
|
||||||
@@ -49,6 +73,11 @@ def get_discs_of_artist(request, mbid):
|
|||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def get_artist_of_disc(request, mbid):
|
def get_artist_of_disc(request, mbid):
|
||||||
|
""" Obtiene el artista de un disco
|
||||||
|
|
||||||
|
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', 10))
|
limit = int(request.GET.get('per_page', 10))
|
||||||
page = int(request.GET.get('page', 1))
|
page = int(request.GET.get('page', 1))
|
||||||
|
|
||||||
@@ -56,12 +85,20 @@ def get_artist_of_disc(request, mbid):
|
|||||||
|
|
||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def get_release(request, mbid):
|
def get_release(_, mbid):
|
||||||
|
""" Obtiene una release dada su mbid"""
|
||||||
return Response(medium.get_release(mbid))
|
return Response(medium.get_release(mbid))
|
||||||
|
|
||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def search_release(request):
|
def search_release(request):
|
||||||
|
""" Busca una release
|
||||||
|
|
||||||
|
Se espera que la request contenga al menos la query y opcionalmente puede incluir
|
||||||
|
per_page y page para paginar los datos
|
||||||
|
|
||||||
|
En caso que no alla query se retornara un error
|
||||||
|
"""
|
||||||
limit = int(request.GET.get('per_page', 10))
|
limit = int(request.GET.get('per_page', 10))
|
||||||
page = int(request.GET.get('page', 1))
|
page = int(request.GET.get('page', 1))
|
||||||
|
|
||||||
@@ -74,6 +111,11 @@ def search_release(request):
|
|||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def get_releases_of_disc(request, mbid):
|
def get_releases_of_disc(request, mbid):
|
||||||
|
""" Obtiene las releases de un disco
|
||||||
|
|
||||||
|
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', 10))
|
limit = int(request.GET.get('per_page', 10))
|
||||||
page = int(request.GET.get('page', 1))
|
page = int(request.GET.get('page', 1))
|
||||||
|
|
||||||
@@ -82,6 +124,11 @@ def get_releases_of_disc(request, mbid):
|
|||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def get_artist_of_release(request, mbid):
|
def get_artist_of_release(request, mbid):
|
||||||
|
""" Obtiene el artista 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', 10))
|
limit = int(request.GET.get('per_page', 10))
|
||||||
page = int(request.GET.get('page', 1))
|
page = int(request.GET.get('page', 1))
|
||||||
|
|
||||||
@@ -89,12 +136,20 @@ def get_artist_of_release(request, mbid):
|
|||||||
|
|
||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def get_recording(request, mbid):
|
def get_recording(_, mbid):
|
||||||
|
"""Obtiene un recording dada su mbid"""
|
||||||
return Response(medium.get_recording(mbid))
|
return Response(medium.get_recording(mbid))
|
||||||
|
|
||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def search_recording(request):
|
def search_recording(request):
|
||||||
|
""" Busca una recording
|
||||||
|
|
||||||
|
Se espera que la request contenga al menos la query y opcionalmente puede incluir
|
||||||
|
per_page y page para paginar los datos
|
||||||
|
|
||||||
|
En caso que no alla query se retornara un error
|
||||||
|
"""
|
||||||
limit = int(request.GET.get('per_page', 10))
|
limit = int(request.GET.get('per_page', 10))
|
||||||
page = int(request.GET.get('page', 1))
|
page = int(request.GET.get('page', 1))
|
||||||
|
|
||||||
@@ -107,6 +162,11 @@ 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
|
||||||
|
|
||||||
|
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))
|
limit = int(request.GET.get('per_page', 100))
|
||||||
page = int(request.GET.get('page', 1))
|
page = int(request.GET.get('page', 1))
|
||||||
|
|
||||||
@@ -115,6 +175,11 @@ def get_recordings_of_release(request, mbid):
|
|||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def get_release_of_recording(request, mbid):
|
def get_release_of_recording(request, mbid):
|
||||||
|
""" Obtiene la release de una recording 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))
|
limit = int(request.GET.get('per_page', 100))
|
||||||
page = int(request.GET.get('page', 1))
|
page = int(request.GET.get('page', 1))
|
||||||
|
|
||||||
@@ -123,6 +188,11 @@ def get_release_of_recording(request, mbid):
|
|||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def get_artist_of_recording(request, mbid):
|
def get_artist_of_recording(request, mbid):
|
||||||
|
""" Obtiene el artista de una grabación 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', 10))
|
limit = int(request.GET.get('per_page', 10))
|
||||||
page = int(request.GET.get('page', 1))
|
page = int(request.GET.get('page', 1))
|
||||||
|
|
||||||
@@ -130,27 +200,28 @@ def get_artist_of_recording(request, mbid):
|
|||||||
|
|
||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def get_cover_art_of_disc(request, mbid):
|
def get_cover_art_of_disc(_, mbid):
|
||||||
|
"""Obtiene la coverart de un disc dado su mbid"""
|
||||||
coverart = medium.get_cover_art_disc(mbid)
|
coverart = medium.get_cover_art_disc(mbid)
|
||||||
if coverart:
|
if coverart:
|
||||||
return Response(coverart)
|
return Response(coverart)
|
||||||
else:
|
|
||||||
return Response(status=404)
|
return Response(status=404)
|
||||||
|
|
||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def get_cover_art_of_release(request, mbid):
|
def get_cover_art_of_release(_, mbid):
|
||||||
|
"""Obtiene la coverart de una release dado su mbid"""
|
||||||
coverart = medium.get_cover_art_release(mbid)
|
coverart = medium.get_cover_art_release(mbid)
|
||||||
if coverart:
|
if coverart:
|
||||||
return Response(coverart)
|
return Response(coverart)
|
||||||
else:
|
return Response(status=404)
|
||||||
return Response(status=404)
|
|
||||||
|
|
||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def get_cover_art_of_recording(request, mbid):
|
def get_cover_art_of_recording(_, mbid):
|
||||||
|
"""Obtiene la coverart de la release de una recording dado su mbid"""
|
||||||
coverart = medium.get_cover_art_recording(mbid)
|
coverart = medium.get_cover_art_recording(mbid)
|
||||||
if coverart:
|
if coverart:
|
||||||
return Response(coverart)
|
return Response(coverart)
|
||||||
else:
|
return Response(status=404)
|
||||||
return Response(status=404)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user