from rest_framework import viewsets from rest_framework.response import Response from rest_framework.decorators import action from rest_framework.filters import OrderingFilter from django_filters.rest_framework import DjangoFilterBackend from django.db import connection from api import models, serializers from django.http import JsonResponse from os import getenv import redis import json import logging class LineaViewSet(viewsets.ModelViewSet): queryset = models.Linea.objects.all() serializer_class = serializers.LineaSerializer filter_backends = [DjangoFilterBackend, OrderingFilter] filterset_fields = ['id_operador', 'route_short_name', 'route_long_name', 'vigente'] ordering_fields = '__all__' @action(detail=False, methods=['get']) def proto(self, request, pk=None): id_paradero = request.GET['id_paradero'] query = "SELECT json_data \ from gtfs_posiciones_json \ where stop_id = %s" with connection.cursor() as cursor: cursor.execute(query, [ id_paradero ]) row = cursor.fetchone() return JsonResponse(row[0], safe=False) @action(detail=False, methods=['get']) def paraderos(self, request, pk=None): pk = request.GET['id_linea'] paraderos = models.Paradero.objects \ .filter(vigente=True, lineaparadero__id_linea=pk) \ .values('id_paradero','stop_lat','stop_lon','stop_name') \ .all() return JsonResponse(list(paraderos), safe=False) # @action(detail=False, methods=['get']) def ___buses(self, request, pk=None): pk = request.GET['id_linea'] # 1. obtener todas los paraderos de redis # 2. consultar en cada paradero si hay una linea que corresponda a la consultada # 3. si existe se agrega el vehiculo db_host = getenv('DB_REDIS_HOST') db_port = getenv('DB_REDIS_PORT') r = redis.Redis(host=db_host, port=db_port, decode_responses=True) fileproto = r.get('fileproto') paraderos_redis = r.keys('stop_id:*') object_buses = {} for key_paradero in paraderos_redis: string_trayectos = r.get(key_paradero) array_trayectos = json.loads(string_trayectos) for trayecto in array_trayectos: patente = trayecto['vehicle_license_plate'] id_linea = f"{trayecto['route_id']}-{trayecto['direction_id']}" if id_linea == pk and key_paradero == 'stop_id:none': print(trayecto, flush=True) object_buses[patente] = { 'Patente_vehiculo': trayecto["vehicle_license_plate"], 'latitude': trayecto["latitude"], 'longitude': trayecto["longitude"], 'speed': trayecto["speed"] } if id_linea == pk and patente not in object_buses: object_buses[patente] = { 'Patente_vehiculo': trayecto["vehicle_license_plate"], 'latitude': trayecto["latitude"], 'longitude': trayecto["longitude"], 'speed': trayecto["speed"] } array_buses = [] for patente in object_buses: array_buses.append(object_buses[patente]) return Response({ 'fileproto': fileproto, 'buses': array_buses }) @action(detail=False, methods=['get']) def buses(self, request, pk=None): pk = request.GET['id_linea'] db_host = getenv('DB_REDIS_HOST') db_port = getenv('DB_REDIS_PORT') r = redis.Redis(host=db_host, port=db_port, decode_responses=True) paraderos = models.Paradero.objects \ .filter(vigente=True, lineaparadero__id_linea=pk) \ .values('id_paradero') \ .all() fileproto = r.get('fileproto') obj_buses = {} array_buses = [] for p in paraderos: key = f'stop_id:{p["id_paradero"]}' data = r.get(key) if data != None: array_trayectos = json.loads(data) for trayecto in array_trayectos: key_route = f'{trayecto["route_id"]}-{trayecto["direction_id"]}' if key_route == pk: patente = trayecto["vehicle_license_plate"] if patente not in obj_buses: obj_buses[patente] = { 'Patente_vehiculo': trayecto["vehicle_license_plate"], 'latitude': trayecto["latitude"], 'longitude': trayecto["longitude"], 'speed': trayecto["speed"] } key = f'stop_id:none' data = r.get(key) if data != None: array_trayectos = json.loads(data) for trayecto in array_trayectos: key_route = f'{trayecto["route_id"]}-{trayecto["direction_id"]}' if key_route == pk: patente = trayecto["vehicle_license_plate"] if (patente not in obj_buses) or (patente in obj_buses and obj_buses[patente]['longitude'] == 0 and obj_buses[patente]['latitude'] == 0): obj_buses[patente] = { 'Patente_vehiculo': trayecto["vehicle_license_plate"], 'latitude': trayecto["latitude"], 'longitude': trayecto["longitude"], 'speed': trayecto["speed"] } for patente in obj_buses: array_buses.append(obj_buses[patente]) return JsonResponse({ 'fileproto': fileproto, 'buses': array_buses }, safe=False) @action(detail=False, methods=['get']) def buses_proto(self, request, pk=None): pk = request.GET['id_linea'] linea = models.Linea.objects \ .filter(id_linea=pk) \ .first() detalle_buses = [] paraderos = models.Paradero.objects \ .filter(vigente=True, lineaparadero__id_linea=pk) \ .values('id_paradero') \ .all() query = "SELECT json_data \ from gtfs_posiciones_json \ where stop_id = %s" for p in paraderos: id_paradero = p['id_paradero'] with connection.cursor() as cursor: cursor.execute(query, [ id_paradero ]) datajson = cursor.fetchone() if datajson != None: buses = list(filter(lambda rowjson: rowjson['Descripcion'] == linea.route_short_name, datajson[0])) for bus in buses: for llegada in bus['Llegadas']: data_bus = { 'patente': llegada['patente'], 'estimada_gps': llegada['EstimadaGPS'], 'distancia_gps': llegada['DistanciaGPS'], } detalle_buses.append(data_bus) return JsonResponse(detalle_buses, safe=False) @action(detail=False, methods=['get']) def count(self, request, pk=None): queryset = models.Linea.objects.all() if 'vigente' in request.GET and request.GET['vigente'] == '1': queryset = queryset.filter(vigente=True) if 'vigente' in request.GET and request.GET['vigente'] == '0': queryset = queryset.filter(vigente=False) return JsonResponse({ 'count': queryset.count() }) @action(detail=False, methods=['get']) def count_buses(self, request, pk=None): query = "SELECT \ l.route_short_name, \ (select count(distinct vehicle_license_plate) \ from gtfs_posiciones as gp \ where (trim(gp.route_id)||'-'||trim(gp.direction_id::varchar)) = l.id_linea \ ) as count \ from linea l \ where \ (select count(distinct vehicle_license_plate) from gtfs_posiciones as gp where \ (trim(gp.route_id)||'-'||trim(gp.direction_id::varchar)) = l.id_linea)>0" with connection.cursor() as cursor: cursor.execute(query) result = cursor.fetchall() data = [] for row in result: data.append({ 'route_short_name': row[0], 'count': row[1] }) return JsonResponse(data, safe=False) @action(detail=False, methods=['get']) def count_buses_recorridos(self, request, pk=None): query = "select count(distinct vehicle_license_plate) from gtfs_posiciones" with connection.cursor() as cursor: cursor.execute(query) result = cursor.fetchone() return JsonResponse({ 'count': result[0] })