kopia lustrzana https://github.com/OpenDroneMap/WebODM
Add compact feature
rodzic
bf1118fbb3
commit
78a2c1ca18
|
@ -153,6 +153,10 @@ class TaskViewSet(viewsets.ViewSet):
|
||||||
def remove(self, *args, **kwargs):
|
def remove(self, *args, **kwargs):
|
||||||
return self.set_pending_action(pending_actions.REMOVE, *args, perms=('delete_project', ), **kwargs)
|
return self.set_pending_action(pending_actions.REMOVE, *args, perms=('delete_project', ), **kwargs)
|
||||||
|
|
||||||
|
@action(detail=True, methods=['post'])
|
||||||
|
def compact(self, *args, **kwargs):
|
||||||
|
return self.set_pending_action(pending_actions.COMPACT, *args, perms=('delete_project', ), **kwargs)
|
||||||
|
|
||||||
@action(detail=True, methods=['get'])
|
@action(detail=True, methods=['get'])
|
||||||
def output(self, request, pk=None, project_pk=None):
|
def output(self, request, pk=None, project_pk=None):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -235,6 +235,7 @@ class Task(models.Model):
|
||||||
(pending_actions.RESTART, 'RESTART'),
|
(pending_actions.RESTART, 'RESTART'),
|
||||||
(pending_actions.RESIZE, 'RESIZE'),
|
(pending_actions.RESIZE, 'RESIZE'),
|
||||||
(pending_actions.IMPORT, 'IMPORT'),
|
(pending_actions.IMPORT, 'IMPORT'),
|
||||||
|
(pending_actions.COMPACT, 'COMPACT'),
|
||||||
)
|
)
|
||||||
|
|
||||||
TASK_PROGRESS_LAST_VALUE = 0.85
|
TASK_PROGRESS_LAST_VALUE = 0.85
|
||||||
|
@ -808,6 +809,14 @@ class Task(models.Model):
|
||||||
# Stop right here!
|
# Stop right here!
|
||||||
return
|
return
|
||||||
|
|
||||||
|
elif self.pending_action == pending_actions.COMPACT:
|
||||||
|
logger.info("Compacting {}".format(self))
|
||||||
|
time.sleep(2) # Purely to make sure the user sees the "compacting..." message in the UI since this is so fast
|
||||||
|
self.compact()
|
||||||
|
self.pending_action = None
|
||||||
|
self.save()
|
||||||
|
return
|
||||||
|
|
||||||
if self.processing_node:
|
if self.processing_node:
|
||||||
# Need to update status (first time, queued or running?)
|
# Need to update status (first time, queued or running?)
|
||||||
if self.uuid and self.status in [None, status_codes.QUEUED, status_codes.RUNNING]:
|
if self.uuid and self.status in [None, status_codes.QUEUED, status_codes.RUNNING]:
|
||||||
|
@ -1142,6 +1151,18 @@ class Task(models.Model):
|
||||||
|
|
||||||
plugin_signals.task_removed.send_robust(sender=self.__class__, task_id=task_id)
|
plugin_signals.task_removed.send_robust(sender=self.__class__, task_id=task_id)
|
||||||
|
|
||||||
|
def compact(self):
|
||||||
|
# Remove all images
|
||||||
|
images_path = self.task_path()
|
||||||
|
images = [os.path.join(images_path, i) for i in self.scan_images()]
|
||||||
|
for im in images:
|
||||||
|
try:
|
||||||
|
os.unlink(im)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(e)
|
||||||
|
|
||||||
|
self.update_size(commit=True)
|
||||||
|
|
||||||
def set_failure(self, error_message):
|
def set_failure(self, error_message):
|
||||||
logger.error("FAILURE FOR {}: {}".format(self, error_message))
|
logger.error("FAILURE FOR {}: {}".format(self, error_message))
|
||||||
self.last_error = error_message
|
self.last_error = error_message
|
||||||
|
@ -1157,7 +1178,8 @@ class Task(models.Model):
|
||||||
def check_if_canceled(self):
|
def check_if_canceled(self):
|
||||||
# Check if task has been canceled/removed
|
# Check if task has been canceled/removed
|
||||||
if Task.objects.only("pending_action").get(pk=self.id).pending_action in [pending_actions.CANCEL,
|
if Task.objects.only("pending_action").get(pk=self.id).pending_action in [pending_actions.CANCEL,
|
||||||
pending_actions.REMOVE]:
|
pending_actions.REMOVE,
|
||||||
|
pending_actions.COMPACT]:
|
||||||
raise TaskInterruptedException()
|
raise TaskInterruptedException()
|
||||||
|
|
||||||
def resize_images(self):
|
def resize_images(self):
|
||||||
|
|
|
@ -3,3 +3,4 @@ REMOVE = 2
|
||||||
RESTART = 3
|
RESTART = 3
|
||||||
RESIZE = 4
|
RESIZE = 4
|
||||||
IMPORT = 5
|
IMPORT = 5
|
||||||
|
COMPACT = 6
|
||||||
|
|
|
@ -4,7 +4,8 @@ const CANCEL = 1,
|
||||||
REMOVE = 2,
|
REMOVE = 2,
|
||||||
RESTART = 3,
|
RESTART = 3,
|
||||||
RESIZE = 4,
|
RESIZE = 4,
|
||||||
IMPORT = 5;
|
IMPORT = 5,
|
||||||
|
COMPACT = 6;
|
||||||
|
|
||||||
let pendingActions = {
|
let pendingActions = {
|
||||||
[CANCEL]: {
|
[CANCEL]: {
|
||||||
|
@ -21,6 +22,9 @@ let pendingActions = {
|
||||||
},
|
},
|
||||||
[IMPORT]: {
|
[IMPORT]: {
|
||||||
descr: _("Importing...")
|
descr: _("Importing...")
|
||||||
|
},
|
||||||
|
[COMPACT]: {
|
||||||
|
descr: _("Compacting...")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,6 +34,7 @@ export default {
|
||||||
RESTART: RESTART,
|
RESTART: RESTART,
|
||||||
RESIZE: RESIZE,
|
RESIZE: RESIZE,
|
||||||
IMPORT: IMPORT,
|
IMPORT: IMPORT,
|
||||||
|
COMPACT: COMPACT,
|
||||||
|
|
||||||
description: function(pendingAction) {
|
description: function(pendingAction) {
|
||||||
if (pendingActions[pendingAction]) return pendingActions[pendingAction].descr;
|
if (pendingActions[pendingAction]) return pendingActions[pendingAction].descr;
|
||||||
|
|
|
@ -239,7 +239,7 @@ class NewTaskPanel extends React.Component {
|
||||||
ref={(domNode) => { if (domNode) this.taskForm = domNode; }}
|
ref={(domNode) => { if (domNode) this.taskForm = domNode; }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{this.state.editTaskFormLoaded && this.props.showAlign && this.state.showMapPreview ?
|
{this.state.editTaskFormLoaded && this.props.showAlign && this.state.showMapPreview && this.state.alignTasks.length > 0 ?
|
||||||
<div>
|
<div>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="col-sm-2 control-label">{_("Alignment")}</label>
|
<label className="col-sm-2 control-label">{_("Alignment")}</label>
|
||||||
|
|
|
@ -462,9 +462,11 @@ class TaskListItem extends React.Component {
|
||||||
const disabled = this.state.actionButtonsDisabled ||
|
const disabled = this.state.actionButtonsDisabled ||
|
||||||
([pendingActions.CANCEL,
|
([pendingActions.CANCEL,
|
||||||
pendingActions.REMOVE,
|
pendingActions.REMOVE,
|
||||||
|
pendingActions.COMPACT,
|
||||||
pendingActions.RESTART].indexOf(task.pending_action) !== -1);
|
pendingActions.RESTART].indexOf(task.pending_action) !== -1);
|
||||||
const editable = this.props.hasPermission("change") && [statusCodes.FAILED, statusCodes.COMPLETED, statusCodes.CANCELED].indexOf(task.status) !== -1;
|
const editable = this.props.hasPermission("change") && [statusCodes.FAILED, statusCodes.COMPLETED, statusCodes.CANCELED].indexOf(task.status) !== -1;
|
||||||
const actionLoading = this.state.actionLoading;
|
const actionLoading = this.state.actionLoading;
|
||||||
|
const showAssetButtons = task.status === statusCodes.COMPLETED;
|
||||||
|
|
||||||
let expanded = "";
|
let expanded = "";
|
||||||
if (this.state.expanded){
|
if (this.state.expanded){
|
||||||
|
@ -484,7 +486,7 @@ class TaskListItem extends React.Component {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if (task.status === statusCodes.COMPLETED){
|
if (showAssetButtons){
|
||||||
if (task.available_assets.indexOf("orthophoto.tif") !== -1 || task.available_assets.indexOf("dsm.tif") !== -1){
|
if (task.available_assets.indexOf("orthophoto.tif") !== -1 || task.available_assets.indexOf("dsm.tif") !== -1){
|
||||||
addActionButton(" " + _("View Map"), "btn-primary", "fa fa-globe", () => {
|
addActionButton(" " + _("View Map"), "btn-primary", "fa fa-globe", () => {
|
||||||
location.href = `/map/project/${task.project}/task/${task.id}/`;
|
location.href = `/map/project/${task.project}/task/${task.id}/`;
|
||||||
|
@ -534,7 +536,7 @@ class TaskListItem extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
actionButtons = (<div className="action-buttons">
|
actionButtons = (<div className="action-buttons">
|
||||||
{task.status === statusCodes.COMPLETED ?
|
{showAssetButtons ?
|
||||||
<AssetDownloadButtons task={this.state.task} disabled={disabled} />
|
<AssetDownloadButtons task={this.state.task} disabled={disabled} />
|
||||||
: ""}
|
: ""}
|
||||||
{actionButtons.map(button => {
|
{actionButtons.map(button => {
|
||||||
|
@ -672,7 +674,6 @@ class TaskListItem extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="row clearfix">
|
<div className="row clearfix">
|
||||||
<ErrorMessage bind={[this, 'actionError']} />
|
|
||||||
{actionButtons}
|
{actionButtons}
|
||||||
</div>
|
</div>
|
||||||
<TaskPluginActionButtons task={task} disabled={disabled} />
|
<TaskPluginActionButtons task={task} disabled={disabled} />
|
||||||
|
@ -734,6 +735,10 @@ class TaskListItem extends React.Component {
|
||||||
type = 'neutral';
|
type = 'neutral';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (task.pending_action === pendingActions.COMPACT){
|
||||||
|
statusIcon = 'fa fa-cog fa-spin fa-fw';
|
||||||
|
}
|
||||||
|
|
||||||
statusLabel = getStatusLabel(status, type, progress);
|
statusLabel = getStatusLabel(status, type, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -764,9 +769,16 @@ class TaskListItem extends React.Component {
|
||||||
|
|
||||||
if (this.props.hasPermission("delete")){
|
if (this.props.hasPermission("delete")){
|
||||||
taskActions.push(
|
taskActions.push(
|
||||||
<li key="sep" role="separator" className="divider"></li>,
|
<li key="sep" role="separator" className="divider"></li>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (task.status === statusCodes.COMPLETED){
|
||||||
|
addTaskAction(_("Compact"), "fa fa-database", this.genActionApiCall("compact", {
|
||||||
|
confirm: _("Compacting will free disk space by permanently deleting the original images used for processing. It will no longer be possible to restart the task. Maps and models will remain in place. Continue?"),
|
||||||
|
defaultError: _("Cannot compact task.")
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
addTaskAction(_("Delete"), "fa fa-trash", this.genActionApiCall("remove", {
|
addTaskAction(_("Delete"), "fa fa-trash", this.genActionApiCall("remove", {
|
||||||
confirm: _("All information related to this task, including images, maps and models will be deleted. Continue?"),
|
confirm: _("All information related to this task, including images, maps and models will be deleted. Continue?"),
|
||||||
defaultError: _("Cannot delete task.")
|
defaultError: _("Cannot delete task.")
|
||||||
|
@ -816,6 +828,7 @@ class TaskListItem extends React.Component {
|
||||||
: ""}
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<ErrorMessage bind={[this, 'actionError']} />
|
||||||
{expanded}
|
{expanded}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -71,7 +71,11 @@ class ProcessingNode(models.Model):
|
||||||
|
|
||||||
self.api_version = info.version
|
self.api_version = info.version
|
||||||
self.queue_count = info.task_queue_count
|
self.queue_count = info.task_queue_count
|
||||||
self.max_images = info.max_images
|
|
||||||
|
if isinstance(info.max_images, (int, float)):
|
||||||
|
self.max_images = max(0, info.max_images)
|
||||||
|
else:
|
||||||
|
self.max_images = None
|
||||||
self.engine_version = info.engine_version
|
self.engine_version = info.engine_version
|
||||||
self.engine = info.engine
|
self.engine = info.engine
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue