From 10a6a6d75c3a1468b0f37bd1ceb5baf9c67dbfcd Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Thu, 25 Oct 2018 12:11:28 +0300 Subject: [PATCH 1/5] Backlink to task initial commit --- cvat/apps/dashboard/__init__.py | 3 ++ .../static/dashboard/js/enginePlugin.js | 18 +++++++++ .../templates/dashboard/dashboard.html | 2 +- cvat/apps/dashboard/views.py | 37 ++++++++++++++----- 4 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 cvat/apps/dashboard/static/dashboard/js/enginePlugin.js diff --git a/cvat/apps/dashboard/__init__.py b/cvat/apps/dashboard/__init__.py index d8e62e54b356..85b9d8c8cd33 100644 --- a/cvat/apps/dashboard/__init__.py +++ b/cvat/apps/dashboard/__init__.py @@ -3,3 +3,6 @@ # # SPDX-License-Identifier: MIT +from cvat.settings.base import JS_3RDPARTY + +JS_3RDPARTY['engine'] = JS_3RDPARTY.get('engine', []) + ['dashboard/js/enginePlugin.js'] \ No newline at end of file diff --git a/cvat/apps/dashboard/static/dashboard/js/enginePlugin.js b/cvat/apps/dashboard/static/dashboard/js/enginePlugin.js new file mode 100644 index 000000000000..0edcada9adab --- /dev/null +++ b/cvat/apps/dashboard/static/dashboard/js/enginePlugin.js @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2018 Intel Corporation + * + * SPDX-License-Identifier: MIT + */ + +"use strict"; + +window.addEventListener('DOMContentLoaded', () => { + let button = $(``); + $('#engineMenuButtons').prepend(button); + + button.on('click', () => { + let win = window.open(`${window.location.origin }/dashboard/?jid=${window.cvat.job.id}`, '_blank'); + win.focus(); + }); +}); + diff --git a/cvat/apps/dashboard/templates/dashboard/dashboard.html b/cvat/apps/dashboard/templates/dashboard/dashboard.html index be700127a325..c12f59ef2e05 100644 --- a/cvat/apps/dashboard/templates/dashboard/dashboard.html +++ b/cvat/apps/dashboard/templates/dashboard/dashboard.html @@ -55,7 +55,7 @@ - {% autopaginate data %} + {% autopaginate data tasks_per_page %}
{% for item in data %} {% include "dashboard/task.html" %} diff --git a/cvat/apps/dashboard/views.py b/cvat/apps/dashboard/views.py index 37e2d3d5ac0a..4006cc374f0c 100644 --- a/cvat/apps/dashboard/views.py +++ b/cvat/apps/dashboard/views.py @@ -10,7 +10,7 @@ from django.contrib.auth.decorators import permission_required from cvat.apps.authentication.decorators import login_required -from cvat.apps.engine.models import Task as TaskModel +from cvat.apps.engine.models import Task as TaskModel, Job as JobModel from cvat.settings.base import JS_3RDPARTY import os @@ -97,22 +97,39 @@ def DetailTaskInfo(request, task, dst_dict): @login_required @permission_required('engine.view_task', raise_exception=True) def DashboardView(request): - filter_name = request.GET['search'] if 'search' in request.GET else None - tasks_query_set = list(TaskModel.objects.prefetch_related('segment_set').order_by('-created_date').all()) - if filter_name is not None: - tasks_query_set = list(filter(lambda x: filter_name.lower() in x.name.lower(), tasks_query_set)) + query_name = request.GET['search'] if 'search' in request.GET else None + query_job = int(request.GET['jid']) if 'jid' in request.GET and request.GET['jid'].isdigit() else None + query_page = None + elements_per_page = 20 + task_list = None + + if query_job is not None and JobModel.objects.filter(pk = query_job).exists(): + task_list = [JobModel.objects.select_related('segment__task').get(pk = query_job).segment.task] + else: + task_list = list(TaskModel.objects.prefetch_related('segment_set').order_by('-created_date').all()) + if query_name is not None: + task_list = list(filter(lambda x: query_name.lower() in x.name.lower(), task_list)) + query_page = int(request.GET['page']) if 'page' in request.GET and request.GET['page'].isdigit() else None + + if query_page is not None: + start, stop = (query_page - 1) * elements_per_page, query_page * elements_per_page - 1 # 0, 19; 20, 39, 40, 59 etc + task_list = [ None if idx < start or idx > stop else task for idx, task in enumerate(task_list) ] data = [] - for task in tasks_query_set: - task_info = {} - MainTaskInfo(task, task_info) - DetailTaskInfo(request, task, task_info) - data.append(task_info) + for task in task_list: + if task is not None: + task_info = {} + MainTaskInfo(task, task_info) + DetailTaskInfo(request, task, task_info) + data.append(task_info) + else: + data.append(None) return render(request, 'dashboard/dashboard.html', { 'data': data, 'max_upload_size': settings.LOCAL_LOAD_MAX_FILES_SIZE, 'max_upload_count': settings.LOCAL_LOAD_MAX_FILES_COUNT, + 'tasks_per_page': elements_per_page, 'share_path': os.getenv('CVAT_SHARE_URL', default=r'${cvat_root}/share'), 'js_3rdparty': JS_3RDPARTY.get('dashboard', []) }) From f15621b567cc64486cf56296ccc63d46305ed694 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Thu, 25 Oct 2018 12:13:53 +0300 Subject: [PATCH 2/5] Simplified code --- cvat/apps/dashboard/__init__.py | 2 +- cvat/apps/dashboard/static/dashboard/js/enginePlugin.js | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/cvat/apps/dashboard/__init__.py b/cvat/apps/dashboard/__init__.py index 85b9d8c8cd33..da270801d9c5 100644 --- a/cvat/apps/dashboard/__init__.py +++ b/cvat/apps/dashboard/__init__.py @@ -5,4 +5,4 @@ from cvat.settings.base import JS_3RDPARTY -JS_3RDPARTY['engine'] = JS_3RDPARTY.get('engine', []) + ['dashboard/js/enginePlugin.js'] \ No newline at end of file +JS_3RDPARTY['engine'] = JS_3RDPARTY.get('engine', []) + ['dashboard/js/enginePlugin.js'] diff --git a/cvat/apps/dashboard/static/dashboard/js/enginePlugin.js b/cvat/apps/dashboard/static/dashboard/js/enginePlugin.js index 0edcada9adab..4c95fa66bff7 100644 --- a/cvat/apps/dashboard/static/dashboard/js/enginePlugin.js +++ b/cvat/apps/dashboard/static/dashboard/js/enginePlugin.js @@ -7,12 +7,9 @@ "use strict"; window.addEventListener('DOMContentLoaded', () => { - let button = $(``); - $('#engineMenuButtons').prepend(button); - - button.on('click', () => { + $(``).on('click', () => { let win = window.open(`${window.location.origin }/dashboard/?jid=${window.cvat.job.id}`, '_blank'); win.focus(); - }); + }).prependTo('#engineMenuButtons'); }); From 7554619bd44c389591d33f9c3e5407f033dd2a8c Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Thu, 25 Oct 2018 15:25:09 +0300 Subject: [PATCH 3/5] Simplified django template --- .../dashboard/templates/dashboard/task.html | 10 +-- cvat/apps/dashboard/views.py | 61 ++----------------- cvat/apps/engine/models.py | 12 ++++ 3 files changed, 21 insertions(+), 62 deletions(-) diff --git a/cvat/apps/dashboard/templates/dashboard/task.html b/cvat/apps/dashboard/templates/dashboard/task.html index 46f10255cc7c..76c50a9b5f88 100644 --- a/cvat/apps/dashboard/templates/dashboard/task.html +++ b/cvat/apps/dashboard/templates/dashboard/task.html @@ -3,14 +3,14 @@ SPDX-License-Identifier: MIT --> -
+
-
+
@@ -18,7 +18,7 @@ {%if item.has_bug_tracker %} - + {% endif %}
@@ -26,9 +26,9 @@ - {% for segment in item.segments %} + {% for jid in item.jid_set %} - + {% endfor %}
{{segment.url}} {{base_url}}?id={{jid}}
diff --git a/cvat/apps/dashboard/views.py b/cvat/apps/dashboard/views.py index 4006cc374f0c..69a4694a50f3 100644 --- a/cvat/apps/dashboard/views.py +++ b/cvat/apps/dashboard/views.py @@ -56,80 +56,27 @@ def JsTreeView(request): json_dumps_params=dict(ensure_ascii=False)) -def MainTaskInfo(task, dst_dict): - dst_dict["status"] = task.status - dst_dict["num_of_segments"] = task.segment_set.count() - dst_dict["mode"] = task.mode.capitalize() - dst_dict["name"] = task.name - dst_dict["task_id"] = task.id - dst_dict["created_date"] = task.created_date - dst_dict["updated_date"] = task.updated_date - dst_dict["bug_tracker_link"] = task.bug_tracker - dst_dict["has_bug_tracker"] = len(task.bug_tracker) > 0 - dst_dict["owner"] = 'undefined' - dst_dict["id"] = task.id - dst_dict["segments"] = [] - -def DetailTaskInfo(request, task, dst_dict): - scheme = request.scheme - host = request.get_host() - dst_dict['segments'] = [] - - for segment in task.segment_set.all(): - for job in segment.job_set.all(): - segment_url = "{0}://{1}/?id={2}".format(scheme, host, job.id) - dst_dict["segments"].append({ - 'id': job.id, - 'start': segment.start_frame, - 'stop': segment.stop_frame, - 'url': segment_url - }) - - db_labels = task.label_set.prefetch_related('attributespec_set').all() - attributes = {} - for db_label in db_labels: - attributes[db_label.id] = {} - for db_attrspec in db_label.attributespec_set.all(): - attributes[db_label.id][db_attrspec.id] = db_attrspec.text - - dst_dict['labels'] = attributes - @login_required @permission_required('engine.view_task', raise_exception=True) def DashboardView(request): query_name = request.GET['search'] if 'search' in request.GET else None query_job = int(request.GET['jid']) if 'jid' in request.GET and request.GET['jid'].isdigit() else None - query_page = None elements_per_page = 20 task_list = None if query_job is not None and JobModel.objects.filter(pk = query_job).exists(): task_list = [JobModel.objects.select_related('segment__task').get(pk = query_job).segment.task] else: - task_list = list(TaskModel.objects.prefetch_related('segment_set').order_by('-created_date').all()) + task_list = list(TaskModel.objects.prefetch_related('segment_set__job_set').order_by('-created_date').all()) if query_name is not None: task_list = list(filter(lambda x: query_name.lower() in x.name.lower(), task_list)) - query_page = int(request.GET['page']) if 'page' in request.GET and request.GET['page'].isdigit() else None - - if query_page is not None: - start, stop = (query_page - 1) * elements_per_page, query_page * elements_per_page - 1 # 0, 19; 20, 39, 40, 59 etc - task_list = [ None if idx < start or idx > stop else task for idx, task in enumerate(task_list) ] - - data = [] - for task in task_list: - if task is not None: - task_info = {} - MainTaskInfo(task, task_info) - DetailTaskInfo(request, task, task_info) - data.append(task_info) - else: - data.append(None) return render(request, 'dashboard/dashboard.html', { - 'data': data, + 'data': task_list, 'max_upload_size': settings.LOCAL_LOAD_MAX_FILES_SIZE, 'max_upload_count': settings.LOCAL_LOAD_MAX_FILES_COUNT, 'tasks_per_page': elements_per_page, + 'base_url': "{0}://{1}/".format(request.scheme, request.get_host()), 'share_path': os.getenv('CVAT_SHARE_URL', default=r'${cvat_root}/share'), - 'js_3rdparty': JS_3RDPARTY.get('dashboard', []) + 'js_3rdparty': JS_3RDPARTY.get('dashboard', []), }) diff --git a/cvat/apps/engine/models.py b/cvat/apps/engine/models.py index 1aaa5198a37a..402a9ed05c61 100644 --- a/cvat/apps/engine/models.py +++ b/cvat/apps/engine/models.py @@ -57,6 +57,18 @@ class Meta: ("change_annotation", "Can modify annotation for the task"), ) + @property + def has_bug_tracker(self): + return len(self.bug_tracker) > 0 + + @property + def jid_set(self): + segments = self.segment_set.all() + jids = [] + for segm in segments: + jids.extend(list(map(lambda job: job.id, segm.job_set.all()))) + return jids + def get_upload_dirname(self): return os.path.join(self.path, ".upload") From a1a1d429cef5c53d0ac71cd2758f1c19db431999 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Thu, 25 Oct 2018 15:30:38 +0300 Subject: [PATCH 4/5] Extra var was removed --- cvat/apps/dashboard/templates/dashboard/dashboard.html | 2 +- cvat/apps/dashboard/views.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/cvat/apps/dashboard/templates/dashboard/dashboard.html b/cvat/apps/dashboard/templates/dashboard/dashboard.html index c12f59ef2e05..be700127a325 100644 --- a/cvat/apps/dashboard/templates/dashboard/dashboard.html +++ b/cvat/apps/dashboard/templates/dashboard/dashboard.html @@ -55,7 +55,7 @@ - {% autopaginate data tasks_per_page %} + {% autopaginate data %}
{% for item in data %} {% include "dashboard/task.html" %} diff --git a/cvat/apps/dashboard/views.py b/cvat/apps/dashboard/views.py index 69a4694a50f3..ea695ce0cb63 100644 --- a/cvat/apps/dashboard/views.py +++ b/cvat/apps/dashboard/views.py @@ -61,7 +61,6 @@ def JsTreeView(request): def DashboardView(request): query_name = request.GET['search'] if 'search' in request.GET else None query_job = int(request.GET['jid']) if 'jid' in request.GET and request.GET['jid'].isdigit() else None - elements_per_page = 20 task_list = None if query_job is not None and JobModel.objects.filter(pk = query_job).exists(): @@ -75,7 +74,6 @@ def DashboardView(request): 'data': task_list, 'max_upload_size': settings.LOCAL_LOAD_MAX_FILES_SIZE, 'max_upload_count': settings.LOCAL_LOAD_MAX_FILES_COUNT, - 'tasks_per_page': elements_per_page, 'base_url': "{0}://{1}/".format(request.scheme, request.get_host()), 'share_path': os.getenv('CVAT_SHARE_URL', default=r'${cvat_root}/share'), 'js_3rdparty': JS_3RDPARTY.get('dashboard', []), From 92dfe070ad8d4db404b5a3c53b25414729e71192 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Thu, 25 Oct 2018 15:40:20 +0300 Subject: [PATCH 5/5] Removed properties --- cvat/apps/dashboard/templates/dashboard/task.html | 12 +++++++----- cvat/apps/engine/models.py | 12 ------------ 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/cvat/apps/dashboard/templates/dashboard/task.html b/cvat/apps/dashboard/templates/dashboard/task.html index 76c50a9b5f88..da017006b59c 100644 --- a/cvat/apps/dashboard/templates/dashboard/task.html +++ b/cvat/apps/dashboard/templates/dashboard/task.html @@ -16,7 +16,7 @@ - {%if item.has_bug_tracker %} + {%if item.bug_tracker %} {% endif %} @@ -26,10 +26,12 @@ - {% for jid in item.jid_set %} - - - + {% for segm in item.segment_set.all %} + {% for job in segm.job_set.all %} + + + + {% endfor %} {% endfor %}
{{base_url}}?id={{jid}}
{{base_url}}?id={{job.id}}
diff --git a/cvat/apps/engine/models.py b/cvat/apps/engine/models.py index 402a9ed05c61..1aaa5198a37a 100644 --- a/cvat/apps/engine/models.py +++ b/cvat/apps/engine/models.py @@ -57,18 +57,6 @@ class Meta: ("change_annotation", "Can modify annotation for the task"), ) - @property - def has_bug_tracker(self): - return len(self.bug_tracker) > 0 - - @property - def jid_set(self): - segments = self.segment_set.all() - jids = [] - for segm in segments: - jids.extend(list(map(lambda job: job.id, segm.job_set.all()))) - return jids - def get_upload_dirname(self): return os.path.join(self.path, ".upload")