feat: add management commands to initialize and run scheduled tasks
This commit is contained in:
parent
d3484e626d
commit
6fb2e00a54
2 changed files with 48 additions and 13 deletions
|
|
@ -24,7 +24,7 @@ class Command(BaseCommand):
|
||||||
exports_dir = os.path.join('exports')
|
exports_dir = os.path.join('exports')
|
||||||
if not os.path.exists(exports_dir):
|
if not os.path.exists(exports_dir):
|
||||||
os.makedirs(exports_dir)
|
os.makedirs(exports_dir)
|
||||||
self.stdout.write(self.style.SUCCESS(f'✓ Répertoire créé: {exports_dir}'))
|
self.stdout.write(self.style.SUCCESS(f'[OK] Répertoire créé: {exports_dir}'))
|
||||||
|
|
||||||
# 1. Tâche d'export mensuel des interventions
|
# 1. Tâche d'export mensuel des interventions
|
||||||
task_name = "Export mensuel des interventions"
|
task_name = "Export mensuel des interventions"
|
||||||
|
|
@ -62,7 +62,7 @@ interventions_export_YYYY_MM.xlsx
|
||||||
task.next_run = task.calculate_next_run()
|
task.next_run = task.calculate_next_run()
|
||||||
task.save()
|
task.save()
|
||||||
|
|
||||||
self.stdout.write(self.style.SUCCESS(f'\n✓ Tâche créée: {task_name}'))
|
self.stdout.write(self.style.SUCCESS(f'\n[OK] Tâche créée: {task_name}'))
|
||||||
self.stdout.write(f' - Fréquence: {task.get_frequency_display()}')
|
self.stdout.write(f' - Fréquence: {task.get_frequency_display()}')
|
||||||
self.stdout.write(f' - Planning: Le {task.day_of_month} de chaque mois à {task.hour:02d}:{task.minute:02d}')
|
self.stdout.write(f' - Planning: Le {task.day_of_month} de chaque mois à {task.hour:02d}:{task.minute:02d}')
|
||||||
self.stdout.write(f' - Prochaine exécution: {task.next_run.strftime("%Y-%m-%d %H:%M")}')
|
self.stdout.write(f' - Prochaine exécution: {task.next_run.strftime("%Y-%m-%d %H:%M")}')
|
||||||
|
|
@ -111,7 +111,7 @@ Données conservées dans le résumé:
|
||||||
task2.next_run = task2.calculate_next_run()
|
task2.next_run = task2.calculate_next_run()
|
||||||
task2.save()
|
task2.save()
|
||||||
|
|
||||||
self.stdout.write(self.style.SUCCESS(f'\n✓ Tâche créée: {task_name_analytics}'))
|
self.stdout.write(self.style.SUCCESS(f'\n[OK] Tâche créée: {task_name_analytics}'))
|
||||||
self.stdout.write(f' - Fréquence: {task2.get_frequency_display()}')
|
self.stdout.write(f' - Fréquence: {task2.get_frequency_display()}')
|
||||||
self.stdout.write(f' - Planning: Tous les jours à {task2.hour:02d}:{task2.minute:02d}')
|
self.stdout.write(f' - Planning: Tous les jours à {task2.hour:02d}:{task2.minute:02d}')
|
||||||
self.stdout.write(f' - Prochaine exécution: {task2.next_run.strftime("%Y-%m-%d %H:%M")}')
|
self.stdout.write(f' - Prochaine exécution: {task2.next_run.strftime("%Y-%m-%d %H:%M")}')
|
||||||
|
|
@ -158,7 +158,7 @@ Arguments disponibles :
|
||||||
task3.next_run = task3.calculate_next_run()
|
task3.next_run = task3.calculate_next_run()
|
||||||
task3.save()
|
task3.save()
|
||||||
|
|
||||||
self.stdout.write(self.style.SUCCESS(f'\n✓ Tâche créée: {task_name_daily}'))
|
self.stdout.write(self.style.SUCCESS(f'\n[OK] Tâche créée: {task_name_daily}'))
|
||||||
self.stdout.write(f' - Fréquence: {task3.get_frequency_display()}')
|
self.stdout.write(f' - Fréquence: {task3.get_frequency_display()}')
|
||||||
self.stdout.write(f' - Planning: Tous les jours à {task3.hour:02d}:{task3.minute:02d}')
|
self.stdout.write(f' - Planning: Tous les jours à {task3.hour:02d}:{task3.minute:02d}')
|
||||||
self.stdout.write(f' - Statut: {"Active" if task3.is_active else "Inactive (à activer si nécessaire)"}')
|
self.stdout.write(f' - Statut: {"Active" if task3.is_active else "Inactive (à activer si nécessaire)"}')
|
||||||
|
|
@ -200,7 +200,7 @@ Arguments disponibles :
|
||||||
task4.next_run = task4.calculate_next_run()
|
task4.next_run = task4.calculate_next_run()
|
||||||
task4.save()
|
task4.save()
|
||||||
|
|
||||||
self.stdout.write(self.style.SUCCESS(f'\n✓ Tâche créée: {task_name_reporting}'))
|
self.stdout.write(self.style.SUCCESS(f'\n[OK] Tâche créée: {task_name_reporting}'))
|
||||||
self.stdout.write(f' - Fréquence: {task4.get_frequency_display()}')
|
self.stdout.write(f' - Fréquence: {task4.get_frequency_display()}')
|
||||||
self.stdout.write(f' - Planning: Tous les jours à {task4.hour:02d}:{task4.minute:02d}')
|
self.stdout.write(f' - Planning: Tous les jours à {task4.hour:02d}:{task4.minute:02d}')
|
||||||
self.stdout.write(f' - Prochaine exécution: {task4.next_run.strftime("%Y-%m-%d %H:%M")}')
|
self.stdout.write(f' - Prochaine exécution: {task4.next_run.strftime("%Y-%m-%d %H:%M")}')
|
||||||
|
|
@ -237,7 +237,7 @@ Les observations liées sont également clôturées.
|
||||||
task5.next_run = task5.calculate_next_run()
|
task5.next_run = task5.calculate_next_run()
|
||||||
task5.save()
|
task5.save()
|
||||||
|
|
||||||
self.stdout.write(self.style.SUCCESS(f'\n✓ Tâche créée: {task_name_auto_close}'))
|
self.stdout.write(self.style.SUCCESS(f'\n[OK] Tâche créée: {task_name_auto_close}'))
|
||||||
self.stdout.write(f' - Fréquence: {task5.get_frequency_display()}')
|
self.stdout.write(f' - Fréquence: {task5.get_frequency_display()}')
|
||||||
self.stdout.write(f' - Planning: Tous les jours à {task5.hour:02d}:{task5.minute:02d}')
|
self.stdout.write(f' - Planning: Tous les jours à {task5.hour:02d}:{task5.minute:02d}')
|
||||||
self.stdout.write(f' - Prochaine exécution: {task5.next_run.strftime("%Y-%m-%d %H:%M")}')
|
self.stdout.write(f' - Prochaine exécution: {task5.next_run.strftime("%Y-%m-%d %H:%M")}')
|
||||||
|
|
@ -280,7 +280,7 @@ Elle effectue les actions suivantes :
|
||||||
task6.next_run = task6.calculate_next_run()
|
task6.next_run = task6.calculate_next_run()
|
||||||
task6.save()
|
task6.save()
|
||||||
|
|
||||||
self.stdout.write(self.style.SUCCESS(f'\n✓ Tâche créée: {task_name_backup}'))
|
self.stdout.write(self.style.SUCCESS(f'\n[OK] Tâche créée: {task_name_backup}'))
|
||||||
self.stdout.write(f' - Fréquence: {task6.get_frequency_display()}')
|
self.stdout.write(f' - Fréquence: {task6.get_frequency_display()}')
|
||||||
self.stdout.write(f' - Planning: Tous les jours à {task6.hour:02d}:{task6.minute:02d}')
|
self.stdout.write(f' - Planning: Tous les jours à {task6.hour:02d}:{task6.minute:02d}')
|
||||||
self.stdout.write(f' - Prochaine exécution: {task6.next_run.strftime("%Y-%m-%d %H:%M")}')
|
self.stdout.write(f' - Prochaine exécution: {task6.next_run.strftime("%Y-%m-%d %H:%M")}')
|
||||||
|
|
@ -290,6 +290,41 @@ Elle effectue les actions suivantes :
|
||||||
if task6.next_run:
|
if task6.next_run:
|
||||||
self.stdout.write(f' - Prochaine exécution: {task6.next_run.strftime("%Y-%m-%d %H:%M")}')
|
self.stdout.write(f' - Prochaine exécution: {task6.next_run.strftime("%Y-%m-%d %H:%M")}')
|
||||||
|
|
||||||
|
# 7. Rappel par e-mail des notifications non lues
|
||||||
|
task_name_notif_reminders = "Rappels des notifications non lues"
|
||||||
|
|
||||||
|
task7, created7 = ScheduledCommand.objects.get_or_create(
|
||||||
|
name=task_name_notif_reminders,
|
||||||
|
defaults={
|
||||||
|
'command_name': 'send_unread_notification_reminders',
|
||||||
|
'command_args': {},
|
||||||
|
'frequency': 'hourly',
|
||||||
|
'minute': 0,
|
||||||
|
'is_active': True,
|
||||||
|
'send_email': False,
|
||||||
|
'description': '''
|
||||||
|
Envoie un e-mail de rappel aux utilisateurs ayant activé l'option et ayant des notifications non lues depuis plus que le délai configuré.
|
||||||
|
|
||||||
|
La tâche s'exécute toutes les heures.
|
||||||
|
Chaque utilisateur configure son délai et ses préférences dans la page /notifications/settings/.
|
||||||
|
'''.strip()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if created7:
|
||||||
|
task7.next_run = task7.calculate_next_run()
|
||||||
|
task7.save()
|
||||||
|
|
||||||
|
self.stdout.write(self.style.SUCCESS(f'\n[OK] Tâche créée: {task_name_notif_reminders}'))
|
||||||
|
self.stdout.write(f' - Fréquence: {task7.get_frequency_display()}')
|
||||||
|
self.stdout.write(f' - Planning: Toutes les heures à :00')
|
||||||
|
self.stdout.write(f' - Prochaine exécution: {task7.next_run.strftime("%Y-%m-%d %H:%M")}')
|
||||||
|
else:
|
||||||
|
self.stdout.write(self.style.WARNING(f'\n! Tâche déjà existante: {task_name_notif_reminders}'))
|
||||||
|
self.stdout.write(f' - Statut: {"Active" if task7.is_active else "Inactive"}')
|
||||||
|
if task7.next_run:
|
||||||
|
self.stdout.write(f' - Prochaine exécution: {task7.next_run.strftime("%Y-%m-%d %H:%M")}')
|
||||||
|
|
||||||
self.stdout.write(self.style.SUCCESS('\n=== Initialisation terminée ==='))
|
self.stdout.write(self.style.SUCCESS('\n=== Initialisation terminée ==='))
|
||||||
self.stdout.write('\nPour gérer les tâches planifiées:')
|
self.stdout.write('\nPour gérer les tâches planifiées:')
|
||||||
self.stdout.write(' 1. Accédez à l\'admin Django: /admin/')
|
self.stdout.write(' 1. Accédez à l\'admin Django: /admin/')
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ class Command(BaseCommand):
|
||||||
for task in tasks:
|
for task in tasks:
|
||||||
if task.should_run_now():
|
if task.should_run_now():
|
||||||
tasks_to_run.append(task)
|
tasks_to_run.append(task)
|
||||||
self.stdout.write(self.style.SUCCESS(f' ✓ {task.name} doit être exécutée'))
|
self.stdout.write(self.style.SUCCESS(f' [OK] {task.name} doit être exécutée'))
|
||||||
else:
|
else:
|
||||||
next_run = task.next_run.strftime('%Y-%m-%d %H:%M') if task.next_run else 'Non planifiée'
|
next_run = task.next_run.strftime('%Y-%m-%d %H:%M') if task.next_run else 'Non planifiée'
|
||||||
self.stdout.write(f' - {task.name} : prochaine exécution le {next_run}')
|
self.stdout.write(f' - {task.name} : prochaine exécution le {next_run}')
|
||||||
|
|
@ -101,7 +101,7 @@ class Command(BaseCommand):
|
||||||
task.next_run = task.calculate_next_run()
|
task.next_run = task.calculate_next_run()
|
||||||
task.save()
|
task.save()
|
||||||
|
|
||||||
self.stdout.write(self.style.SUCCESS(f' ✓ Succès (durée: {log.duration_seconds:.1f}s)'))
|
self.stdout.write(self.style.SUCCESS(f' [OK] Succès (durée: {log.duration_seconds:.1f}s)'))
|
||||||
|
|
||||||
# Envoyer l'email si configuré
|
# Envoyer l'email si configuré
|
||||||
if task.send_email and task.email_recipients:
|
if task.send_email and task.email_recipients:
|
||||||
|
|
@ -125,7 +125,7 @@ class Command(BaseCommand):
|
||||||
task.next_run = task.calculate_next_run()
|
task.next_run = task.calculate_next_run()
|
||||||
task.save()
|
task.save()
|
||||||
|
|
||||||
self.stdout.write(self.style.ERROR(f' ✗ Erreur: {str(e)}'))
|
self.stdout.write(self.style.ERROR(f' [ERREUR] Erreur: {str(e)}'))
|
||||||
|
|
||||||
# Envoyer l'email d'erreur si configuré
|
# Envoyer l'email d'erreur si configuré
|
||||||
if task.send_email and task.email_recipients:
|
if task.send_email and task.email_recipients:
|
||||||
|
|
@ -175,17 +175,17 @@ StreetUp - Système de tâches planifiées
|
||||||
# Attacher le fichier si il existe
|
# Attacher le fichier si il existe
|
||||||
if output_file and os.path.exists(output_file):
|
if output_file and os.path.exists(output_file):
|
||||||
email.attach_file(output_file)
|
email.attach_file(output_file)
|
||||||
self.stdout.write(self.style.SUCCESS(f' ✓ Fichier attaché: {output_file}'))
|
self.stdout.write(self.style.SUCCESS(f' [OK] Fichier attaché: {output_file}'))
|
||||||
|
|
||||||
email.send(fail_silently=False)
|
email.send(fail_silently=False)
|
||||||
|
|
||||||
log.email_sent = True
|
log.email_sent = True
|
||||||
log.save(update_fields=['email_sent'])
|
log.save(update_fields=['email_sent'])
|
||||||
|
|
||||||
self.stdout.write(self.style.SUCCESS(f' ✓ Email envoyé à: {", ".join(recipients)}'))
|
self.stdout.write(self.style.SUCCESS(f' [OK] Email envoyé à: {", ".join(recipients)}'))
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.stdout.write(self.style.ERROR(f' ✗ Erreur lors de l\'envoi de l\'email: {str(e)}'))
|
self.stdout.write(self.style.ERROR(f' [ERREUR] Erreur lors de l\'envoi de l\'email: {str(e)}'))
|
||||||
|
|
||||||
def send_error_email(self, task, log):
|
def send_error_email(self, task, log):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue