342 lines
11 KiB
Python
342 lines
11 KiB
Python
import json
|
|
from json.decoder import JSONDecodeError
|
|
|
|
from django.http import JsonResponse
|
|
from oauth2_provider.decorators import protected_resource
|
|
|
|
from lists.forms import ListItemForm, TagForm, EntityForm
|
|
from lists.models import ListItem, Tag, Entity, OpinionHelpful
|
|
from users.models import User
|
|
|
|
|
|
def list_view(request, user_id):
|
|
"""
|
|
Punto de entrada de las vistas de lista de un usuario
|
|
"""
|
|
|
|
# Tiene que existir un usuario con el id entregado.
|
|
user = User.objects.filter(pk=user_id)
|
|
if user.count() != 1:
|
|
return JsonResponse({'status': 404, 'error': f'No existe un usuario con id {user_id}'}, status=404)
|
|
user = user[0]
|
|
|
|
if request.method == 'GET':
|
|
return _get_list(request, user)
|
|
elif request.method == 'POST':
|
|
return _add_to_list(request, user)
|
|
else:
|
|
return JsonResponse({'status': 404, 'error': 'La ruta no existe'}, status=404)
|
|
|
|
|
|
def _get_list(request, user):
|
|
"""Retorna la lista de un usuario"""
|
|
|
|
encoded_list = []
|
|
for list_item in user.list.all():
|
|
encoded_list.append({
|
|
'entity': {
|
|
'mbid': list_item.entity.mbid,
|
|
'type': list_item.entity.entity_type,
|
|
},
|
|
'tags': [{
|
|
'id': tag.id,
|
|
'name': tag.name
|
|
} for tag in list_item.tags.all()]
|
|
})
|
|
|
|
return JsonResponse({
|
|
'user_id': user.id,
|
|
'list': encoded_list
|
|
})
|
|
|
|
|
|
@protected_resource()
|
|
def _add_to_list(request, user):
|
|
"""Agrega un nuevo item a la lista del usuario"""
|
|
|
|
# Solo el dueño o un administrador puede modificar la lista
|
|
if request.user.id != user.id and not request.user.is_admin:
|
|
return JsonResponse({'status': 403,
|
|
'error': 'El usuario no tiene permiso para hacer esta acción'},
|
|
status=403)
|
|
|
|
try:
|
|
request_data = json.loads(request.body.decode('utf8'))
|
|
except JSONDecodeError:
|
|
return JsonResponse({'status': 400,
|
|
'error': 'El body de la request no es json valido'},
|
|
status=400)
|
|
|
|
list_item = ListItem(user=user)
|
|
|
|
if request_data.get('entity') and Entity.objects.filter(mbid=request_data['entity']).count() == 0:
|
|
# Entity no existe en la base de datos, se crea
|
|
data = {
|
|
'mbid': request_data.get('entity', None),
|
|
'entity_type': request_data.get('entity_type', None)
|
|
}
|
|
|
|
entity_form = EntityForm(data)
|
|
|
|
if not entity_form.is_valid():
|
|
return JsonResponse({'status': 400, 'error': entity_form.errors.as_json()}, status=400)
|
|
|
|
entity_form.save()
|
|
|
|
form = ListItemForm(request_data, instance=list_item)
|
|
|
|
if not form.is_valid():
|
|
return JsonResponse({'status': 400, 'error': form.errors.as_json()}, status=400)
|
|
|
|
if user.list.filter(entity__mbid=request_data['entity']).count() > 0:
|
|
return JsonResponse({'status': 400,
|
|
'error': 'El usuario ya tiene esta entidad en su lista'},
|
|
status=400)
|
|
|
|
form.save()
|
|
|
|
return JsonResponse({'status': 200})
|
|
|
|
|
|
def list_item_view(request, user_id, list_item_id):
|
|
"""
|
|
Punto de entrada a las vistas de item de lista de un usuario
|
|
"""
|
|
|
|
# Tiene que existir un usuario con el id entregado.
|
|
user = User.objects.filter(pk=user_id)
|
|
if user.count() != 1:
|
|
return JsonResponse({'status': 404, 'error': f'No existe un usuario con id {user_id}'}, status=404)
|
|
user = user[0]
|
|
|
|
# Tiene que existir un item de lista de usuario con el id entregado
|
|
list_item = ListItem.objects.filter(id=list_item_id, user_id=user_id)
|
|
if list_item.count() == 0:
|
|
return JsonResponse({'status': 404, 'error': 'No existe el list_item'}, status=404)
|
|
list_item = list_item[0]
|
|
|
|
if request.method == 'GET':
|
|
return _get_list_item(request, list_item)
|
|
if request.method == 'PUT':
|
|
return _update_list_item(request, user, list_item)
|
|
elif request.method == 'DELETE':
|
|
return _remove_list_item(request, user, list_item)
|
|
else:
|
|
return JsonResponse({'status': 404, 'error': 'La ruta no existe'}, status=404)
|
|
|
|
|
|
def _get_list_item(request, list_item):
|
|
"""Obtiene un item de la lista del usuario"""
|
|
|
|
encoded_list_item = {
|
|
'entity': {
|
|
'mbid': list_item.entity.mbid,
|
|
'type': list_item.entity.entity_type,
|
|
},
|
|
'tags': [{
|
|
'id': tag.id,
|
|
'name': tag.name
|
|
} for tag in list_item.tags.all()],
|
|
'stars': list_item.stars,
|
|
'opinion': list_item.opinion
|
|
}
|
|
|
|
return JsonResponse(encoded_list_item)
|
|
|
|
|
|
@protected_resource()
|
|
def _update_list_item(request, user, list_item):
|
|
# Solo el dueño o un administrador puede modificar la lista
|
|
if request.user.id != user.id and not request.user.is_admin:
|
|
return JsonResponse({'status': 403,
|
|
'error': 'El usuario no tiene permiso para hacer esta acción'},
|
|
status=403)
|
|
|
|
try:
|
|
request_data = json.loads(request.body.decode('utf8'))
|
|
except JSONDecodeError:
|
|
return JsonResponse({'status': 400,
|
|
'error': 'El body de la request no es json valido'},
|
|
status=400)
|
|
|
|
form = ListItemForm(request_data, instance=list_item)
|
|
|
|
if not form.is_valid():
|
|
return JsonResponse({'status': 400, 'error': form.errors.as_json()}, status=400)
|
|
|
|
form.save()
|
|
|
|
return JsonResponse({'status': 200})
|
|
|
|
|
|
@protected_resource()
|
|
def _remove_list_item(request, user, list_item):
|
|
"""Elimina un item de la lista del usuario"""
|
|
|
|
# Solo el dueño o un administrador puede modificar la lista
|
|
if request.user.id != user.id and not request.user.is_admin:
|
|
return JsonResponse({'status': 403,
|
|
'error': 'El usuario no tiene permiso para hacer esta acción'},
|
|
status=403)
|
|
|
|
list_item.delete()
|
|
|
|
return JsonResponse({'status': 200})
|
|
|
|
|
|
def tag_view(request, user_id, tag_id=None):
|
|
"""
|
|
Punto de entrada para las vistas de tags
|
|
"""
|
|
|
|
# Tiene que existir un usuario con el id entregado.
|
|
user = User.objects.filter(pk=user_id)
|
|
if user.count() != 1:
|
|
return JsonResponse({'status': 404, 'error': f'No existe un usuario con id {user_id}'}, status=404)
|
|
user = user[0]
|
|
|
|
# Tag id puede ser none, pero si no lo es, tiene que existir
|
|
tag = None
|
|
if tag_id:
|
|
tag = Tag.objects.filter(pk=tag_id)
|
|
if tag.count() != 1:
|
|
return JsonResponse({'status': 404, 'error': f'No existe una tag con id {tag}'}, status=404)
|
|
tag = tag[0]
|
|
|
|
if request.method == 'GET':
|
|
return _get_tags(request, user)
|
|
elif request.method == 'POST':
|
|
return _post_tag(request, user)
|
|
elif request.method == 'PUT' and tag:
|
|
return _put_tag(request, user, tag)
|
|
elif request.method == 'DELETE' and tag:
|
|
return _delete_tag(request, user, tag)
|
|
else:
|
|
return JsonResponse({'status': 404, 'error': 'La ruta no existe'}, status=404)
|
|
|
|
|
|
def _get_tags(request, user):
|
|
"""Obtiene todas las tags de un usuario"""
|
|
|
|
encoded_tags = []
|
|
for tag in user.tags.all():
|
|
encoded_tags.append({
|
|
'id': tag.id,
|
|
'name': tag.name
|
|
})
|
|
|
|
return JsonResponse({'tags': encoded_tags})
|
|
|
|
|
|
@protected_resource()
|
|
def _post_tag(request, user):
|
|
"""Crea una nueva tag en un usuario"""
|
|
# Solo el dueño o un administrador puede modificar la lista
|
|
if request.user.id != user.id and not request.user.is_admin:
|
|
return JsonResponse({'status': 403,
|
|
'error': 'El usuario no tiene permiso para hacer esta acción'},
|
|
status=403)
|
|
|
|
try:
|
|
request_data = json.loads(request.body.decode('utf8'))
|
|
except JSONDecodeError:
|
|
return JsonResponse({'status': 400,
|
|
'error': 'El body de la request no es json valido'},
|
|
status=400)
|
|
|
|
tag = Tag(user=user)
|
|
form = TagForm(request_data, instance=tag)
|
|
|
|
if not form.is_valid():
|
|
return JsonResponse({'status': 400, 'error': form.errors.as_json()}, status=400)
|
|
|
|
if user.tags.filter(name=request_data['name']).count() > 0:
|
|
return JsonResponse({'status': 400, 'error': 'El usuario ya tiene un tag con ese nombre'}, status=400)
|
|
|
|
form.save()
|
|
|
|
return JsonResponse({'status': 200})
|
|
|
|
|
|
@protected_resource()
|
|
def _put_tag(request, user, tag):
|
|
"""Actualiza una tag"""
|
|
|
|
# Solo el dueño o un administrador puede modificar la lista
|
|
if request.user.id != user.id and not request.user.is_admin:
|
|
return JsonResponse({'status': 403,
|
|
'error': 'El usuario no tiene permiso para hacer esta acción'},
|
|
status=403)
|
|
|
|
try:
|
|
request_data = json.loads(request.body.decode('utf8'))
|
|
except JSONDecodeError:
|
|
return JsonResponse({'status': 400,
|
|
'error': 'El body de la request no es json valido'},
|
|
status=400)
|
|
|
|
form = TagForm(request_data, instance=tag)
|
|
|
|
if not form.is_valid():
|
|
return JsonResponse({'status': 400, 'error': form.errors.as_json()}, status=400)
|
|
|
|
if user.tags.filter(name=request_data['name']).count() > 0:
|
|
return JsonResponse({'status': 400, 'error': 'El usuario ya tiene un tag con ese nombre'}, status=400)
|
|
|
|
form.save()
|
|
|
|
return JsonResponse({'status': 200})
|
|
|
|
|
|
@protected_resource()
|
|
def _delete_tag(request, user, tag):
|
|
"""Elimina una tag de un usuario, al eliminarla se remueve de todas los listitem a las que estaba asociada"""
|
|
|
|
# Solo el dueño o un administrador puede modificar la lista
|
|
if request.user.id != user.id and not request.user.is_admin:
|
|
return JsonResponse({'status': 403,
|
|
'error': 'El usuario no tiene permiso para hacer esta acción'},
|
|
status=403)
|
|
|
|
# Eliminando la tag de los items que están asociados a ella
|
|
for list_item in tag.list.all():
|
|
list_item.tags.remove(tag)
|
|
|
|
tag.delete()
|
|
|
|
return JsonResponse({'status': 200}, status=200)
|
|
|
|
|
|
def get_entity_opinions(request, entity_mbid):
|
|
"""Opiniones sobre una entidad"""
|
|
|
|
if request.method != 'GET':
|
|
return JsonResponse({'status': 404, 'error': 'La ruta no existe'}, status=404)
|
|
|
|
# Tiene que existir la entidad con el id entregado.
|
|
items = ListItem.objects.filter(entity__mbid=entity_mbid)
|
|
if items.count() == 0:
|
|
return JsonResponse({'status': 404, 'error': f'La entidad {entity_mbid} no esta en ninguna lista'}, status=404)
|
|
|
|
encoded_opinions = []
|
|
for item in items:
|
|
helpful_y = OpinionHelpful.objects.filter(opinion_id=item, vote='Y').count()
|
|
helpful_n = OpinionHelpful.objects.filter(opinion_id=item, vote='N').count()
|
|
helpful_f = OpinionHelpful.objects.filter(opinion_id=item, vote='F').count()
|
|
|
|
encoded_opinions.append({
|
|
'user': {
|
|
'id': item.user.id,
|
|
'username': item.user.username,
|
|
},
|
|
'opinion': item.opinion,
|
|
'stars': item.stars,
|
|
'helpful': {
|
|
'Y': helpful_y,
|
|
'N': helpful_n,
|
|
'F': helpful_f,
|
|
}
|
|
})
|
|
|
|
return JsonResponse({'opinions': encoded_opinions})
|