Merge branch 'app.wiai.de' of https://mg-server.ddns.net/git/BaStA/basta-server into app.wiai.de

This commit is contained in:
otrs 2018-04-17 00:47:52 +02:00
commit 5c09a4c6a1
16 changed files with 419 additions and 1 deletions

View File

View File

@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib import admin
from apps.bug_report.models import BugMsg
admin.site.register(BugMsg)

View File

View File

@ -0,0 +1,73 @@
from apps.bug_report.models import BugMsg
from rest_framework import serializers
class BugMsgCategoriesSerializer(serializers.Serializer):
"""Your data serializer, define your fields here."""
def create(self, validated_data):
pass
def update(self, instance, validated_data):
pass
id = serializers.CharField()
short = serializers.CharField()
name = serializers.CharField()
class BugMsgStatesSerializer(serializers.Serializer):
"""Your data serializer, define your fields here."""
def create(self, validated_data):
pass
def update(self, instance, validated_data):
pass
id = serializers.CharField()
name = serializers.CharField()
class BugMsgPrioritiesSerializer(serializers.Serializer):
"""Your data serializer, define your fields here."""
def create(self, validated_data):
pass
def update(self, instance, validated_data):
pass
id = serializers.CharField()
name = serializers.CharField()
class BugMsgSerializer(serializers.HyperlinkedModelSerializer):
category = serializers.ChoiceField(choices=BugMsg.CATEGORY_CHOICES)
status = serializers.ChoiceField(choices=BugMsg.STATE_CHOICES)
# def create(self, validated_data):
# title = validated_data.pop('title')
# description = validated_data.pop('description')
# category = validated_data.pop('category')
# if 'status' in validated_data:
# status = validated_data.pop('status')
# else:
# status = BugMsg.REGISTERED
# bugMsg, _ = BugMsg.objects.get_or_create(title=title, description=description, category=category, status=status)
# return bugMsg
class Meta:
model = BugMsg
fields = ('id', 'title', 'status', 'description', 'category')
class BugMsgDetailSerializer(serializers.HyperlinkedModelSerializer):
category = serializers.ChoiceField(choices=BugMsg.CATEGORY_CHOICES)
priority = serializers.ChoiceField(choices=BugMsg.PRIORITY_CHOICES)
status = serializers.ChoiceField(choices=BugMsg.STATE_CHOICES)
registration_date = serializers.DateField(format='iso-8601')
class Meta:
model = BugMsg
fields = ('id', 'registration_date', 'title', 'description', 'category', 'priority', 'status')

View File

