Create default presets at boot

pull/246/head
Piero Toffanin 2017-07-25 13:54:41 -04:00
rodzic 4acb13829a
commit 750f43ca9d
7 zmienionych plików z 69 dodań i 11 usunięć

Wyświetl plik

@ -4,6 +4,7 @@ from django.core.exceptions import ObjectDoesNotExist
from django.db.utils import ProgrammingError
from guardian.shortcuts import assign_perm
from app.models import Preset
from nodeodm.models import ProcessingNode
# noinspection PyUnresolvedReferences
from . import scheduler, signals
@ -50,6 +51,19 @@ def boot():
# Add permission to view processing nodes
default_group.permissions.add(Permission.objects.get(codename="view_processingnode"))
# Add default presets
Preset.objects.get_or_create(name='DSM + DTM', system=True,
options=[{'name': 'dsm', 'value': True}, {'name': 'dtm', 'value': True}])
Preset.objects.get_or_create(name='High Quality', system=True,
options=[{'name': 'dsm', 'value': True},
{'name': 'skip-resize', 'value': True},
{'name': 'mesh-octree-depth', 'value': "12"},
{'name': 'use-25dmesh', 'value': True},
{'name': 'dem-resolution', 'value': "0.04"},
{'name': 'orthophoto-resolution', 'value': "60"},
])
Preset.objects.get_or_create(name='Default', system=True, options=[{'name': 'dsm', 'value': True}])
# Unlock any Task that might have been locked
Task.objects.filter(processing_lock=True).update(processing_lock=False)

Wyświetl plik

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.1 on 2017-07-25 17:24
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('app', '0009_auto_20170721_1332'),
]
operations = [
migrations.AlterField(
model_name='preset',
name='owner',
field=models.ForeignKey(blank=True, help_text='The person who owns this preset', null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
]

Wyświetl plik

@ -10,7 +10,7 @@ logger = logging.getLogger('app.logger')
class Preset(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE, help_text="The person who owns this preset")
owner = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE, help_text="The person who owns this preset")
name = models.CharField(max_length=255, blank=False, null=False, help_text="A label used to describe the preset")
options = JSONField(default=list(), blank=True, help_text="Options that define this preset (same format as in a Task's options).",
validators=[validate_task_options])

Wyświetl plik

@ -64,6 +64,8 @@ class EditTaskForm extends React.Component {
this.handleDeletePreset = this.handleDeletePreset.bind(this);
this.findFirstPresetMatching = this.findFirstPresetMatching.bind(this);
this.getAvailableOptionsOnly = this.getAvailableOptionsOnly.bind(this);
this.getAvailableOptionsOnlyText = this.getAvailableOptionsOnlyText.bind(this);
}
notifyFormLoaded(){
@ -209,7 +211,7 @@ class EditTaskForm extends React.Component {
}
this.presetsRequest =
$.getJSON("/api/presets/?ordering=-created_at", presets => {
$.getJSON("/api/presets/?ordering=-system,-created_at", presets => {
if (Array.isArray(presets)){
// Add custom preset
const customPreset = {
@ -218,7 +220,7 @@ class EditTaskForm extends React.Component {
options: [],
system: true
};
presets.push(customPreset);
presets.unshift(customPreset);
// Choose preset
let selectedPreset = presets[0],
@ -298,6 +300,11 @@ class EditTaskForm extends React.Component {
return options.filter(opt => optionNames[opt.name]);
}
getAvailableOptionsOnlyText(options, availableOptions){
const opts = this.getAvailableOptionsOnly(options, availableOptions);
return opts.map(opt => `${opt.name}:${opt.value}`).join(", ");
}
getTaskInfo(){
const { name, selectedNode, selectedPreset } = this.state;
@ -323,7 +330,7 @@ class EditTaskForm extends React.Component {
options: [],
system: true
};
presets.push(customPreset);
presets.unshift(customPreset);
this.setState({presets});
}
customPreset.options = Utils.clone(selectedPreset.options);
@ -463,9 +470,13 @@ class EditTaskForm extends React.Component {
<div className="form-group form-inline">
<label className="col-sm-2 control-label">Options</label>
<div className="col-sm-10">
<select className="form-control" value={this.state.selectedPreset.id} onChange={this.handleSelectPreset}>
<select
title={this.getAvailableOptionsOnlyText(this.state.selectedPreset.options, this.state.selectedNode.options)}
className="form-control"
value={this.state.selectedPreset.id}
onChange={this.handleSelectPreset}>
{this.state.presets.map(preset =>
<option value={preset.id} key={preset.id}>{preset.name}</option>
<option value={preset.id} key={preset.id} className={preset.system ? "system-preset" : ""}>{preset.name}</option>
)}
</select>

Wyświetl plik

@ -38,12 +38,13 @@ class TaskListItem extends React.Component {
}
shouldRefresh(){
if (this.state.task.pending_action !== null) return true;
// If a task is completed, or failed, etc. we don't expect it to change
if ([statusCodes.COMPLETED, statusCodes.FAILED, statusCodes.CANCELED].indexOf(this.state.task.status) !== -1) return false;
return (([statusCodes.QUEUED, statusCodes.RUNNING, null].indexOf(this.state.task.status) !== -1 && this.state.task.processing_node) ||
(!this.state.task.uuid && this.state.task.processing_node && !this.state.task.last_error) ||
this.state.task.pending_action !== null);
(!this.state.task.uuid && this.state.task.processing_node && !this.state.task.last_error));
}
loadTimer(startTime){

Wyświetl plik

@ -10,4 +10,8 @@
.preset-error{
margin-top: 12px;
}
.system-preset{
background-color: #eee;
}
}

Wyświetl plik

@ -16,10 +16,15 @@ class TestApiPreset(BootTestCase):
superuser = User.objects.get(username='testsuperuser')
Preset.objects.create(owner=superuser, name='Global Preset #1', system=True, options=[{'test': True}])
Preset.objects.create(owner=superuser, name='Global Preset #2', system=True, options=[{'test2': True}])
Preset.objects.create(name='Global Preset #1', system=True, options=[{'test': True}])
Preset.objects.create(name='Global Preset #2', system=True, options=[{'test2': True}])
Preset.objects.create(owner=superuser, name='Local Preset #1', system=False, options=[{'test3': True}])
def check_default_presets(self):
self.assertTrue(Preset.objects.filter(name="Default", system=True).exists())
self.assertTrue(Preset.objects.filter(name="DSM + DTM", system=True).exists())
self.assertTrue(Preset.objects.filter(name="High Quality", system=True).exists())
def test_preset(self):
client = APIClient()
@ -48,8 +53,9 @@ class TestApiPreset(BootTestCase):
self.assertTrue(res.status_code == status.HTTP_200_OK)
# Only ours and global presets are available
self.assertTrue(len(res.data) == 3)
self.assertTrue(len(res.data) == 6)
self.assertTrue('My Local Preset' in [preset['name'] for preset in res.data])
self.assertTrue('High Quality' in [preset['name'] for preset in res.data])
self.assertTrue('Global Preset #1' in [preset['name'] for preset in res.data])
self.assertTrue('Global Preset #2' in [preset['name'] for preset in res.data])
self.assertFalse('Local Preset #1' in [preset['name'] for preset in res.data])