Skip to content

Commit

Permalink
Minor changes inside server.
Browse files Browse the repository at this point in the history
  • Loading branch information
nmanovic committed Feb 5, 2019
1 parent a19887e commit c6b8060
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 86 deletions.
24 changes: 24 additions & 0 deletions cvat/apps/engine/migrations/0024_pluginoption.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 2.1.5 on 2019-02-05 18:17

import cvat.apps.engine.models
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('engine', '0023_plugin'),
]

operations = [
migrations.CreateModel(
name='PluginOption',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', cvat.apps.engine.models.SafeCharField(max_length=32)),
('value', cvat.apps.engine.models.SafeCharField(max_length=1024)),
('plugin', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='engine.Plugin')),
],
),
]
36 changes: 22 additions & 14 deletions cvat/apps/engine/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,29 +139,37 @@ def __str__(self):

class Meta:
default_permissions = ()
unique_together = ('task', 'name')


def parse_attribute(text):
match = re.match(r'^([~@])(\w+)=(\w+):(.+)?$', text)
prefix = match.group(1)
type = match.group(2)
name = match.group(3)
if match.group(4):
values = list(csv.reader(StringIO(match.group(4)), quotechar="'"))[0]
else:
values = []

return {'prefix':prefix, 'type':type, 'name':name, 'values':values}

# FIXME: need to remote text and add (name, type, permanent,
# default_value, values)
class AttributeSpec(models.Model):
label = models.ForeignKey(Label, on_delete=models.CASCADE)
text = models.CharField(max_length=1024)

class Meta:
default_permissions = ()
# FIXME: unique_together = ('label', 'name')

@classmethod
def parse(cls, value):
match = re.match(r'^([~@])(\w+)=(\w+):(.+)?$', value)
if match:
prefix = match.group(1)
type = match.group(2)
name = match.group(3)
if match.group(4):
values = list(csv.reader(StringIO(match.group(4)),
quotechar="'"))[0]
else:
values = []

return {'prefix':prefix, 'type':type, 'name':name, 'values':values}
else:
return None

def get_attribute(self):
return parse_attribute(self.text)
return self.parse(self.text)

def is_mutable(self):
attr = self.get_attribute()
Expand Down
15 changes: 8 additions & 7 deletions cvat/apps/engine/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,21 @@ class Meta:
model = AttributeSpec
fields = ('id', 'text')

def validate_text(self, value):
attr = AttributeSpec.parse(value)
if attr is None:
message = "{} attribute value isn't correct".format(value)
raise serializers.ValidationError(message)

return value

class LabelSerializer(serializers.ModelSerializer):
attributes = AttributeSerializer(many=True, source='attributespec_set',
default=[])
class Meta:
model = Label
fields = ('id', 'name', 'attributes')

# When data is a part of multipart/form-data need to convert labels from
# json string to the internal representation.
def to_internal_value(self, data):
if isinstance(data, str):
data = json.loads(data)
return super().to_internal_value(data)

class JobSerializer(serializers.ModelSerializer):
task_id = serializers.ReadOnlyField(source="segment.task.id")
start_frame = serializers.ReadOnlyField(source="segment.start_frame")
Expand Down
2 changes: 1 addition & 1 deletion cvat/apps/engine/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ def _parse_labels(labels):
parsed_labels[token] = {}
last_label = token
else:
attr = models.parse_attribute(token)
attr = models.AttributeSpec.parse(token)
attr['text'] = token
if not attr['type'] in ['checkbox', 'radio', 'number', 'text', 'select']:
raise ValueError("labels string is not corect. " +
Expand Down
2 changes: 1 addition & 1 deletion cvat/apps/engine/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

# deprecated API
path('', views.dispatch_request),
path('create/task', views.create_task),
#path('create/task', views.create_task),
#path('get/task/<int:tid>/frame/<int:frame>', views.get_frame),
path('check/task/<int:tid>', views.check_task),
path('delete/task/<int:tid>', views.delete_task),
Expand Down
63 changes: 0 additions & 63 deletions cvat/apps/engine/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,69 +254,6 @@ def dispatch_request(request):
else:
return redirect('/dashboard/')


@login_required
@permission_required(perm=['engine.task.create'], raise_exception=True)
def create_task(request):
"""Create a new annotation task"""

db_task = None
params = request.POST.dict()
params['owner'] = request.user
slogger.glob.info("create task with params = {}".format(params))
try:
db_task = task.create_empty(params)
target_paths = []
source_paths = []
upload_dir = db_task.get_upload_dirname()
share_root = settings.SHARE_ROOT
if params['storage'] == 'share':
data_list = request.POST.getlist('data')
data_list.sort(key=len)
for share_path in data_list:
relpath = os.path.normpath(share_path).lstrip('/')
if '..' in relpath.split(os.path.sep):
raise Exception('Permission denied')
abspath = os.path.abspath(os.path.join(share_root, relpath))
if os.path.commonprefix([share_root, abspath]) != share_root:
raise Exception('Bad file path on share: ' + abspath)
source_paths.append(abspath)
target_paths.append(os.path.join(upload_dir, relpath))
else:
data_list = request.FILES.getlist('data')

if len(data_list) > settings.LOCAL_LOAD_MAX_FILES_COUNT:
raise Exception(
'Too many files. Please use download via share')
common_size = 0
for f in data_list:
common_size += f.size
if common_size > settings.LOCAL_LOAD_MAX_FILES_SIZE:
raise Exception('Too many size. Please use download via share')

for data_file in data_list:
source_paths.append(data_file.name)
path = os.path.join(upload_dir, data_file.name)
target_paths.append(path)
with open(path, 'wb') as upload_file:
for chunk in data_file.chunks():
upload_file.write(chunk)

params['SOURCE_PATHS'] = source_paths
params['TARGET_PATHS'] = target_paths

task.create(db_task.id, params)

return JsonResponse({'tid': db_task.id})
except Exception as exc:
slogger.glob.error("cannot create task {}".format(
params['task_name']), exc_info=True)
db_task.delete()
return HttpResponseBadRequest(str(exc))

return JsonResponse({'tid': db_task.id})


@login_required
# @permission_required(perm=['engine.task.access'],
# fn=objectgetter(models.Task, 'tid'), raise_exception=True)
Expand Down

0 comments on commit c6b8060

Please sign in to comment.