diff --git a/streetup/common/management/commands/init_scheduled_tasks.py b/streetup/common/management/commands/init_scheduled_tasks.py index 33511bb..db7e11f 100644 --- a/streetup/common/management/commands/init_scheduled_tasks.py +++ b/streetup/common/management/commands/init_scheduled_tasks.py @@ -24,7 +24,7 @@ class Command(BaseCommand): exports_dir = os.path.join('exports') if not os.path.exists(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 task_name = "Export mensuel des interventions" @@ -62,7 +62,7 @@ interventions_export_YYYY_MM.xlsx task.next_run = task.calculate_next_run() 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' - 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")}') @@ -111,7 +111,7 @@ Données conservées dans le résumé: task2.next_run = task2.calculate_next_run() 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' - 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")}') @@ -158,7 +158,7 @@ Arguments disponibles : task3.next_run = task3.calculate_next_run() 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' - 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)"}') @@ -200,7 +200,7 @@ Arguments disponibles : task4.next_run = task4.calculate_next_run() 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' - 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")}') @@ -237,7 +237,7 @@ Les observations liées sont également clôturées. task5.next_run = task5.calculate_next_run() 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' - 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")}') @@ -280,7 +280,7 @@ Elle effectue les actions suivantes : task6.next_run = task6.calculate_next_run() 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' - 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")}') @@ -290,6 +290,41 @@ Elle effectue les actions suivantes : if task6.next_run: 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('\nPour gérer les tâches planifiées:') self.stdout.write(' 1. Accédez à l\'admin Django: /admin/') diff --git a/streetup/common/management/commands/run_scheduled_commands.py b/streetup/common/management/commands/run_scheduled_commands.py index 0bd69ca..c3103fa 100644 --- a/streetup/common/management/commands/run_scheduled_commands.py +++ b/streetup/common/management/commands/run_scheduled_commands.py @@ -39,7 +39,7 @@ class Command(BaseCommand): for task in tasks: if task.should_run_now(): 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: 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}') @@ -101,7 +101,7 @@ class Command(BaseCommand): task.next_run = task.calculate_next_run() 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é if task.send_email and task.email_recipients: @@ -125,7 +125,7 @@ class Command(BaseCommand): task.next_run = task.calculate_next_run() 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é 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 if output_file and os.path.exists(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) log.email_sent = True 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: - 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): """