Skip to content

Commit

Permalink
Implemented GET tasks/ID/status and POST tasks/ is in progress.
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikita Manovich committed Jan 31, 2019
1 parent 2262597 commit 6902545
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 30 deletions.
40 changes: 21 additions & 19 deletions cvat/apps/dashboard/static/dashboard/js/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
/* Server requests */
function createTaskRequest(oData, onSuccessRequest, onSuccessCreate, onError, onComplete, onUpdateStatus) {
$.ajax({
url: "/create/task",
url: "/api/v1/tasks/",
type: "POST",
data: oData,
contentType: false,
Expand All @@ -42,7 +42,7 @@ function createTaskRequest(oData, onSuccessRequest, onSuccessCreate, onError, on

let requestInterval = setInterval(function() {
$.ajax({
url: "/check/task/" + tid,
url: "/api/v1/tasks/{}/status".format(tid),
success: receiveStatus,
error: function(data) {
clearInterval(requestInterval);
Expand All @@ -54,34 +54,33 @@ function createTaskRequest(oData, onSuccessRequest, onSuccessCreate, onError, on

function receiveStatus(data) {
if (done) return;
if (data["state"] === "created") {
if (data.state === "Finished") {
done = true;
clearInterval(requestInterval);
onComplete();
onSuccessCreate(tid);
}
else if (data["state"] === "error") {
else if (data.state === "Failed") {
done = true;
clearInterval(requestInterval);
onComplete();
onError(data.stderr);
onError(data.message);
}
else if (data["state"] === "started" && "status" in data) {
onUpdateStatus(data["status"]);
else if (data["state"] === "Started" && data.message != "") {
onUpdateStatus(data.message);
}
}
}
}


function updateTaskRequest(labels) {
let oData = new FormData();
oData.append("labels", labels);
let data = new LabelsInfo(labels);

$.ajax({
url: "/update/task/" + window.cvat.dashboard.taskID,
type: "POST",
data: oData,
url: "/api/v1/tasks/" + window.cvat.dashboard.taskID,
type: "PATCH",
data: data,
contentType: false,
processData: false,
success: function() {
Expand Down Expand Up @@ -509,25 +508,28 @@ function setupTaskCreator() {
}

let taskData = new FormData();
taskData.append("task_name", name);
taskData.append("bug_tracker_link", bugTrackerLink);
taskData.append("name", name);
taskData.append("bug_tracker", bugTrackerLink);
taskData.append("labels", labels);
taskData.append("flip_flag", flipImages);
taskData.append("flipped", flipImages);
taskData.append("z_order", zOrder);
taskData.append("storage", source);

if (customSegmentSize.prop("checked")) {
taskData.append("segment_size", segmentSize);
}
if (customOverlapSize.prop("checked")) {
taskData.append("overlap_size", overlapSize);
taskData.append("overlap", overlapSize);
}
if (customCompressQuality.prop("checked")) {
taskData.append("compress_quality", compressQuality);
taskData.append("image_quality", compressQuality);
}

for (let file of files) {
taskData.append("data", file);
if (source === "local") {
taskData.append("client_files", file);
} else {
taskData.append("server_files", file);
}
}

submitCreate.prop("disabled", true);
Expand Down
18 changes: 18 additions & 0 deletions cvat/apps/engine/migrations/0021_task_image_quality.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.1.5 on 2019-01-31 16:21

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('engine', '0020_remove_task_path'),
]

operations = [
migrations.AddField(
model_name='task',
name='image_quality',
field=models.PositiveSmallIntegerField(default=50),
),
]
3 changes: 2 additions & 1 deletion cvat/apps/engine/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@ class Task(models.Model):
created_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(auto_now_add=True)
overlap = models.PositiveIntegerField(default=0)
segment_size = models.PositiveIntegerField(default=sys.maxsize)
segment_size = models.PositiveIntegerField()
z_order = models.BooleanField(default=False)
flipped = models.BooleanField(default=False)
image_quality = models.PositiveSmallIntegerField(default=50)
# FIXME: remote source field
source = SafeCharField(max_length=256, default="unknown")
status = models.CharField(max_length=32, choices=StatusChoice.choices(),
Expand Down
18 changes: 13 additions & 5 deletions cvat/apps/engine/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,22 +71,28 @@ class Meta:
def to_internal_value(self, data):
return { 'file' : data }

class RequestStatusSerializer(serializers.Serializer):
state = serializers.ChoiceField(choices=["Unknown",
"Queued", "Started", "Finished", "Failed"])
message = serializers.CharField(allow_blank=True, default="")

class TaskSerializer(serializers.ModelSerializer):
labels = LabelSerializer(many=True, source='label_set')
labels = LabelSerializer(many=True, source='label_set', partial=True)
segments = SegmentSerializer(many=True, source='segment_set', read_only=True)
client_files = ClientFileSerializer(many=True, source='clientfile_set',
write_only=True)
write_only=True, partial=True)
server_files = ServerFileSerializer(many=True, source='serverfile_set',
write_only=True)
write_only=True, partial=True)
remote_files = RemoteFileSerializer(many=True, source='remotefile_set',
write_only=True)
write_only=True, partial=True)
image_quality = serializers.IntegerField(min_value=0, max_value=100)

class Meta:
model = Task
fields = ('url', 'id', 'name', 'size', 'mode', 'owner', 'assignee',
'bug_tracker', 'created_date', 'updated_date', 'overlap',
'segment_size', 'z_order', 'flipped', 'status', 'labels', 'segments',
'server_files', 'client_files', 'remote_files')
'server_files', 'client_files', 'remote_files', 'image_quality')
read_only_fields = ('size', 'mode', 'created_date', 'updated_date',
'overlap', 'status', 'segment_size')
ordering = ['-id']
Expand All @@ -96,6 +102,8 @@ def create(self, validated_data):
client_files = validated_data.pop('clientfile_set')
server_files = validated_data.pop('serverfile_set')
remote_files = validated_data.pop('remotefile_set')
if not validated_data.get('segment_size'):
validated_data['segment_size'] = 0
db_task = Task.objects.create(size=0, **validated_data)
for label in labels:
attributes = label.pop('attributespec_set')
Expand Down
5 changes: 3 additions & 2 deletions cvat/apps/engine/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
path( # GET, DELETE, PATCH
REST_API_PREFIX + 'tasks/<int:pk>', views.TaskDetail.as_view(),
name='task-detail'),
path( # GET
REST_API_PREFIX + 'tasks/<int:pk>/status', views.TaskStatus.as_view(),
name='task-status'),
# GET meta information for all frames
path(REST_API_PREFIX + 'tasks/<int:pk>/frames/meta',
views.get_image_meta_cache, name='image-meta-cache'),
Expand Down Expand Up @@ -79,8 +82,6 @@
views.dummy_view,
name='plugin-request-detail'),

path('create/task', views.create_task), ####
path('check/task/<int:tid>', views.check_task), ####
path('delete/task/<int:tid>', views.delete_task), ####
path('update/task/<int:tid>', views.update_task), ####
path('dump/annotation/task/<int:tid>', views.dump_annotation), ###
Expand Down
38 changes: 35 additions & 3 deletions cvat/apps/engine/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from ast import literal_eval

from django.http import HttpResponse, HttpResponseBadRequest, JsonResponse
from django.shortcuts import redirect, render
from django.shortcuts import redirect, render, get_object_or_404
from django.conf import settings
from rules.contrib.views import permission_required, objectgetter
from django.views.decorators.gzip import gzip_page
Expand All @@ -19,7 +19,8 @@
from rest_framework.response import Response
from rest_framework.reverse import reverse
from rest_framework.renderers import JSONRenderer

from rest_framework import status
import django_rq


from . import annotation, task, models
Expand All @@ -30,7 +31,8 @@
from .log import slogger, clogger
from cvat.apps.engine.models import StatusChoice, Task, Job
from cvat.apps.engine.serializers import (TaskSerializer, UserSerializer,
ExceptionSerializer, AboutSerializer, JobSerializer, ImageMetaSerializer)
ExceptionSerializer, AboutSerializer, JobSerializer, ImageMetaSerializer,
RequestStatusSerializer)
from django.contrib.auth.models import User

# Server REST API
Expand Down Expand Up @@ -61,6 +63,36 @@ class TaskDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Task.objects.all()
serializer_class = TaskSerializer

class TaskStatus(APIView):
serializer_class = RequestStatusSerializer

def get(self, request, version, pk):
db_task = get_object_or_404(Task, pk=pk)
response = self._get_response(queue="default",
job_id="api/{}/tasks/{}".format(version, pk))
serializer = TaskStatus.serializer_class(data=response)

if serializer.is_valid(raise_exception=True):
return Response(serializer.data)

def _get_response(self, queue, job_id):
queue = django_rq.get_queue(queue)
job = queue.fetch_job(job_id)
response = {}
if job is None or job.is_finished:
response = { "state": "Finished" }
elif job.is_queued:
response = { "state": "Queued" }
elif job.is_failed:
response = { "state": "Failed", "message": job.exc_info }
else:
response = { "state": "Started" }
if 'status' in job.meta:
response['message'] = job.meta['status']

return response


class JobList(generics.ListAPIView):
queryset = Job.objects.all()
serializer_class = JobSerializer
Expand Down

0 comments on commit 6902545

Please sign in to comment.