mirror of https://github.com/interlegis/sigi.git
Sesóstris Vieira
10 months ago
15 changed files with 574 additions and 12 deletions
@ -0,0 +1,90 @@ |
|||
from django_extensions.management.jobs import BaseJob |
|||
from django_extensions.management.jobs import get_jobs |
|||
from django.utils import timezone |
|||
from django.utils.formats import localize |
|||
from django.utils.translation import gettext as _ |
|||
from sigi.apps.utils.models import Cronjob, JobSchedule |
|||
|
|||
WHEN_SETS = { |
|||
"daily": "0 0 * * *", |
|||
"hourly": "0 * * * *", |
|||
"monthly": "0 0 1 * *", |
|||
"weekly": "0 0 * * 0", |
|||
"yearly": "0 0 1 1 *", |
|||
"minutely": "* * * * *", |
|||
} |
|||
|
|||
|
|||
class Job(BaseJob): |
|||
help = "Controlador de cronjobs do SIGI." |
|||
|
|||
def execute(self): |
|||
print("Rodando controlador de jobs...") |
|||
self.remove_old_jobs() |
|||
self.sync_new_jobs() |
|||
self.run_scheduled() |
|||
self.schedule_jobs() |
|||
|
|||
def remove_old_jobs(self): |
|||
"""Remover das tabelas os jobs que foram removidos do código""" |
|||
print("\tRemover das tabelas os jobs que foram removidos do código...") |
|||
all_jobs = get_jobs() |
|||
excludes = Cronjob.objects.all() |
|||
for app_name, job_name in all_jobs.keys(): |
|||
excludes = excludes.exclude(app_name=app_name, job_name=job_name) |
|||
print("\t\t", excludes.delete()) |
|||
|
|||
def sync_new_jobs(self): |
|||
""" |
|||
Atualizar a tabela de JOBS com os novos JOBS que tenham sido criados |
|||
""" |
|||
print( |
|||
"\tAtualizar a tabela de JOBS com os novos JOBS que tenham " |
|||
"sido criados..." |
|||
) |
|||
all_jobs = get_jobs() |
|||
for (app_name, job_name), JobClass in all_jobs.items(): |
|||
if app_name == "sigi.apps.utils" and job_name == "job_controller": |
|||
# Ignorar job_controller |
|||
continue |
|||
try: |
|||
job = Cronjob.objects.get(app_name=app_name, job_name=job_name) |
|||
except Cronjob.DoesNotExist: |
|||
# Inserir o JOB na tabela de JOBS # |
|||
job_obj = JobClass() |
|||
if job_obj.when in WHEN_SETS: |
|||
expressao_cron = WHEN_SETS[job_obj.when] |
|||
else: |
|||
expressao_cron = WHEN_SETS["daily"] # Default |
|||
job = Cronjob( |
|||
app_name=app_name, |
|||
job_name=job_name, |
|||
expressao_cron=expressao_cron, |
|||
) |
|||
job.save() |
|||
print(f"\t\tNovo job encontrado: {job_name}: {job_obj.help}") |
|||
|
|||
def run_scheduled(self): |
|||
"""Executa os jobs que estão agendados""" |
|||
print("\tExecutar os jobs que estão agendados...") |
|||
for sched in JobSchedule.objects.filter( |
|||
status=JobSchedule.STATUS_AGENDADO |
|||
): |
|||
agora = timezone.localtime() |
|||
if sched.iniciar <= agora: |
|||
sched.run_job() |
|||
|
|||
def schedule_jobs(self): |
|||
"""Criar agenda para próxima execução""" |
|||
print("\tCriar agenda para próxima execução...") |
|||
for job in Cronjob.objects.exclude( |
|||
jobschedule__status__in=[ |
|||
JobSchedule.STATUS_AGENDADO, |
|||
JobSchedule.STATUS_EXECUTANDO, |
|||
] |
|||
): |
|||
sched = job.next_schedule() |
|||
print( |
|||
f"\t\tAgendado job {sched.job.job_name} " |
|||
f"para {localize(sched.iniciar)}" |
|||
) |
@ -0,0 +1,45 @@ |
|||
# Generated by Django 4.2.7 on 2024-02-26 12:53 |
|||
|
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('utils', '0001_initial'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.CreateModel( |
|||
name='Cronjob', |
|||
fields=[ |
|||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('app_name', models.CharField(editable=False, max_length=100, verbose_name='app')), |
|||
('job_name', models.CharField(editable=False, max_length=100, verbose_name='job')), |
|||
('expressao_cron', models.CharField(default='* * * * *', help_text="Usar expressoões no formato padrão de CRON: 'minute hour day month day-of-week'. Mais detalhes: <a href='https://help.ubuntu.com/community/CronHowto'>CronHowTo</a>", max_length=100, verbose_name='expressão CRON')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Cron job', |
|||
'verbose_name_plural': 'Cron jobs', |
|||
'ordering': ('app_name', 'job_name'), |
|||
}, |
|||
), |
|||
migrations.CreateModel( |
|||
name='JobSchedule', |
|||
fields=[ |
|||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('iniciar', models.DateTimeField(verbose_name='Iniciar em')), |
|||
('iniciado', models.DateTimeField(blank=True, null=True, verbose_name='Iniciado em')), |
|||
('status', models.CharField(choices=[('A', 'Agendado'), ('E', 'Executando'), ('C', 'Concluído')], default='A', max_length=1, verbose_name='estado')), |
|||
('tempo_gasto', models.DurationField(blank=True, editable=False, null=True, verbose_name='tempo gasto')), |
|||
('resultado', models.TextField(blank=True, editable=False, verbose_name='resultado da execução')), |
|||
('job', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='utils.cronjob', verbose_name='Cron job')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Agenda de execução', |
|||
'verbose_name_plural': 'Agenda de execuções', |
|||
'ordering': ('iniciar',), |
|||
}, |
|||
), |
|||
] |
@ -0,0 +1,33 @@ |
|||
{% extends "admin/change_form.html" %} |
|||
{% load static i18n %} |
|||
|
|||
{% block extrastyle %} |
|||
{{ block.super }} |
|||
<style type="text/css"> |
|||
.display { |
|||
flex: 1; |
|||
} |
|||
h1 { |
|||
font-size: 2.5rem; |
|||
} |
|||
h2 { |
|||
font-size: 2rem; |
|||
} |
|||
h3 { |
|||
font-size: 1.5rem; |
|||
} |
|||
</style> |
|||
{% endblock %} |
|||
|
|||
{% block after_field_sets %} |
|||
<fieldset class="module aligned "> |
|||
<div class="form-row field-resultado"> |
|||
<div class="input-field"> |
|||
<div class="readonly-label"><label>Resultado:</label></div> |
|||
<div class="readonly"> |
|||
<pre>{{ original.resultado }}</pre> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</fieldset> |
|||
{% endblock %} |
Loading…
Reference in new issue