From c36d382d6896a479bc1f08d30bde3c1ae65e2f1b Mon Sep 17 00:00:00 2001 From: Nico Vermaas <vermaas@astron.nl> Date: Thu, 21 Jan 2021 11:01:23 +0100 Subject: [PATCH] adding... loads of stuff --- atdb/taskdatabase/models.py | 19 +++++---- atdb/taskdatabase/serializers.py | 24 +++++++++-- atdb/taskdatabase/services/signals.py | 40 +++++++++--------- .../static/taskdatabase/style.css | 5 +-- .../templates/taskdatabase/index.html | 10 ++--- .../templates/taskdatabase/tasks.html | 41 ++++++------------- atdb/taskdatabase/urls.py | 2 +- atdb/taskdatabase/views.py | 6 +-- 8 files changed, 73 insertions(+), 74 deletions(-) diff --git a/atdb/taskdatabase/models.py b/atdb/taskdatabase/models.py index 16cd9d74..cc72d800 100644 --- a/atdb/taskdatabase/models.py +++ b/atdb/taskdatabase/models.py @@ -21,19 +21,20 @@ class Task(models.Model): task_type = models.CharField(max_length=20, default="task") # note: the apparent naming reversal is intentional. Predecessors are somebody elses successors. - desired_predecessor_id = models.CharField(max_length=12, blank=True, null=True) - predecessor = models.ForeignKey('self', related_name='task_successors', on_delete=models.SET_NULL, null=True,blank=True) - successor = models.ForeignKey('self', related_name='task_predecessors', on_delete=models.SET_NULL, null=True,blank=True) + # todo: change to Integer... but then the specification service has to be changed to using a dict + # to properly translate a python 'None' string to a Null value. - workflow = models.ForeignKey(Workflow, related_name='tasks', on_delete=models.SET_NULL, null=True) + new_predecessor_id = models.CharField(max_length=12, blank=True, null=True) + predecessor = models.ForeignKey('self', related_name='task_successors', on_delete=models.SET_NULL, null=True,blank=True) + workflow = models.ForeignKey(Workflow, related_name='tasks', on_delete=models.SET_NULL, null=True, blank=True) project = models.CharField(max_length=100, blank=True, null=True, default="unknown") sas_id = models.CharField(max_length=30, blank=True, null=True) priority = models.IntegerField(default=0) purge_policy = models.CharField(max_length=5, default="no", blank=True, null=True) - desired_workflow_id = models.CharField(max_length=12, blank=True, null=True) - desired_workflow_uri = models.CharField(max_length=100, blank=True, null=True) - workflow = models.ForeignKey(Workflow, related_name='tasks', on_delete=models.SET_NULL, null=True,blank=True) + new_workflow_id = models.CharField(max_length=12, blank=True, null=True) + new_workflow_uri = models.CharField(max_length=100, blank=True, null=True) + stage_request_id = models.IntegerField(default=0) inputs = models.JSONField(null=True, blank=True) outputs = models.JSONField(null=True, blank=True) @@ -41,7 +42,7 @@ class Task(models.Model): skip = models.BooleanField(default=False) creationTime = models.DateTimeField(default=datetime.utcnow, blank=True) - desired_status = models.CharField(max_length=50, default="defining", null=True) + new_status = models.CharField(max_length=50, default="defining", null=True) status = models.CharField(db_index=True, default="unknown", max_length=50,blank=True, null=True) def __str__(self): @@ -62,7 +63,7 @@ class LogEntry(models.Model): step_name = models.CharField(max_length=30, blank=True, null=True) start_time = models.DateTimeField(blank=True, null=True) end_time = models.DateTimeField(blank=True, null=True) - desired_status = models.CharField(max_length=50, default="defined", blank=True, null=True) + new_status = models.CharField(max_length=50, default="defined", blank=True, null=True) status = models.CharField(max_length=50,default="defined", blank=True, null=True) def __str__(self): diff --git a/atdb/taskdatabase/serializers.py b/atdb/taskdatabase/serializers.py index 74546845..670ef18b 100644 --- a/atdb/taskdatabase/serializers.py +++ b/atdb/taskdatabase/serializers.py @@ -2,6 +2,21 @@ from rest_framework import serializers from .models import Status, Task, Workflow, LogEntry + +class WorkflowSerializer(serializers.ModelSerializer): + +# tasks = serializers.StringRelatedField( +# many=True, +# required=False, +# ) + + #workflow = WorkflowSerializer() + + class Meta: + model = Workflow + fields = "__all__" + + class TaskSerializer(serializers.ModelSerializer): status_history = serializers.StringRelatedField( @@ -12,11 +27,12 @@ class TaskSerializer(serializers.ModelSerializer): class Meta: model = Task fields = ('id','task_type','taskID', - 'desired_predecessor_id','predecessor','successor', + 'new_predecessor_id','predecessor', 'project','sas_id','priority','purge_policy','skip', - 'desired_workflow_id','desired_workflow_uri','workflow', - 'status','desired_status', - 'inputs','outputs','status_history') + 'new_workflow_id','new_workflow_uri','workflow', + 'stage_request_id', + 'status','new_status', + 'inputs','outputs','status_history',) class StatusSerializer(serializers.ModelSerializer): diff --git a/atdb/taskdatabase/services/signals.py b/atdb/taskdatabase/services/signals.py index 03ce4475..d6a7590c 100644 --- a/atdb/taskdatabase/services/signals.py +++ b/atdb/taskdatabase/services/signals.py @@ -35,23 +35,23 @@ def pre_save_task_handler(sender, **kwargs): def add_workflow(myTaskObject): - desired_workflow_id = myTaskObject.desired_workflow_id - desired_workflow_uri = myTaskObject.desired_workflow_uri + new_workflow_id = myTaskObject.new_workflow_id + new_workflow_uri = myTaskObject.new_workflow_uri # first try to find the workflow by desired workflow_id try: - desired_workflow = Workflow.objects.get(id=desired_workflow_id) + new_workflow = Workflow.objects.get(id=new_workflow_id) except: - desired_workflow = None + new_workflow = None - if (desired_workflow == None): + if (new_workflow == None): # then try workflow_uri - desired_workflow = Workflow.objects.get(workflow_uri=desired_workflow_uri) + new_workflow = Workflow.objects.get(workflow_uri=new_workflow_uri) # first check if works needs to be done at all - if (myTaskObject.workflow != desired_workflow): + if (myTaskObject.workflow != new_workflow): # set the new status - myTaskObject.workflow = desired_workflow + myTaskObject.workflow = new_workflow return myTaskObject @@ -60,14 +60,14 @@ def add_predecessor(myTaskObject): # connect the task to a workflow after posting a (flat) task through the REST API try: - desired_predecessor_id = myTaskObject.desired_predecessor_id + new_predecessor_id = myTaskObject.new_predecessor_id # first try to find the workflow by desired workflow_id - desired_predecessor = Task.objects.get(id=desired_predecessor_id) + new_predecessor = Task.objects.get(id=new_predecessor_id) - if (myTaskObject.predecessor != desired_predecessor): + if (myTaskObject.predecessor != new_predecessor): # set the new status - myTaskObject.predecessor = desired_predecessor + myTaskObject.predecessor = new_predecessor except: pass @@ -89,15 +89,15 @@ def handle_pre_save(sender, **kwargs): # handle status change status = str(myTaskObject.status) - desired_status = str(myTaskObject.desired_status) + new_status = str(myTaskObject.new_status) - if (desired_status!=None) and (status!=desired_status): + if (new_status!=None) and (status!=new_status): # set the new status - myTaskObject.status = desired_status + myTaskObject.status = new_status # add the new to the status history by brewing a status object out of it - myStatus = Status(name=desired_status, task=myTaskObject) + myStatus = Status(name=new_status, task=myTaskObject) myStatus.save() # connect the task to a workflow after posting a (flat) task through the REST API @@ -113,8 +113,8 @@ def handle_pre_save(sender, **kwargs): connect_signals() # dispatch a job if the status has changed. - if (desired_status != None) and (status != desired_status): - jobs.dispatchJob(myTaskObject, desired_status) + if (new_status != None) and (status != new_status): + jobs.dispatchJob(myTaskObject, new_status) @receiver(post_save, sender=Task) @@ -137,10 +137,10 @@ def handle_post_save(sender, **kwargs): logger.info("save new "+str(myTaskObject.task_type)) # set status - myTaskObject.status = myTaskObject.desired_status + myTaskObject.status = myTaskObject.new_status # add the new to the status history by brewing a status object out of it - myStatus = Status(name=myTaskObject.desired_status, task=myTaskObject) + myStatus = Status(name=myTaskObject.new_status, task=myTaskObject) myStatus.save() # temporarily disconnect the post_save handler to save the dataproduct (again) and avoiding recursion. diff --git a/atdb/taskdatabase/static/taskdatabase/style.css b/atdb/taskdatabase/static/taskdatabase/style.css index d29e1bad..7704fca8 100644 --- a/atdb/taskdatabase/static/taskdatabase/style.css +++ b/atdb/taskdatabase/static/taskdatabase/style.css @@ -39,12 +39,11 @@ TD { color: red; } -.staging,.submitting,.running,.ingesting { +.defining,.staging,.submitting,.running,.ingesting { font-style: italic; color: green; -font-weight: bold; } -.running { +.processing { font-weight: bold; background-color: lightyellow; } diff --git a/atdb/taskdatabase/templates/taskdatabase/index.html b/atdb/taskdatabase/templates/taskdatabase/index.html index 650241c1..158027fc 100644 --- a/atdb/taskdatabase/templates/taskdatabase/index.html +++ b/atdb/taskdatabase/templates/taskdatabase/index.html @@ -17,14 +17,14 @@ <table class="table table-striped table-bordered table-sm"> <thead> <tr> - <th width="3%">TaskID</th> - <th width="10%">task_type</th> + <th width="5%">TaskID</th> + <th width="3%">task_type</th> <th>Project</th> + <th>Workflow</th> <th>Status</th> <th>Created</th> - <th>Quality</th> + <th>Size</th> - <th>Details</th> <th>Actions</th> </tr> </thead> @@ -44,7 +44,7 @@ </div> {% include 'taskdatabase/pagination.html' %} </div> - <p class="footer"> Version 1.0.0 (17 jan 2021 - 09:00) + <p class="footer"> Version 1.0.0 (21 jan 2021 - 11:00) <script type="text/javascript"> (function(seconds) { var refresh, diff --git a/atdb/taskdatabase/templates/taskdatabase/tasks.html b/atdb/taskdatabase/templates/taskdatabase/tasks.html index d451b907..132285ae 100644 --- a/atdb/taskdatabase/templates/taskdatabase/tasks.html +++ b/atdb/taskdatabase/templates/taskdatabase/tasks.html @@ -1,8 +1,8 @@ {% load static %} {% for task in my_tasks %} - {% if task.my_status != "removed_invisible" %} + {% if task.status != "removed_invisible" %} <div class="row"> - <tr class="{{ task.my_status }}"> + <tr class="{{ task.status }}"> <td> @@ -14,66 +14,49 @@ </td> <td>{{ task.project }}</td> - <td> - {% if task.my_status != "valid_priority" %} - {{ task.my_status }} - {% endif %} - {% if task.my_status == "valid_priority" %} - valid (priority) - {% endif %} - {% if task.my_status == "ingesting" %} - {% if task.control_parameters != "unknown" %} - {{ task.control_parameters }} - {% endif %} - {% endif %} - </td> + <td>{{ task.workflow }} + <td>{{ task.status }}</td> <td>{{ task.creationTime|date:"Y-m-d H:i:s" }} </td> - <td>{{ task.endtime|date:"Y-m-d H:i:s" }} </td> - <td>{{ task.size|filesizeformat }} </td> - <td> - {% if "removed" in task.my_status and task.quality != "unknown" %} - {{ task.quality }} - {% endif %} </td> <td> - {% if task.my_status == "defined" %} + {% if task.status == "defined" %} <a href="{% url 'task-setstatus-view' task.pk 'scheduled' my_tasks.number %}" class="btn btn-primary btn-sm" role="button">Schedule</a> {% endif %} - {% if task.my_status == "scheduled" %} + {% if task.status == "scheduled" %} <a href="{% url 'task-setstatus-view' task.pk 'defined' my_tasks.number %}" class="btn btn-primary btn-sm" role="button">Unschedule</a> {% if not task.skip_auto_ingest %} <a href="{% url 'task-skipautoingest-view' task.pk 'true' my_tasks.number %}" class="btn btn-primary btn-sm" role="button">Skip Ingest</a> {% endif %} {% endif %} - {% if task.my_status == "completed" or task.my_status == "incomplete" %} + {% if task.status == "completed" or task.status == "incomplete" %} <a href="{% url 'task-setstatus-view' task.pk 'valid' my_tasks.number %}" class="btn btn-primary btn-sm" role="button">Ready to Ingest</a> {% endif %} - {% if task.my_status == "error (no completing)" or task.my_status == "defined" %} + {% if task.status == "error (no completing)" or task.status == "defined" %} <a href="{% url 'task-setstatus-view' task.pk 'completing' my_tasks.number %}" class="btn btn-success btn-sm" role="button">Completing</a> {% endif %} - {% if task.my_status == "valid" %} + {% if task.status == "valid" %} <a href="{% url 'task-setstatus-view' task.pk 'valid_priority' my_tasks.number %}" class="btn btn-warning btn-sm" role="button">Priority Ingest</a> <a href="{% url 'task-setstatus-view' task.pk 'completed' my_tasks.number %}" class="btn btn-primary btn-sm" role="button">Cancel Ingest</a> {% endif %} - {% if task.my_status == "valid_priority" %} + {% if task.status == "valid_priority" %} <a href="{% url 'task-setstatus-view' task.pk 'valid' my_tasks.number %}" class="btn btn-primary btn-sm" role="button">Cancel Priority</a> <a href="{% url 'task-setstatus-view' task.pk 'completed' my_tasks.number %}" class="btn btn-primary btn-sm" role="button">Cancel Ingest</a> {% endif %} - {% if task.my_status == "archived" %} + {% if task.status == "archived" %} <a href="{% url 'task-setquality-view' task.pk 'data_is_good' my_tasks.number %}" class="btn btn-success btn-sm" role="button">Data is Good</a> <a href="{% url 'task-setquality-view' task.pk 'data_is_bad' my_tasks.number %}" class="btn btn-danger btn-sm" role="button">Data is Bad</a> {% endif %} - {% if task.my_status == "removed" and task.quality == "unknown" %} + {% if task.status == "removed" and task.quality == "unknown" %} <a href="{% url 'task-setquality-view' task.pk 'data_is_good' my_tasks.number %}" class="btn btn-success btn-sm" role="button">Data is Good</a> <a href="{% url 'task-setquality-view' task.pk 'data_is_bad' my_tasks.number %}" class="btn btn-danger btn-sm" role="button">Data is Bad</a> {% endif %} diff --git a/atdb/taskdatabase/urls.py b/atdb/taskdatabase/urls.py index 6b4e8133..56ebc80a 100644 --- a/atdb/taskdatabase/urls.py +++ b/atdb/taskdatabase/urls.py @@ -24,7 +24,7 @@ urlpatterns = [ name='get-next-taskid-view'), # --- controller resources --- - path('tasks/<int:pk>/setstatus/<desired_status>/<page>', + path('tasks/<int:pk>/setstatus/<new_status>/<page>', views.TaskSetStatus, name='task-setstatus-view'), diff --git a/atdb/taskdatabase/views.py b/atdb/taskdatabase/views.py index 9d629398..721016e9 100644 --- a/atdb/taskdatabase/views.py +++ b/atdb/taskdatabase/views.py @@ -189,7 +189,7 @@ class LogEntryDetailsViewAPI(generics.RetrieveUpdateDestroyAPIView): # --- controller resources, triggered by a button in the GUI or directoy with a URL --- -# set task status to 'desired_status' - called from the GUI +# set task status to 'new_status' - called from the GUI def Skip(request,pk,skip_it,page): @@ -200,10 +200,10 @@ def Skip(request,pk,skip_it,page): return redirect('/atdb/?page='+page) -def TaskSetStatus(request,pk,desired_status,page): +def TaskSetStatus(request,pk,new_status,page): model = Task task = Task.objects.get(pk=pk) - task.desired_status = desired_status + task.new_status = new_status task.save() return redirect('/atdb/?page='+page) -- GitLab