|
@ -1,7 +1,6 @@ |
|
|
import io |
|
|
import io |
|
|
from contextlib import redirect_stderr, redirect_stdout |
|
|
from contextlib import redirect_stderr, redirect_stdout |
|
|
from cron_converter import Cron |
|
|
from cron_converter import Cron |
|
|
from pyexpat import model |
|
|
|
|
|
from django.db import models |
|
|
from django.db import models |
|
|
from django.contrib.auth.models import Group |
|
|
from django.contrib.auth.models import Group |
|
|
from django.utils import timezone |
|
|
from django.utils import timezone |
|
@ -72,12 +71,14 @@ class Cronjob(models.Model): |
|
|
), |
|
|
), |
|
|
default=30, |
|
|
default=30, |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
destinatario_email = models.TextField( |
|
|
destinatario_email = models.TextField( |
|
|
_("destinatário(s) de e-mail"), |
|
|
_("destinatário(s) de e-mail"), |
|
|
help_text=_("Insira um endereço de e-mail por linha."), |
|
|
help_text=_("Insira um endereço de e-mail por linha."), |
|
|
blank=True, |
|
|
blank=True, |
|
|
) |
|
|
) |
|
|
|
|
|
last_digest = models.DateTimeField( |
|
|
|
|
|
_("último envio de digest"), blank=True, null=True |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
def get_emails_list(self): |
|
|
def get_emails_list(self): |
|
|
return [ |
|
|
return [ |
|
@ -86,9 +87,6 @@ class Cronjob(models.Model): |
|
|
if email.strip() |
|
|
if email.strip() |
|
|
] |
|
|
] |
|
|
|
|
|
|
|
|
def __str__(self): |
|
|
|
|
|
return f"Destinatários: {', '.join(self.get_emails_list())}" |
|
|
|
|
|
|
|
|
|
|
|
class Meta: |
|
|
class Meta: |
|
|
ordering = ("app_name", "job_name") |
|
|
ordering = ("app_name", "job_name") |
|
|
verbose_name = _("Cron job") |
|
|
verbose_name = _("Cron job") |
|
@ -177,7 +175,6 @@ class JobSchedule(models.Model): |
|
|
resultado = models.TextField( |
|
|
resultado = models.TextField( |
|
|
_("resultado da execução"), blank=True, editable=False |
|
|
_("resultado da execução"), blank=True, editable=False |
|
|
) |
|
|
) |
|
|
enviado = models.BooleanField(_("enviado"), default=False) |
|
|
|
|
|
|
|
|
|
|
|
class Meta: |
|
|
class Meta: |
|
|
ordering = ("-iniciar",) |
|
|
ordering = ("-iniciar",) |
|
@ -224,7 +221,10 @@ class JobSchedule(models.Model): |
|
|
if self.job.destinatario_email == "": |
|
|
if self.job.destinatario_email == "": |
|
|
return |
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
now = timezone.localtime() |
|
|
|
|
|
|
|
|
if self.job.digest == "N": |
|
|
if self.job.digest == "N": |
|
|
|
|
|
# Envia imediatamente sem acumular |
|
|
send_mail( |
|
|
send_mail( |
|
|
subject=f"JOB: {self.job.job_name}", |
|
|
subject=f"JOB: {self.job.job_name}", |
|
|
message=self.resultado, |
|
|
message=self.resultado, |
|
@ -233,47 +233,47 @@ class JobSchedule(models.Model): |
|
|
fail_silently=True, |
|
|
fail_silently=True, |
|
|
html_message=self.resultado, |
|
|
html_message=self.resultado, |
|
|
) |
|
|
) |
|
|
self.enviado = True |
|
|
self.job.last_digest = now |
|
|
self.save() |
|
|
self.job.save() |
|
|
|
|
|
|
|
|
elif self.job.digest == "D": |
|
|
|
|
|
self.send_digest_email(frequency="daily") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else: |
|
|
|
|
|
# Determina o período de digest |
|
|
|
|
|
if self.job.digest == "D": |
|
|
|
|
|
period = timedelta(days=1) |
|
|
elif self.job.digest == "S": |
|
|
elif self.job.digest == "S": |
|
|
self.send_digest_email(frequency="weekly") |
|
|
period = timedelta(weeks=1) |
|
|
|
|
|
else: |
|
|
|
|
|
raise ValueError( |
|
|
|
|
|
f"Valor inválido para digest: {self.job.digest}" |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
# Se o período foi atingido desde o último digest, envia |
|
|
|
|
|
if ( |
|
|
|
|
|
not self.job.last_digest |
|
|
|
|
|
or now >= self.job.last_digest + period |
|
|
|
|
|
): |
|
|
|
|
|
self.send_digest_email(frequency=self.job.digest) |
|
|
|
|
|
self.job.last_digest = now |
|
|
|
|
|
self.job.save() |
|
|
|
|
|
|
|
|
def send_digest_email(self, frequency): |
|
|
def send_digest_email(self, frequency): |
|
|
"""Envia email de digest diário ou semanal.""" |
|
|
"""Envia email de digest acumulando jobs desde o último digest.""" |
|
|
now = timezone.localtime() |
|
|
now = timezone.localtime() |
|
|
|
|
|
|
|
|
# Definir horário estático |
|
|
# Determina o período de acumulação baseado no último digest |
|
|
send_time = timezone.datetime.min.time() # Meia-noite |
|
|
if self.job.last_digest: |
|
|
today = now.date() |
|
|
period_start = self.job.last_digest |
|
|
|
|
|
|
|
|
if frequency == "daily": |
|
|
|
|
|
# Verifica se é meia-noite |
|
|
|
|
|
if now.time() != send_time: |
|
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
# Definir início do período como o dia anterior |
|
|
|
|
|
period_start = today - timedelta(days=1) |
|
|
|
|
|
|
|
|
|
|
|
elif frequency == "weekly": |
|
|
|
|
|
# Verifica se é segunda-feira e se é meia-noite |
|
|
|
|
|
if today.weekday() != 0 or now.time() != send_time: |
|
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
# Define o início do período como segunda-feira da semana passada |
|
|
|
|
|
period_start = today - timedelta(days=7) |
|
|
|
|
|
|
|
|
|
|
|
else: |
|
|
else: |
|
|
raise ValueError("Invalid frequency for digest email.") |
|
|
period_start = ( |
|
|
|
|
|
now - timedelta(days=1) |
|
|
|
|
|
if frequency == "D" |
|
|
|
|
|
else now - timedelta(weeks=1) |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
job_schedules = JobSchedule.objects.filter( |
|
|
job_schedules = JobSchedule.objects.filter( |
|
|
job=self.job, |
|
|
job=self.job, |
|
|
status=JobSchedule.STATUS_CONCLUIDO, |
|
|
status=JobSchedule.STATUS_CONCLUIDO, |
|
|
iniciado__gte=period_start, |
|
|
iniciado__gte=period_start, |
|
|
enviado=False, |
|
|
|
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
if job_schedules.exists(): |
|
|
if job_schedules.exists(): |
|
@ -293,8 +293,6 @@ class JobSchedule(models.Model): |
|
|
html_message=message, |
|
|
html_message=message, |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
job_schedules.update(enviado=True) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Config(models.Model): |
|
|
class Config(models.Model): |
|
|
PARAMETRO_CHOICES = ( |
|
|
PARAMETRO_CHOICES = ( |
|
|