126 lines
3.7 KiB
Python
126 lines
3.7 KiB
Python
"""Modulo de funciones utilitarias"""
|
|
import json
|
|
import logging
|
|
import functools
|
|
import datetime
|
|
|
|
from django.http import JsonResponse
|
|
from django.conf import settings
|
|
|
|
import redis
|
|
from pygments import highlight
|
|
from pygments.lexers import JsonLexer
|
|
from pygments.formatters import TerminalTrueColorFormatter
|
|
|
|
_log = logging.getLogger('utils')
|
|
_log.addHandler(logging.NullHandler())
|
|
|
|
|
|
def pretty_print_json(json_input):
|
|
"""Formats and prints json to stdout with colors using pygments"""
|
|
formatted_json = json.dumps(json_input, indent=2)
|
|
print(highlight(formatted_json, JsonLexer(), TerminalTrueColorFormatter()))
|
|
|
|
|
|
def message_response(status, error_message):
|
|
"""Sends an error response with the status code of the error and an explanation"""
|
|
json_message = {
|
|
'status_code': status,
|
|
'message': error_message
|
|
}
|
|
|
|
return JsonResponse(json_message, status=status)
|
|
|
|
|
|
def require_json(function):
|
|
"""Decorator to make a view only accept a json body"""
|
|
@functools.wraps(function)
|
|
def decorator(*args, **kwargs):
|
|
try:
|
|
received_json = json.loads(args[0].body)
|
|
return function(*args, **kwargs, received_json=received_json)
|
|
except json.JSONDecodeError:
|
|
_log.warning('Function %s got a non json request body', function.__name__)
|
|
return message_response(400, 'Se envío json no valido')
|
|
|
|
return decorator
|
|
|
|
|
|
def expected_keys(keys, dictionary):
|
|
"""Verifica que un diccionario contiene todas las keys de una lista"""
|
|
for key in keys:
|
|
if key not in dictionary:
|
|
return f'No se encuentra {key}'
|
|
return None
|
|
|
|
|
|
def replace_key(dictionary, old, new):
|
|
"""Remplaza una key en un diccionario
|
|
|
|
En esencia crea una nueva key con los contenidos de la antigua y elimina la antigua
|
|
|
|
Esto lo hace inplace por lo que el diccionario es modificado
|
|
|
|
TODO que cree un nuevo diccionario, es mas bonito el codigo asi
|
|
"""
|
|
dictionary[new] = dictionary[old]
|
|
del dictionary[old]
|
|
|
|
|
|
def sanitize_keys(dictionary):
|
|
"""Remplaza las keys de un diccionario que contienen '-' ya que el diccionario pretende
|
|
ser json y acceder a json con esos caracteres en javascript es incomodo
|
|
|
|
El diccionario es modificado inplace pero de todas formas se retorna
|
|
"""
|
|
for key in list(dictionary.keys()):
|
|
if '-' in key and key in dictionary:
|
|
new_key = key.replace('-', '_')
|
|
replace_key(dictionary, key, new_key)
|
|
return dictionary
|
|
|
|
|
|
def make_key(key, key_prefix=None, version=1):
|
|
"""Key generation function for cache"""
|
|
if key_prefix is None:
|
|
key_prefix = settings.CACHES.get('default').get('KEY_PREFIX')
|
|
|
|
return ':'.join([key_prefix, str(version), key])
|
|
|
|
|
|
def get_redis_connection():
|
|
"""Obtiene una conexion con el cliente de redis"""
|
|
host = settings.DATA_CACHE.get('host')
|
|
port = settings.DATA_CACHE.get('port')
|
|
db = settings.DATA_CACHE.get('db')
|
|
return redis.Redis(host=host, port=port, db=db, decode_responses=True)
|
|
|
|
|
|
def parse_date(date, default=datetime.datetime(1, 1, 1)):
|
|
"""Intenta parsear una fecha la cual le pueden faltar partes
|
|
|
|
Esta pensado para parsear fechas entregadas por musicbrainz, el cual puede entrar fechas con
|
|
año, con año y mes, o, con año, mes y dia
|
|
|
|
Si es que no puede lograrlo retornara el default definido
|
|
"""
|
|
try:
|
|
parsed = datetime.datetime.strptime(date, "%Y")
|
|
return parsed
|
|
except ValueError:
|
|
pass
|
|
|
|
try:
|
|
parsed = datetime.datetime.strptime(date, "%Y-%m")
|
|
return parsed
|
|
except ValueError:
|
|
pass
|
|
|
|
try:
|
|
parsed = datetime.datetime.strptime(date, "%Y-%m-%d")
|
|
return parsed
|
|
except ValueError:
|
|
pass
|
|
|
|
return default
|