from django.conf import settings from django.db import models from django.http import HttpResponse import json import time import boto3 from telegram import Update from rest_framework import viewsets, status from rest_framework.response import Response from rest_framework.decorators import action from django_filters.rest_framework import DjangoFilterBackend from django.db.models import Count, Subquery, OuterRef, Value from django.db.models.functions import Concat from django.contrib.postgres.aggregates import ArrayAgg from .tgbot import TgBot from .updater import tg_bot_updater_instance from .models import TgItem, TmcElement, TmcField from .serializers import TgItemSerializer, TmcFieldSerializer, TgStatItemSerializer import logging logger = logging.getLogger("root") class TgItemViewSet(viewsets.ModelViewSet): queryset = TgItem.objects.filter(is_check=True).order_by("-created_at") serializer_class = TgItemSerializer http_method_names = ["post", "get", "patch", "delete"] permission_classes = () authentication_classes = () filter_backends = [DjangoFilterBackend] filterset_fields = ["user_id"] def retrieve(self, request, pk=None): item = TgItem.objects.get(id=pk) logger.info( item.tmc.values("tmc__name").annotate(count=models.Count("tmc__name")) ) return super().retrieve(request, pk) # return Response(serializer.data) def partial_update(self, request, *args, **kwargs): if "location_id" in request.data: request.data["location"] = 35 return super().partial_update(request) def destroy(self, request, *args, **kwargs): instance = self.get_object() if instance.tmc.count() == 0: return super().destroy(request) else: return Response(status=status.HTTP_204_NO_CONTENT) @action(detail=False, methods=["post"], url_path=settings.TGBOT["WEBHOOK_URL"]) def send_tg_data(self, request): tg_bot_updater_instance.my_queue.put( Update.de_json(data=json.loads(request.body), bot=TgBot.app.bot) ) return Response({"result": "ok"}) # return super().create(request, *args, **kwargs) class TmcFieldViewset(viewsets.ModelViewSet): queryset = TmcField.objects.all() serializer_class = TmcFieldSerializer http_method_names = ["post", "get", "patch"] permission_classes = () authentication_classes = () def partial_update(self, request, *args, **kwargs): return super().partial_update(request) @action(detail=False, methods=["get"], url_path=r"get_name/(?P[^/.]+)") def get_name(self, request, chat_id): tg_bot_updater_instance.my_queue.put( {"name": "admin_get_name", "queryset": chat_id} ) response = [] timer = 30 while timer > 0: sleeping = 1 timer -= sleeping time.sleep(sleeping) if chat_id in tg_bot_updater_instance.return_values: response.append(tg_bot_updater_instance.return_values[chat_id]) del tg_bot_updater_instance.return_values[chat_id] break return Response(response) @action(detail=False, methods=["get"], url_path=r"get_image/(?P[^/.]+)") def get_image(self, request, field_id): tg_bot_updater_instance.my_queue.put( {"name": "admin_get_image", "queryset": field_id} ) response = [] timer = 30 while timer > 0: sleeping = 1 timer -= sleeping time.sleep(sleeping) if field_id in tg_bot_updater_instance.return_values: response.append(tg_bot_updater_instance.return_values[field_id]) del tg_bot_updater_instance.return_values[field_id] break return Response(response) @action(detail=False, methods=["get"], url_path=r"get_image_s3/(?P[^/.]+)") def get_image_s3(self, request, file_id): s3 = boto3.client( service_name="s3", endpoint_url="https://s3.ru-1.storage.selcloud.ru", aws_access_key_id=settings.SELECTEL["access"], aws_secret_access_key=settings.SELECTEL["secret"], ) get_object_response = s3.get_object(Bucket="inventorization", Key=file_id) image = get_object_response["Body"].read() response = HttpResponse(image, content_type="image/jpeg") response["Content-Disposition"] = 'inline; filename="image.jpeg"' return response class TmcStatViewset(viewsets.ViewSet): queryset = TgItem.objects.filter(is_check=True).order_by("-created_at") http_method_names = ["get"] def list(self, request): if 'type' in request.query_params and request.query_params['type'] == 'location': queryset = ( TgItem.objects.filter(is_check=True) .values("location__parent") .annotate( inv_count=Count("location__parent"), tmc_count=Count("tmc__tmc_id", distinct=True) ) .annotate( tmc=ArrayAgg("tmc"), ) ) else: queryset = ( TgItem.objects.all() .values("tmc__tmc_id") .annotate( inv_count=Count("location__parent"), tmc_count=Count("id", distinct=True) ) .annotate( location__parent=ArrayAgg("location__parent"), tmc=ArrayAgg("tmc"), ) ) # logger.info(queryset) # logger.info(TgItem.objects.all().values()) serializer = TgStatItemSerializer(queryset, many=True) return Response(serializer.data)