@ -0,0 +1,26 @@
"""ofu_app URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.urls import path
from apps.bug_report.api.v1_2 import views as api_views
urlpatterns = [
# API Version 1.2
path('bug-report/reports/', api_views.ApiBugMsgs.as_view(), name='bug-reports'),
path('bug-report/reports/<int:pk>/', api_views.ApiBugMsgUpdate.as_view(), name='bug-report'),
path('bug-report/priorities/', api_views.ApiBugPriorities.as_view(), name='bug-priorities'),
path('bug-report/categories/', api_views.ApiBugCategories.as_view(), name='bug-categories'),
path('bug-report/states/', api_views.ApiBugStates.as_view(), name='bug-states'),
]

View File

@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from apps.bug_report.api.v1_2.serializers import BugMsgSerializer, BugMsgCategoriesSerializer, \
BugMsgPrioritiesSerializer, BugMsgStatesSerializer, BugMsgDetailSerializer
from apps.bug_report.models import BugMsg
from rest_framework import generics, views, status
from rest_framework.decorators import permission_classes
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
@permission_classes((AllowAny,))
class ApiBugMsgs(generics.ListCreateAPIView):
serializer_class = BugMsgSerializer
queryset = BugMsg.objects.order_by('-registration_date')
@permission_classes((AllowAny,))
class ApiBugMsgUpdate(generics.RetrieveUpdateAPIView):
serializer_class = BugMsgDetailSerializer
queryset = BugMsg.objects.all()
@permission_classes((AllowAny,))
class ApiBugPriorities(views.APIView):
def get(self, request):
data = BugMsg.API_Priorities
results = BugMsgPrioritiesSerializer(data, many=True).data
return Response(results, status=status.HTTP_200_OK)
@permission_classes((AllowAny,))
class ApiBugCategories(views.APIView):
def get(self, request):
data = BugMsg.API_CATEGORIES
results = BugMsgCategoriesSerializer(data, many=True).data
return Response(results, status=status.HTTP_200_OK)
@permission_classes((AllowAny,))
class ApiBugStates(views.APIView):
def get(self, request):
data = BugMsg.API_STATES
results = BugMsgStatesSerializer(data, many=True).data
return Response(results, status=status.HTTP_200_OK)

View File

@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.apps import AppConfig
class FoodConfig(AppConfig):
name = 'apps.food'

View File

@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import os
from io import BytesIO
import uuid
from _datetime import datetime
from PIL import Image
from django.conf import settings
from django.contrib.auth.models import User
from django.core.files.uploadedfile import SimpleUploadedFile
from django.db import models
from django.utils import timezone
from django.core.validators import MaxValueValidator, MinValueValidator
MAX_LENGTH = 256
MAX_TITLE_LENGTH = 128
MAX_DESCRIPTION_LENGTH = 1024
MAX_PRIORITY_LENGTH = 32
MAX_CATEGORY_LENGTH = 32
MAX_STATE_LENGTH = 64
# Create your models here.
class BugMsg(models.Model):
# Priorities
HIGH = 'HIGH'
LOW = 'LOW'
# Categories
FOOD = 'FOOD'
EVENTS = 'Events'
DONAR = 'DONAR'
OTHER = 'Other'
# State
REGISTERED = 'REGISTERED'
TODO = 'TODO'
IN_PROGRESS = 'IN_PROGRESS'
DONE = 'DONE'
REJECTED = 'REJECTED'
PRIORITY_CHOICES = (
(HIGH, 'High'), (LOW, 'Low')
)
CATEGORY_CHOICES = (
(FOOD, 'Food App'), (EVENTS, 'Event App'), (DONAR, 'Donar App'), (OTHER, 'Other')
)
STATE_CHOICES = (
(REGISTERED, 'registered'), (TODO, 'todo'), (IN_PROGRESS, 'in progress'), (DONE, 'done'), (REJECTED, 'rejected')
)
# Api priorities data
API_Priorities = [{'id': HIGH, 'name': 'High'},
{'id': LOW, 'name': 'Low'}, ]
# Api categories data
API_CATEGORIES = [{'id': FOOD, 'name': 'Food App', 'short': 'Food'},
{'id': EVENTS, 'name': 'Event App', 'short': 'Events'},
{'id': DONAR, 'name': 'Donar App', 'short': 'Donar'},
{'id': OTHER, 'name': 'Other', 'short': 'Other'}, ]
# Api state data
API_STATES = [{'id': REGISTERED, 'name': 'Registered'},
{'id': TODO, 'name': 'todo'},
{'id': IN_PROGRESS, 'name': 'in progress'},
{'id': DONE, 'name': 'done'},
{'id': REJECTED, 'name': 'rejected'},
]
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=MAX_TITLE_LENGTH, unique=True)
description = models.CharField(max_length=MAX_DESCRIPTION_LENGTH)
priority = models.CharField(max_length=MAX_PRIORITY_LENGTH, choices=PRIORITY_CHOICES)
category = models.CharField(max_length=MAX_CATEGORY_LENGTH, choices=CATEGORY_CHOICES)
status = models.CharField(max_length=MAX_STATE_LENGTH, choices=STATE_CHOICES)
registration_date = models.DateField(default=timezone.now)
def __str__(self):
return "%s - %s - %s - %s" % (self.registration_date.strftime("%d.%m.%Y"), self.title, self.priority, self.status)

View File

@ -0,0 +1,133 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.test import TestCase
from django.urls import reverse
from apps.food.models import SingleFood, Menu
from apps.food.api.v1_1.serializers import MenuSerializer
from rest_framework import status
from datetime import datetime
# Create your tests here.
class SingleFood_Scope(TestCase):
def setUp(self):
self.singlefood_1 = SingleFood.objects.create(name="testfood1")
self.singlefood_2 = SingleFood.objects.create(name="testfood2")
self.singlefood_3 = SingleFood.objects.create(name="testfood3")
self.singlefood_4 = SingleFood.objects.create(name="testfood4")
self.singlefood_5 = SingleFood.objects.create(name="testfood5")
self.singlefood_6 = SingleFood.objects.create(name="testfood6")
self.today_menu = Menu.objects.create(date='2017-01-15', location=Menu.ERBA)
self.today_menu.menu.add(self.singlefood_1)
self.today_menu.menu.add(self.singlefood_2)
self.today_menu.menu.add(self.singlefood_3)
self.menu_2 = Menu.objects.create(date='2017-01-10', location=Menu.FEKI)
self.menu_2.menu.add(self.singlefood_4)
self.menu_2.menu.add(self.singlefood_5)
self.menu_2.menu.add(self.singlefood_6)
def test_get_food_root(self):
"""
All menus in response
"""
menus = Menu.objects.all()
serializer = MenuSerializer(menus, many=True)
response = self.client.get(reverse('api-v1_1-food-all'))
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data, serializer.data)
def test_get_food_date_param(self):
"""
Menu for a given date is in the response
"""
serializer = MenuSerializer(self.menu_2, many=False)
response_1 = self.client.get(reverse('api-v1_1-food-date', kwargs={'year': '2017', 'month': '01', 'day': '10'}))
self.assertEqual(response_1.status_code, 200)
self.assertEqual(response_1.data, [serializer.data])
serializer_2 = MenuSerializer(self.today_menu, many=False)
response_2 = self.client.get(reverse('api-v1_1-food-date', kwargs={'year': '2017', 'month': '01', 'day': '15'}))
self.assertEqual(response_2.status_code, 200)
self.assertEqual(response_2.data, [serializer_2.data])
def test_get_food_date_param_not_in_set(self):
"""
Empty response if no object with request date in set
"""
response_1 = self.client.get(reverse('api-v1_1-food-date', kwargs={'year': '2017', 'month': '01', 'day': '11'}))
self.assertEqual(response_1.status_code, 200)
self.assertEqual(response_1.data, [])
def test_get_food_location_param(self):
"""
Menu for a given location is in the response
"""
serializer_1 = MenuSerializer(self.today_menu, many=False)
response_1 = self.client.get(reverse('api-v1_1-food-location', kwargs={'location': Menu.ERBA}))
self.assertEqual(response_1.status_code, 200)
self.assertEqual(response_1.data, [serializer_1.data])
serializer_2 = MenuSerializer(self.menu_2, many=False)
response_2 = self.client.get(reverse('api-v1_1-food-location', kwargs={'location': Menu.FEKI}))
self.assertEqual(response_2.status_code, 200)
self.assertEqual(response_2.data, [serializer_2.data])
def test_get_food_location_param_not_in_set(self):
"""
Empty response if no object with request location in set
"""
response_1 = self.client.get(reverse('api-v1_1-food-location', kwargs={'location': Menu.AUSTRASSE}))
self.assertEqual(response_1.status_code, 200)
self.assertEqual(response_1.data, [])
def test_get_food_location_date_param(self):
"""
Menu for request location and date is in the response
"""
serializer = MenuSerializer(self.menu_2, many=False)
response = self.client.get(reverse('api-v1_1-food-location-date',
kwargs={'year': '2017', 'month': '01', 'day': '10',
'location': Menu.FEKI}))
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data, [serializer.data])
def test_get_food_location_date_param_not_in_set(self):
"""
Empty response if no object with request date and location in set
"""
response_1 = self.client.get(reverse('api-v1_1-food-location-date',
kwargs={'year': '2017', 'month': '01', 'day': '11',
'location': Menu.FEKI}))
self.assertEqual(response_1.status_code, 200)
self.assertEqual(response_1.data, [])
response_1 = self.client.get(reverse('api-v1_1-food-location-date',
kwargs={'year': '2017', 'month': '01', 'day': '10',
'location': Menu.AUSTRASSE}))
self.assertEqual(response_1.status_code, 200)
self.assertEqual(response_1.data, [])
def test_get_food_today_param(self):
"""
Menu for request today is in the response
"""
self.singlefood = SingleFood.objects.create(name="testfood")
self.today_menu = Menu.objects.create(date=datetime.today().strftime('%Y-%m-%d'), location=Menu.ERBA)
self.today_menu.menu.add(self.singlefood)
serializer = MenuSerializer(self.today_menu, many=False)
response = self.client.get(reverse('api-v1_1-food-today'))
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data, [serializer.data])
def test_get_food_today_param_not_in_set(self):
"""
Empty response if no object with date 'today' is in set
"""
response = self.client.get(reverse('api-v1_1-food-today'))
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data, [])

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.test import TestCase
from apps.food.models import SingleFood
# Create your tests here.
class SingleFood_Scope(TestCase):
def setUp(self):
SingleFood.objects.create(name="testfood")
def test_food_created_just_with_name(self):
"""Animals that can speak are correctly identified"""
food = SingleFood.objects.get(name="testfood")
self.assertEqual(food.name, 'testfood')
self.assertIsNone(food.allergens.all().first(), [])
self.assertIsNone(food.price_employee)
self.assertIsNone(food.price_guest)
self.assertIsNone(food.price_student)
self.assertIsNone(food.image)
self.assertEqual(food.rating, 0.0)

View File

@ -4,6 +4,9 @@ from django.contrib.auth.models import User
from rest_framework import validators from rest_framework import validators
from rest_framework import serializers from rest_framework import serializers
from django.db.utils import IntegrityError from django.db.utils import IntegrityError
import logging
logger = logging.getLogger(__name__)
class UserFoodImageSerializer(serializers.HyperlinkedModelSerializer): class UserFoodImageSerializer(serializers.HyperlinkedModelSerializer):
@ -90,6 +93,8 @@ class UserFoodImageSerializer(serializers.ModelSerializer):
image = validated_data.pop('image') image = validated_data.pop('image')
food_image = FoodImage.objects.create(image=image) food_image = FoodImage.objects.create(image=image)
food_image.save() food_image.save()
logger.info('New Image: {}\nFood: {}'.format(food_image.image.url, food.name))
logger.error('New Image: {}\nFood: {}'.format(food_image.image.url, food.name))
try: try:
user_food_image = UserFoodImage.objects.create(user=user, food=food, image=food_image) user_food_image = UserFoodImage.objects.create(user=user, food=food, image=food_image)
user_food_image.save() user_food_image.save()

View File

@ -56,7 +56,7 @@ class ApiMenus(generics.ListAPIView):
except ValueError as e: except ValueError as e:
# TODO: return Exception # TODO: return Exception
return [] return []
queryset.order_by('date')
return queryset return queryset

View File

@ -101,6 +101,7 @@ INSTALLED_APPS = [
'apps.events', 'apps.events',
'apps.donar', 'apps.donar',
'apps.registration', 'apps.registration',
'apps.bug_report',
'rest_framework', 'rest_framework',
'rest_framework.authtoken', 'rest_framework.authtoken',
'djoser', 'djoser',
@ -235,6 +236,10 @@ LOGGING = {
'level': 'ERROR', 'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler', 'class': 'django.utils.log.AdminEmailHandler',
}, },
'mail_admins_image_upload': {
'level': 'INFO',
'class': 'django.utils.log.AdminEmailHandler',
},
}, },
'loggers': { 'loggers': {
'apps.food.utils': { 'apps.food.utils': {
@ -245,5 +250,9 @@ LOGGING = {
'handlers': ['console', 'file', 'mail_admins'], 'handlers': ['console', 'file', 'mail_admins'],
'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG'), 'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG'),
}, },
'apps.food.api.v1_2.serializers.user_serializers': {
'handlers': ['mail_admins_image_upload', 'console'],
'level': 'INFO',
},
}, },
} }

View File

@ -57,6 +57,7 @@ urlpatterns = [
# -- Version 1.2 # -- Version 1.2
url(r'^api/v1.2/', include('apps.food.api.v1_2.urls')), url(r'^api/v1.2/', include('apps.food.api.v1_2.urls')),
url(r'^api/v1.2/', include('apps.registration.api.urls')), url(r'^api/v1.2/', include('apps.registration.api.urls')),
url(r'^api/v1.2/', include('apps.bug_report.api.v1_2.urls')),
# -- Third Party APIs # -- Third Party APIs
url(r'^api/auth/', include('rest_framework.urls', namespace='rest_framework')), url(r'^api/auth/', include('rest_framework.urls', namespace='rest_framework')),