157 lines
6.1 KiB
Python
157 lines
6.1 KiB
Python
from django.urls import re_path
|
|
from django.contrib.auth.decorators import permission_required
|
|
from rest_framework import routers, viewsets, status
|
|
from rest_framework.decorators import api_view, permission_classes
|
|
from rest_framework.response import Response
|
|
from rest_framework.permissions import IsAuthenticated
|
|
|
|
from inventory.models import Event, Container, Item, Comment
|
|
from inventory.serializers import EventSerializer, ContainerSerializer, CommentSerializer, ItemSerializer, \
|
|
SearchResultSerializer
|
|
|
|
from base64 import b64decode
|
|
|
|
|
|
class EventViewSet(viewsets.ModelViewSet):
|
|
serializer_class = EventSerializer
|
|
queryset = Event.objects.all()
|
|
permission_classes = []
|
|
|
|
|
|
class ContainerViewSet(viewsets.ModelViewSet):
|
|
serializer_class = ContainerSerializer
|
|
queryset = Container.objects.all()
|
|
|
|
|
|
class ItemViewSet(viewsets.ModelViewSet):
|
|
serializer_class = ItemSerializer
|
|
|
|
def prefetch_queryset(self, queryset):
|
|
serializer = self.get_serializer_class()
|
|
if hasattr(serializer, 'Meta') and hasattr(serializer.Meta, 'prefetch_related_fields'):
|
|
queryset = queryset.prefetch_related(*serializer.Meta.prefetch_related_fields)
|
|
return queryset
|
|
|
|
def get_queryset(self):
|
|
queryset = Item.objects.all()
|
|
return self.prefetch_queryset(queryset)
|
|
|
|
|
|
def filter_items(items, query):
|
|
query_tokens = query.split(' ')
|
|
for item in items:
|
|
value = 0
|
|
for token in query_tokens:
|
|
if token in item.description:
|
|
value += 1
|
|
if value > 0:
|
|
yield {'search_score': value, 'item': item}
|
|
|
|
|
|
@api_view(['GET'])
|
|
@permission_classes([IsAuthenticated])
|
|
def search_items(request, event_slug, query):
|
|
try:
|
|
event = Event.objects.get(slug=event_slug)
|
|
if not request.user.has_event_perm(event, 'view_item'):
|
|
return Response(status=403)
|
|
items = filter_items(Item.objects.filter(event=event), b64decode(query).decode('utf-8'))
|
|
return Response(SearchResultSerializer(items, many=True).data)
|
|
except Event.DoesNotExist:
|
|
return Response(status=404)
|
|
|
|
|
|
@api_view(['GET', 'POST'])
|
|
@permission_classes([IsAuthenticated])
|
|
def item(request, event_slug):
|
|
vs = ItemViewSet()
|
|
try:
|
|
event = None
|
|
if event_slug != 'none':
|
|
event = Event.objects.get(slug=event_slug)
|
|
if request.method == 'GET':
|
|
if not request.user.has_event_perm(event, 'view_item'):
|
|
return Response(status=403)
|
|
return Response(ItemSerializer(vs.prefetch_queryset(Item.objects.filter(event=event)), many=True).data)
|
|
elif request.method == 'POST':
|
|
if not request.user.has_event_perm(event, 'add_item'):
|
|
return Response(status=403)
|
|
validated_data = ItemSerializer(data=request.data)
|
|
if validated_data.is_valid():
|
|
validated_data.save(event=event)
|
|
return Response(validated_data.data, status=201)
|
|
return Response(status=400)
|
|
except Event.DoesNotExist:
|
|
return Response(status=404)
|
|
except KeyError:
|
|
return Response(status=400)
|
|
|
|
|
|
@api_view(['POST'])
|
|
@permission_classes([IsAuthenticated])
|
|
@permission_required('tickets.add_comment', raise_exception=True)
|
|
def add_comment(request, event_slug, id):
|
|
event = None
|
|
if event_slug != 'none':
|
|
event = Event.objects.get(slug=event_slug)
|
|
item = Item.objects.get(event=event, id=id)
|
|
if not request.user.has_event_perm(event, 'view_item'):
|
|
return Response(status=403)
|
|
if 'comment' not in request.data or request.data['comment'] == '':
|
|
return Response({'status': 'error', 'message': 'missing comment'}, status=status.HTTP_400_BAD_REQUEST)
|
|
comment = Comment.objects.create(
|
|
item=item,
|
|
comment=request.data['comment'],
|
|
)
|
|
return Response(CommentSerializer(comment).data, status=status.HTTP_201_CREATED)
|
|
|
|
|
|
@api_view(['GET', 'PUT', 'DELETE', 'PATCH'])
|
|
@permission_classes([IsAuthenticated])
|
|
def item_by_id(request, event_slug, id):
|
|
try:
|
|
event = Event.objects.get(slug=event_slug)
|
|
item = Item.objects.get(event=event, id=id)
|
|
if request.method == 'GET':
|
|
if not request.user.has_event_perm(event, 'view_item'):
|
|
return Response(status=403)
|
|
return Response(ItemSerializer(item).data)
|
|
elif request.method == 'PUT':
|
|
if not request.user.has_event_perm(event, 'change_item'):
|
|
return Response(status=403)
|
|
validated_data = ItemSerializer(item, data=request.data)
|
|
if validated_data.is_valid():
|
|
validated_data.save()
|
|
return Response(validated_data.data)
|
|
return Response(validated_data.errors, status=400)
|
|
elif request.method == 'PATCH':
|
|
if not request.user.has_event_perm(event, 'change_item'):
|
|
return Response(status=403)
|
|
validated_data = ItemSerializer(item, data=request.data, partial=True)
|
|
if validated_data.is_valid():
|
|
validated_data.save()
|
|
return Response(validated_data.data)
|
|
return Response(validated_data.errors, status=400)
|
|
elif request.method == 'DELETE':
|
|
if not request.user.has_event_perm(event, 'delete_item'):
|
|
return Response(status=403)
|
|
item.delete()
|
|
return Response(status=204)
|
|
except Item.DoesNotExist:
|
|
return Response(status=404)
|
|
except Event.DoesNotExist:
|
|
return Response(status=404)
|
|
|
|
|
|
router = routers.SimpleRouter()
|
|
router.register(r'events', EventViewSet, basename='events')
|
|
router.register(r'boxes', ContainerViewSet, basename='boxes')
|
|
router.register(r'box', ContainerViewSet, basename='boxes')
|
|
|
|
urlpatterns = router.urls + [
|
|
re_path(r'^(?P<event_slug>[\w-]+)/items/$', item, name='item'),
|
|
re_path(r'^(?P<event_slug>[\w-]+)/items/(?P<query>[-A-Za-z0-9+/]*={0,3})/$', search_items, name='search_items'),
|
|
re_path(r'^(?P<event_slug>[\w-]+)/item/$', item, name='item'),
|
|
re_path(r'^(?P<event_slug>[\w-]+)/item/(?P<id>\d+)/comment/$', add_comment, name='add_comment'),
|
|
re_path(r'^(?P<event_slug>[\w-]+)/item/(?P<id>\d+)/$', item_by_id, name='item_by_id'),
|
|
]
|