Browse Source

Merge pull request #178 from lucasmndc/master

Adição de digest email
pull/181/head
Sesostris Vieira 4 months ago
committed by GitHub
parent
commit
f34815de40
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 8
      sigi/apps/utils/admin.py
  2. 34
      sigi/apps/utils/management/jobs.py
  3. 41
      sigi/apps/utils/migrations/0005_cronjob_destinatario_email_cronjob_digest_and_more.py
  4. 24
      sigi/apps/utils/migrations/0006_remove_jobschedule_enviado_cronjob_last_digest.py
  5. 104
      sigi/apps/utils/models.py

8
sigi/apps/utils/admin.py

@ -65,6 +65,9 @@ class CronjobAdmin(admin.ModelAdmin):
"expressao_cron", "expressao_cron",
"get_schedule", "get_schedule",
"get_runner", "get_runner",
"destinatario_email",
"digest",
"last_digest",
) )
fields = [ fields = [
"job_name", "job_name",
@ -72,8 +75,11 @@ class CronjobAdmin(admin.ModelAdmin):
"get_help", "get_help",
"expressao_cron", "expressao_cron",
"manter_logs", "manter_logs",
"destinatario_email",
"digest",
"last_digest",
] ]
readonly_fields = ("job_name", "app_name", "get_help") readonly_fields = ("job_name", "app_name", "get_help", "last_digest")
inlines = [JobScheduleInline] inlines = [JobScheduleInline]
def get_urls(self): def get_urls(self):

34
sigi/apps/utils/management/jobs.py

@ -80,14 +80,14 @@ class JobReportMixin:
"output_encoding": "unicode", "output_encoding": "unicode",
}, },
) )
send_mail( # send_mail(
subject=f"JOB: {self.help}", # subject=f"JOB: {self.help}",
message=rst, # message=rst,
from_email=settings.SERVER_EMAIL, # from_email=settings.SERVER_EMAIL,
recipient_list=Config.get_param("EMAIL_JOBS"), # recipient_list=Config.get_param("EMAIL_JOBS"),
fail_silently=True, # fail_silently=True,
html_message=html, # html_message=html,
) # )
print(rst) print(rst)
def prepare_report(self, start_time, end_time): def prepare_report(self, start_time, end_time):
@ -128,13 +128,13 @@ class JobReportMixin:
rst, html = self.prepare_report(start_time, end_time) rst, html = self.prepare_report(start_time, end_time)
if self.send_report_mail: # if self.send_report_mail:
send_mail( # send_mail(
subject=f"JOB: {self.help}", # subject=f"JOB: {self.help}",
message=rst, # message=rst,
from_email=settings.SERVER_EMAIL, # from_email=settings.SERVER_EMAIL,
recipient_list=Config.get_param("EMAIL_JOBS"), # recipient_list=Config.get_param("EMAIL_JOBS"),
fail_silently=True, # fail_silently=True,
html_message=html, # html_message=html,
) # )
print(rst) print(rst)

41
sigi/apps/utils/migrations/0005_cronjob_destinatario_email_cronjob_digest_and_more.py

@ -0,0 +1,41 @@
# Generated by Django 5.0.6 on 2024-07-30 15:53
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("utils", "0004_alter_jobschedule_options_cronjob_manter_logs"),
]
operations = [
migrations.AddField(
model_name="cronjob",
name="destinatario_email",
field=models.TextField(
blank=True,
help_text="Insira um endereço de e-mail por linha.",
verbose_name="destinatário(s) de e-mail",
),
),
migrations.AddField(
model_name="cronjob",
name="digest",
field=models.CharField(
choices=[
("N", "Enviar sem digest"),
("D", "Enviar com digest diário"),
("S", "Enviar com digest semanal"),
],
default="N",
max_length=1,
verbose_name="digest",
),
),
migrations.AddField(
model_name="jobschedule",
name="enviado",
field=models.BooleanField(default=False, verbose_name="enviado"),
),
]

24
sigi/apps/utils/migrations/0006_remove_jobschedule_enviado_cronjob_last_digest.py

