On donne la possibilité d'annuler une tâche d'import

This commit is contained in:
Jean-Marie Favreau 2023-12-23 12:52:19 +01:00
parent e52b9b0400
commit e02caa06d9
6 changed files with 79 additions and 18 deletions

View File

@ -28,7 +28,7 @@ app.autodiscover_tasks()
def close_import_task(taskid, success, error_message): def close_import_task(taskid, success, error_message):
from agenda_culturel.models import BatchImportation from agenda_culturel.models import BatchImportation
task = BatchImportation.objects.get(pk=taskid) task = BatchImportation.objects.get(celery_id=taskid)
task.status = BatchImportation.STATUS.SUCCESS if success else BatchImportation.STATUS.FAILED task.status = BatchImportation.STATUS.SUCCESS if success else BatchImportation.STATUS.FAILED
fields = ["status"] fields = ["status"]
if not success: if not success:
@ -38,33 +38,40 @@ def close_import_task(taskid, success, error_message):
@app.task(bind=True) @app.task(bind=True)
def import_events_from_json(self, json, taskid): def import_events_from_json(self, json):
from agenda_culturel.models import Event from agenda_culturel.models import Event
from .importation import EventsImporter
logger.info("Import events from json: {}".format(taskid)) logger.info("Import events from json: {}".format(self.request.id))
# TODO importer = EventsImporter(self.request.id)
success = True success, error_message = importer.import_events(json)
error_message = ""
# finally, close task # finally, close task
close_import_task(taskid, success, error_message) close_import_task(self.request.id, success, error_message)
@app.task(bind=True) @app.task(bind=True)
def import_events_from_url(self, source, browsable_url, taskid): def import_events_from_url(self, source, browsable_url):
from agenda_culturel.models import Event from agenda_culturel.models import Event
from .importation import EventsImporter
logger.info("Import events from url: {} {}".format(source, taskid)) logger.info("Import events from url: {} {}".format(source, self.request.id))
# first get json
# TODO # TODO
# then import
# importer = EventsImporter(self.request.id)
# success, error_message = importer.import_events(json)
success = True success = True
error_message = "" error_message = ""
# finally, close task # finally, close task
close_import_task(taskid, success, error_message) close_import_task(self.request.id, success, error_message)

View File

@ -0,0 +1,30 @@
from agenda_culturel.models import Event
import json
class EventsImporter:
def __init__(self, celery_id):
self.celery_id = celery_id
def import_events(self, json_structure):
try:
structure = json.loads(json_structure)
self.url = structure["header"]["url"]
self.date = structure["header"]["date"]
except:
return (False, "JSON file is not correctly structured")
# load events
for event in structure["events"]:
self.import_event(event)
def import_event(self, event):
pass

View File

@ -0,0 +1,18 @@
# Generated by Django 4.2.7 on 2023-12-23 11:06
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('agenda_culturel', '0013_batchimportation_error_message_and_more'),
]
operations = [
migrations.AddField(
model_name='batchimportation',
name='celery_id',
field=models.CharField(default='', max_length=128),
),
]

View File

@ -241,3 +241,5 @@ class BatchImportation(models.Model):
nb_initial = models.PositiveIntegerField(verbose_name=_('Number of collected events'), default=0) nb_initial = models.PositiveIntegerField(verbose_name=_('Number of collected events'), default=0)
nb_imported = models.PositiveIntegerField(verbose_name=_('Number of imported events'), default=0) nb_imported = models.PositiveIntegerField(verbose_name=_('Number of imported events'), default=0)
celery_id = models.CharField(max_length=128, default="")

View File

@ -1,4 +1,4 @@
{% extends "agenda_culturel/page.html" %} !<{% extends "agenda_culturel/page.html" %}
{% block title %}Importations par lot{% endblock %} {% block title %}Importations par lot{% endblock %}
@ -30,7 +30,7 @@
<tr> <tr>
<td>{{ obj.id }}</a></td> <td>{{ obj.id }}</a></td>
<td>{{ obj.created_date }}</td> <td>{{ obj.created_date }}</td>
<td>{{ obj.status }}</td> <td><span{% if obj.status == "failed" %} data-tooltip="{{ obj.error_message }}"{% endif %}>{{ obj.status }}</span></td>
<td>{% if obj.status == "running" %}<a href="{% url 'cancel_import' obj.id %}">Annuler</a>{% endif %}</td> <td>{% if obj.status == "running" %}<a href="{% url 'cancel_import' obj.id %}">Annuler</a>{% endif %}</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -32,7 +32,7 @@ from django.contrib.messages.views import SuccessMessageMixin
from .calendar import CalendarMonth, CalendarWeek from .calendar import CalendarMonth, CalendarWeek
from .extractors import ExtractorAllURLs from .extractors import ExtractorAllURLs
from .celery import import_events_from_json, import_events_from_url from .celery import app as celery_app, import_events_from_json, import_events_from_url
import unicodedata import unicodedata
@ -493,14 +493,18 @@ class BatchImportationCreateView(SuccessMessageMixin, LoginRequiredMixin, Create
success_message = _('The import has been run successfully.') success_message = _('The import has been run successfully.')
def form_valid(self, form): def form_valid(self, form):
response = super().form_valid(form)
# run import
if "json" in form.data and form.data["json"] is not None and form.data["json"].strip() != "": if "json" in form.data and form.data["json"] is not None and form.data["json"].strip() != "":
import_events_from_json.delay(form.data["json"], self.object.id) result = import_events_from_json.delay(form.data["json"])
else: else:
import_events_from_url.delay(self.object.source, self.object.browsable_url, self.object.id) result = import_events_from_url.delay(self.object.source, self.object.browsable_url)
# update the object with celery_id
form.instance.celery_id = result.id
return super().form_valid(form)
return response
@login_required(login_url="/accounts/login/") @login_required(login_url="/accounts/login/")
@ -508,7 +512,7 @@ def cancel_import(request, pk):
import_process = get_object_or_404(BatchImportation, pk=pk) import_process = get_object_or_404(BatchImportation, pk=pk)
if request.method == 'POST': if request.method == 'POST':
# TODO cancel the celery import celery_app.control.revoke(import_process.celery_id)
import_process.status = BatchImportation.STATUS.CANCELED import_process.status = BatchImportation.STATUS.CANCELED
import_process.save(update_fields=["status"]) import_process.save(update_fields=["status"])