Compare commits

..

3 Commits

Author SHA1 Message Date
dc0695f369 added custom permissions 2025-02-18 23:47:49 +01:00
9cfdad68f8 created base classes for common views. 2025-02-18 23:47:08 +01:00
9d9a86efaa added spiders app 2025-02-18 23:46:22 +01:00
13 changed files with 289 additions and 2 deletions

10
settings/puckomissions.py Normal file
View File

@ -0,0 +1,10 @@
from rest_framework.permissions import BasePermission
from rest_framework.permissions import SAFE_METHODS
class IsAdminOrReadOnly(BasePermission):
def has_permission(self, request, view):
if request.method in SAFE_METHODS:
return True
return bool(request.user and request.user.is_staff)

133
settings/puckoviews.py Normal file
View File

@ -0,0 +1,133 @@
from knox.auth import TokenAuthentication
from rest_framework.viewsets import GenericViewSet
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework.viewsets import ViewSetMixin
from rest_framework.decorators import action
from rest_framework.renderers import BrowsableAPIRenderer
from rest_framework.renderers import JSONRenderer
from rest_framework_yaml.renderers import YAMLRenderer
from rest_framework_xml.renderers import XMLRenderer
from settings.puckomissions import IsAdminOrReadOnly
from settings.puckignation import MediumPagination
class PuckoView(GenericViewSet, ViewSetMixin):
authentication_classes = (TokenAuthentication,)
renderer_classes = (BrowsableAPIRenderer, JSONRenderer, YAMLRenderer, XMLRenderer)
serializer_class = None
model_class = None
class PuckoPagesView(PuckoView):
pagination_class = MediumPagination
def get_queryset(self):
return self.model_class.objects.all()
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
def get_paginated_response(self, data, status=200):
"""
Return a paginated style `Response` object for the given output data.
"""
assert self.paginator is not None
return self.paginator.get_paginated_response(data, status=200)
def get_paginated_response_schema(self, *args, **kwargs):
assert self.paginator is not None
return self.paginator.get_paginated_response_schema(*args, **kwargs)
class PuckoPaginatedView(PuckoPagesView):
def __init__(self, *args, **kwargs):
super(PuckoPaginatedView).__init__(*args, **kwargs)
@action(detail=False)
def fetch_all(self, request):
query = self.paginator.paginate_queryset(self.get_queryset(), request)
serializer = self.serializer_class(query, many=True)
return self.get_paginated_response(serializer.data, status=200)
class PuckoSearchView(PuckoPagesView):
@action(detail=False)
def list(self, request):
serializer = self.serializer_class(data=request.data, many=False)
data = serializer.initial_data
if serializer.is_valid():
data = self.paginator.paginate_queryset(self.get_object(data), request)
ret = self.serializer_class(data, many=True)
if len(ret.data) < 1:
return Response({"message": "Could not find anything"}, status="404")
return self.get_paginated_response(ret.data, status=200)
return Response({"message": "not a valid search."}, status=400)
class PuckoAddView(PuckoView):
@action(detail=True)
def create(self, request):
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
class PuckoAllAddView(PuckoPaginatedView, PuckoAddView):
pass
class PuckoSlugView(PuckoView):
permission_classes = (IsAdminOrReadOnly,)
def get_object(self, slug):
try:
return self.model_class.objects.get(slug=slug)
except:
return Response({"message": f"{self.model_class.__class__.__name__} could not be found."})
@action(detail=True)
def retrieve(self, request, slug):
obj = self.get_object(slug)
if isinstance(obj, Response):
return obj
serializer = self.serializer_class(obj)
return Response(serializer.data, status=200)
@action(detail=True)
def update(self, request, slug):
obj = self.get_object(slug)
if isinstance(obj, Response):
return obj
serializer = self.serializer_class(obj, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
@action(detail=True)
def update_partial(self, request, slug):
obj = self.get_object(slug)
if isinstance(obj, Response):
return obj
serializer = self.serializer_class(obj, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
@action(detail=True)
def delete(self, request, slug):
obj = self.get_object(slug)
if isinstance(obj, Response):
return obj
if obj is None:
return Response({"message", "could not delete, what i could not find."})
obj.delete()
return Response({"message": f"{obj.__class__.__name__} deleted."}, status=204)

View File

@ -61,8 +61,8 @@ INSTALLED_APPS = [
'knox',
# my shit
'options',
'users'
'users',
'spiders'
]
MIDDLEWARE = [

View File

@ -24,6 +24,7 @@ from drf_spectacular.views import SpectacularSwaggerView
urlpatterns = [
path("auth/", include('users.urls')),
path("spiders/", include('spiders.urls')),
# Spectacular
path("schema/", SpectacularAPIView.as_view(), name="schema-text"),

0
spiders/__init__.py Normal file
View File

6
spiders/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class SpidersConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'spiders'

View File

@ -0,0 +1,59 @@
from rest_framework import serializers
class DagensLunch(serializers.Serializer):
place = serializers.CharField(max_length=20)
monday = serializers.CharField()
tuesday = serializers.CharField()
wednesday = serializers.CharField()
thursday = serializers.CharField()
friday = serializers.CharField()
scraped_by = serializers.CharField(max_length=40)
scraped_at = serializers.DateTimeField()
class Meta:
fields = ("place", "monday", "tuesday", "wednesday", "thursday", "friday", "scraped_by", "scraped_at")
read_only_fields = ("place", "monday", "tuesday", "wednesday", "thursday", "friday", "scraped_by", "scraped_at")
class DagensLunchMax(DagensLunch):
class Meta(DagensLunch.Meta):
pass
class DagensLunchValsaren(DagensLunch):
week = serializers.CharField()
alltid = serializers.CharField()
klassiker = serializers.CharField()
price = serializers.DecimalField(max_digits=6, decimal_places=2)
price_takeaway = serializers.DecimalField(max_digits=6, decimal_places=2)
class Meta(DagensLunch.Meta):
fields = DagensLunch.Meta.fields + (
"week", "alltid", "klassiker", "price", "price_takeaway"
)
read_only_fields = DagensLunch.Meta.read_only_fields + (
"week", "alltid", "klassiker", "price", "price_takeaway"
)
class DagensLunchMalmens(DagensLunch):
week = serializers.CharField()
monday = serializers.ListField()
tuesday = serializers.ListField()
wednesday = serializers.ListField()
thursday = serializers.ListField()
friday = serializers.ListField()
class Meta(DagensLunch.Meta):
fields = DagensLunch.Meta.fields + ( "week", )
read_only_fields = DagensLunch.Meta.read_only_fields + ( "week", )
class DagensLunchHeat(DagensLunch):
monday = serializers.ListField()
tuesday = serializers.ListField()
wednesday = serializers.ListField()
thursday = serializers.ListField()
friday = serializers.ListField()
week = serializers.CharField()
class Meta(DagensLunch.Meta):
fields = DagensLunch.Meta.fields + ( "week", )
read_only_fields = DagensLunch.Meta.read_only_fields + ( "week", )

View File

@ -0,0 +1,12 @@
from django.urls import path
from spiders.dagens_lunch.views import Lunch_Valsaren_View
from spiders.dagens_lunch.views import Lunch_Malmens_View
from spiders.dagens_lunch.views import Lunch_Heat_View
from spiders.dagens_lunch.views import Lunch_Max_View
urlpatterns = [
path("valsaren/", Lunch_Valsaren_View.as_view({"get": "lunch"}), name="spiders_dagens_lunch_valsaren"),
path("malmens/", Lunch_Malmens_View.as_view({"get": "lunch"}), name="spiders_dagens_lunch_malmens"),
path("heat/", Lunch_Heat_View.as_view({"get": "lunch"}), name="spiders_dagens_lunch_heat"),
path("max/", Lunch_Max_View.as_view({"get": "lunch"}), name="spiders_dagens_lunch_max"),
]

View File

@ -0,0 +1,55 @@
import json
from pathlib import Path
from settings.puckoviews import PuckoView
from rest_framework.response import Response
from rest_framework.permissions import AllowAny
from spiders.dagens_lunch.serializer import DagensLunchValsaren
from spiders.dagens_lunch.serializer import DagensLunchMalmens
from spiders.dagens_lunch.serializer import DagensLunchHeat
from spiders.dagens_lunch.serializer import DagensLunchMax
DAGENS_LUNCH_PATH = Path("/home/riisen/utveckling/spiders/dagens_lunch/latest")
class Lunch_Valsaren_View(PuckoView):
permission_classes = [AllowAny,]
serializer_class = DagensLunchValsaren
def lunch(self, request):
file = DAGENS_LUNCH_PATH / "valsaren.json"
with open(file, "r") as f:
data = json.load(f)
serializer = self.serializer_class(data)
return Response(serializer.data, status=200)
class Lunch_Malmens_View(PuckoView):
permission_classes = [AllowAny,]
serializer_class = DagensLunchMalmens
def lunch(self, request):
file = DAGENS_LUNCH_PATH / "malmens.json"
with open(file, "r") as f:
data = json.load(f)
serializer = self.serializer_class(data)
return Response(serializer.data, status=200)
class Lunch_Heat_View(PuckoView):
permission_classes = [AllowAny,]
serializer_class = DagensLunchHeat
def lunch(self, request):
file = DAGENS_LUNCH_PATH / "heat.json"
with open(file, "r") as f:
data = json.load(f)
serializer = self.serializer_class(data)
return Response(serializer.data, status=200)
class Lunch_Max_View(PuckoView):
permission_classes = [AllowAny,]
serializer_class = DagensLunchMax
def lunch(self, request):
file = DAGENS_LUNCH_PATH / "max.json"
with open(file, "r") as f:
data = json.load(f)
serializer = self.serializer_class(data)
return Response(serializer.data, status=200)

View File

3
spiders/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

6
spiders/urls.py Normal file
View File

@ -0,0 +1,6 @@
from django.urls import path
from django.urls import include
urlpatterns = [
path("dagens_lunch/", include("spiders.dagens_lunch.urls"))
]

2
spiders/views.py Normal file
View File

@ -0,0 +1,2 @@
import json