@ -0,0 +1,24 @@
# Generated by Django 5.0.6 on 2024-08-13 13:35
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("utils", "0005_cronjob_destinatario_email_cronjob_digest_and_more"),
]
operations = [
migrations.RemoveField(
model_name="jobschedule",
name="enviado",
),
migrations.AddField(
model_name="cronjob",
name="last_digest",
field=models.DateTimeField(
blank=True, null=True, verbose_name="último envio de digest"
),
),
]

104
sigi/apps/utils/models.py

@ -9,6 +9,9 @@ from django.utils.formats import localize
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django_extensions.management.jobs import get_job, get_jobs from django_extensions.management.jobs import get_job, get_jobs
from tinymce.models import HTMLField from tinymce.models import HTMLField
from django.core.mail import send_mail
from django.conf import settings
from datetime import timedelta
class SigiAlert(models.Model): class SigiAlert(models.Model):
@ -35,6 +38,17 @@ class SigiAlert(models.Model):
class Cronjob(models.Model): class Cronjob(models.Model):
DIGEST_CHOICES = [
("N", _("Enviar sem digest")),
("D", _("Enviar com digest diário")),
("S", _("Enviar com digest semanal")),
]
digest = models.CharField(
_("digest"),
max_length=1,
choices=DIGEST_CHOICES,
default="N",
)
app_name = models.CharField(_("app"), max_length=100, editable=False) app_name = models.CharField(_("app"), max_length=100, editable=False)
job_name = models.CharField(_("job"), max_length=100, editable=False) job_name = models.CharField(_("job"), max_length=100, editable=False)
expressao_cron = models.CharField( expressao_cron = models.CharField(
@ -58,6 +72,21 @@ class Cronjob(models.Model):
), ),
default=30, default=30,
) )
destinatario_email = models.TextField(
_("destinatário(s) de e-mail"),
help_text=_("Insira um endereço de e-mail por linha."),
blank=True,
)
last_digest = models.DateTimeField(
_("último envio de digest"), blank=True, null=True
)
def get_emails_list(self):
return [
email.strip()
for email in self.destinatario_email.splitlines()
if email.strip()
]
class Meta: class Meta:
ordering = ("app_name", "job_name") ordering = ("app_name", "job_name")
@ -190,6 +219,81 @@ class JobSchedule(models.Model):
self.tempo_gasto = timezone.localtime() - self.iniciado self.tempo_gasto = timezone.localtime() - self.iniciado
self.save() self.save()
if self.job.destinatario_email == "":
return
now = timezone.localtime()
if self.job.digest == "N":
# Envia imediatamente sem acumular
send_mail(
subject=f"JOB: {self.job.job_name}",
message=self.resultado,
from_email=settings.SERVER_EMAIL,
recipient_list=self.job.get_emails_list(),
fail_silently=True,
html_message=self.resultado,
)
self.job.last_digest = now
self.job.save()
else:
# Determina o período de digest
if self.job.digest == "D":
period = timedelta(days=1)
elif self.job.digest == "S":
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):
"""Envia email de digest acumulando jobs desde o último digest."""
now = timezone.localtime()
# Determina o período de acumulação baseado no último digest
if self.job.last_digest:
period_start = self.job.last_digest
else:
period_start = (
now - timedelta(days=1)
if frequency == "D"
else now - timedelta(weeks=1)
)
job_schedules = JobSchedule.objects.filter(
job=self.job,
status=JobSchedule.STATUS_CONCLUIDO,
iniciado__gte=period_start,
)
if job_schedules.exists():
message_lines = []
for js in job_schedules:
message_lines.append(
f"{localize(js.iniciado)}: {js.resultado}"
)
message = "\n\n".join(message_lines)
send_mail(
subject=f"Digest JOB: {self.job.job_name} ({frequency})",
message=message,
from_email=settings.SERVER_EMAIL,
recipient_list=self.job.get_emails_list(),
fail_silently=True,
html_message=message,
)
class Config(models.Model): class Config(models.Model):
PARAMETRO_CHOICES = ( PARAMETRO_CHOICES = (

Loading…
Cancel
Save