Skip to content

Commit

Permalink
Merge pull request #15 from Grupo-Syntax-Squad/func/urls-alertas-5
Browse files Browse the repository at this point in the history
Func/urls alertas 5
  • Loading branch information
Gabriel4SS authored Sep 28, 2024
2 parents 40a82b4 + 1378f14 commit 321507e
Show file tree
Hide file tree
Showing 8 changed files with 256 additions and 15 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ python -m venv .venv
.\.venv\Scripts\activate
```
```sh
pip install -r .\requiments-dev.txt
pip install -r .\requirements-dev.txt
```
### Varáveis de ambiente

Expand Down
4 changes: 4 additions & 0 deletions src/tupan/alertas/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ class AlertaAdmin(admin.ModelAdmin):
"ativo",
"condicao",
]
readonly_fields = [
"criado",
"modificado"
]


@admin.register(HistoricoAlerta)
Expand Down
14 changes: 7 additions & 7 deletions src/tupan/alertas/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ class Meta:


class Alerta(Base):
nome = models.CharField(help_text="nome do alerta", max_length=127, unique=True)
condicao = models.CharField(help_text="condição para o alerta acontecer", max_length=4)
nome = models.CharField(help_text="Nome do alerta", max_length=127, unique=True)
condicao = models.CharField(help_text="Condição para o alerta acontecer", max_length=4)
ativo = models.BooleanField(default=True)
# falta a chave estrangeira da estacao_parametro

Expand All @@ -25,9 +25,9 @@ def __str__(self):


class HistoricoAlerta(Base):
timestamp = models.BigIntegerField(blank=False)
timestamp = models.BigIntegerField(help_text="Data/hora do alerta em timestamp" ,blank=False)
alerta = models.ForeignKey(Alerta, related_name="historico_alertas", on_delete=models.CASCADE)
timestamp_convertido = models.DateTimeField(blank=True, null=True)
timestamp_convertido = models.DateTimeField(help_text="Data/hora do alerta em datetime", blank=True, null=True)

class Meta:
verbose_name = "Histórico de Alerta"
Expand All @@ -39,9 +39,9 @@ def save(self, *args, **kwargs):


class Medicao(Base):
timestamp = models.BigIntegerField(blank=False)
timestamp_convertido = models.DateTimeField(blank=True, null=True)
dados = models.CharField(max_length=63, blank=False, null=False)
timestamp = models.BigIntegerField(help_text="Data/hora da medição em timestamp", blank=False)
timestamp_convertido = models.DateTimeField(help_text="Data/hora da medição em datetime", blank=True, null=True)
dados = models.CharField(help_text="Valor dos dados da medição", max_length=63, blank=False, null=False)
# Falta a chave estrangeira estacao_parametro

class Meta:
Expand Down
74 changes: 72 additions & 2 deletions src/tupan/alertas/tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,73 @@
from django.test import TestCase
import pytest
import json
from django.urls import reverse
from .models import Alerta, HistoricoAlerta

# Create your tests here.
@pytest.fixture
def alerta_auxiliar():
alerta = {
"nome": "Alerta1",
"condicao": "<2",
}
return alerta


class TestAlerta:
@pytest.mark.django_db
def teste_criar_alerta(self, alerta_auxiliar):
Alerta.objects.create(**alerta_auxiliar)

assert Alerta.objects.count() == 1
alerta_no_banco = Alerta.objects.first()

assert alerta_no_banco.pk == 1
assert alerta_no_banco.nome == alerta_auxiliar['nome']
assert alerta_no_banco.condicao == alerta_auxiliar['condicao']
assert alerta_no_banco.ativo == True

@pytest.mark.django_db
def teste_url_listar_alertas(self, client, alerta_auxiliar):
Alerta.objects.create(**alerta_auxiliar)

url = reverse("alertas")
response = client.get(url)

json_data = response.json()

assert response.status_code == 200
assert len(json_data) == 1
assert json_data[0]['nome'] == "Alerta1"
assert json_data[0]['condicao'] == "<2"

@pytest.mark.django_db
def teste_url_cadastrar_alerta(self, client, alerta_auxiliar):

url = reverse("alertas")
response = client.post(url, data=json.dumps(alerta_auxiliar), content_type="application/json")

json_data = response.json()
assert response.status_code == 201
assert json_data['nome'] == 'Alerta1'
assert json_data['ativo'] == True


class TestHistoricoAlerta:
@pytest.fixture
def historico_alerta_auxiliar(self, alerta_auxiliar):
alerta = Alerta.objects.create(**alerta_auxiliar)
hist = {
"timestamp": 1726067292,
"alerta": alerta
}
return hist

@pytest.mark.django_db
def teste_criar_historico(self, historico_alerta_auxiliar):
HistoricoAlerta.objects.create(**historico_alerta_auxiliar)

assert HistoricoAlerta.objects.count() == 1
historico_no_banco = HistoricoAlerta.objects.first()

assert historico_no_banco.pk == 1
assert historico_no_banco.timestamp == historico_alerta_auxiliar['timestamp']
assert historico_no_banco.alerta == historico_alerta_auxiliar['alerta']
10 changes: 10 additions & 0 deletions src/tupan/alertas/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from django.urls import path
from .views import AlertasView, AlertasDetalhesView, HistoricoAlertaView, MedicaoView, MedicaoDetalhesView

urlpatterns = [
path('', AlertasView.as_view(), name='alertas'),
path('<int:id>', AlertasDetalhesView.as_view(), name='alertas-detalhes'),
path('historicos', HistoricoAlertaView.as_view(), name='historico-alertas'),
path('medicoes', MedicaoView.as_view(), name='medicoes'),
path('medicoes/<int:id>', MedicaoDetalhesView.as_view(), name='medicoes-detalhes')
]
160 changes: 158 additions & 2 deletions src/tupan/alertas/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,159 @@
from django.shortcuts import render
from rest_framework.views import APIView
from django.http import JsonResponse
import json
from .models import Alerta, HistoricoAlerta, Medicao
from django.core.exceptions import ValidationError

# Create your views here.

class AlertasView(APIView):
def get(self, request, *args, **kwargs):
try:
# Obtém o valor do parâmetro 'ativo' da requisição, se disponível
ativo_param = request.GET.get('ativo', None)

if ativo_param is not None:
ativo_param = ativo_param.strip().lower()
if ativo_param == 'true':
ativo = True
alertas = Alerta.objects.filter(ativo=ativo).values()
elif ativo_param == 'false':
ativo = False
alertas = Alerta.objects.filter(ativo=ativo).values()
else:
raise ValidationError('Parâmetro inválido para "ativo".')
else:
alertas = Alerta.objects.all().values()

return JsonResponse(list(alertas), safe=False)

except ValidationError as ve:
return JsonResponse({'error': str(ve)}, status=400)

except Exception as e:
return JsonResponse({
'error': 'Erro ao buscar dados, tente novamente',
'data': f"{e}"
}, status=500)

def post(self, request, *args, **kwargs):
try:
data = json.loads(request.body)
nome = data.get('nome')
condicao = data.get('condicao')

if not nome or not condicao:
return JsonResponse({'error': 'Campos obrigatórios: nome, condicao'}, status=400)

alerta = Alerta(nome=nome, condicao=condicao)
alerta.save()

return JsonResponse({
'id': alerta.pk,
'nome': alerta.nome,
'condicao': alerta.condicao,
'ativo': alerta.ativo
}, status=201)

except json.JSONDecodeError:
return JsonResponse({'error': 'Dados inválidos'}, status=400)


class AlertasDetalhesView(APIView):
def get(self, request, id, *args, **kwargs):
try:
alerta = Alerta.objects.filter(id=id, ativo=True).values().first()
if alerta:
return JsonResponse(alerta, safe=False)
else:
return JsonResponse({'error': 'Alerta não encontrado ou inativo'}, status=404)
except:
return JsonResponse({'error': 'Erro ao buscar dados, tente novamente'}, status=500)

def put(self, request, id, *args, **kwargs):
try:
data = json.loads(request.body)
alerta = Alerta.objects.filter(id=id, ativo=True).first()
if alerta:
alerta.nome = data.get('nome', alerta.nome)
alerta.condicao = data.get('condicao', alerta.condicao)
alerta.save()
return JsonResponse({
'id': alerta.pk,
'nome': alerta.nome,
'condicao': alerta.condicao,
'ativo': alerta.ativo
}, status=200)
else:
return JsonResponse({'error': 'Alerta não encontrado ou inativo'}, status=404)
except json.JSONDecodeError:
return JsonResponse({'error': 'Dados inválidos'}, status=400)
except:
return JsonResponse({'error': 'Erro ao atualizar alerta, tente novamente'}, status=500)

def delete(self, request, id, *args, **kwargs):
try:
alerta = Alerta.objects.filter(id=id).first()
if alerta:
alerta.ativo = False
alerta.save()
return JsonResponse({'message': 'Alerta desativado com sucesso'}, status=200)
else:
return JsonResponse({'error': 'Alerta não encontrado'}, status=404)
except:
return JsonResponse({'error': 'Erro ao desativar alerta, tente novamente'}, status=500)


class HistoricoAlertaView(APIView):
def get(self, request, *args, **kwargs):
try:
historico = HistoricoAlerta.objects.get()
return JsonResponse(list(historico), safe=False)
except:
return JsonResponse({'error': 'Erro ao buscar dados, tente novamente'}, status=500)

def post(self, request, *args, **kwargs):
try:
data = json.loads(request.body)
timestamp = data.get('timestamp')
alerta_id = data.get('alerta')

if not timestamp or not alerta_id:
return JsonResponse({'error': 'Campos obrigatórios: timestamp, alerta'}, status=400)

alerta = Alerta.objects.get(pk=alerta_id)
hist = HistoricoAlerta(timestamp=timestamp, alerta=alerta)
hist.save()

return JsonResponse({
'id': hist.pk,
'timestamp': hist.timestamp,
'alerta': hist.alerta.pk,
'timestamp_convertido': hist.timestamp_convertido
}, status=201)
except Alerta.DoesNotExist:
return JsonResponse({'error': 'Alerta não encontrado'}, status=404)
except json.JSONDecodeError:
return JsonResponse({'error': 'Dados inválidos'}, status=400)
except Exception as e:
return JsonResponse({'error': f'Erro ao salvar histórico: {str(e)}'}, status=500)


class MedicaoView(APIView):
def get(self, request, *args, **kwargs):
try:
medicoes = Medicao.objects.get()
return JsonResponse(list(medicoes), safe=False)
except:
return JsonResponse({'error': 'Erro ao buscar dados, tente novamente'}, status=500)


class MedicaoDetalhesView(APIView):
def get(self, request, id, *args, **kwargs):
try:
alerta = Medicao.objects.filter(id=id, ativo=True).values().first()
if alerta:
return JsonResponse(alerta, safe=False)
else:
return JsonResponse({'error': 'Medição não encontrada ou inativa'}, status=404)
except:
return JsonResponse({'error': 'Erro ao buscar dados, tente novamente'}, status=500)
6 changes: 3 additions & 3 deletions src/tupan/tupan/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,13 @@
# Internationalization
# https://docs.djangoproject.com/en/5.1/topics/i18n/

LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'pt-br'

TIME_ZONE = 'UTC'
TIME_ZONE = 'America/Sao_Paulo'

USE_I18N = True

USE_TZ = True
USE_TZ = False


# Static files (CSS, JavaScript, Images)
Expand Down
1 change: 1 addition & 0 deletions src/tupan/tupan/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

urlpatterns = [
path('admin/', admin.site.urls),
path('alertas', include('alertas.urls')),
path('', include('estacoes.urls')),
path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
Expand Down

0 comments on commit 321507e

Please sign in to comment.