kopia lustrzana https://github.com/OpenDroneMap/WebODM
Added settings page
rodzic
a9a474ad46
commit
32863c7b33
|
@ -14,124 +14,125 @@ from rest_framework import status
|
|||
|
||||
#from .platform_helper import get_all_platforms, get_platform_by_name
|
||||
|
||||
class ImportFolderTaskView(TaskView):
|
||||
def post(self, request, project_pk=None, pk=None):
|
||||
task = self.get_and_check_task(request, pk)
|
||||
# class ImportFolderTaskView(TaskView):
|
||||
# def post(self, request, project_pk=None, pk=None):
|
||||
# task = self.get_and_check_task(request, pk)
|
||||
|
||||
|
||||
# Read form data
|
||||
folder_url = request.data.get('selectedFolderUrl', None)
|
||||
platform_name = request.data.get('platform', None)
|
||||
# folder_url = request.data.get('selectedFolderUrl', None)
|
||||
# platform_name = request.data.get('platform', None)
|
||||
|
||||
# Make sure both values are set
|
||||
if folder_url == None or platform_name == None:
|
||||
return Response({'error': 'Folder URL and platform name must be set.'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
# # Make sure both values are set
|
||||
# if folder_url == None or platform_name == None:
|
||||
# return Response({'error': 'Folder URL and platform name must be set.'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# Fetch the platform by name
|
||||
platform = get_platform_by_name(platform_name)
|
||||
# # Fetch the platform by name
|
||||
# platform = get_platform_by_name(platform_name)
|
||||
|
||||
# Make sure that the platform actually exists
|
||||
if platform == None:
|
||||
return Response({'error': 'Failed to find a platform with the name \'{}\''.format(platform_name)}, status=status.HTTP_400_BAD_REQUEST)
|
||||
# # Make sure that the platform actually exists
|
||||
# if platform == None:
|
||||
# return Response({'error': 'Failed to find a platform with the name \'{}\''.format(platform_name)}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# Verify that the folder url is valid
|
||||
if platform.verify_folder_url(folder_url) == None:
|
||||
return Response({'error': 'Invalid URL'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
# # Verify that the folder url is valid
|
||||
# if platform.verify_folder_url(folder_url) == None:
|
||||
# return Response({'error': 'Invalid URL'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# Get the files from the folder
|
||||
files = platform.import_from_folder(folder_url)
|
||||
# # Get the files from the folder
|
||||
# files = platform.import_from_folder(folder_url)
|
||||
|
||||
# Update the task with the new information
|
||||
task.console_output += "Importing {} images...\n".format(len(files))
|
||||
task.images_count = len(files)
|
||||
task.pending_action = pending_actions.IMPORT
|
||||
task.save()
|
||||
# # Update the task with the new information
|
||||
# task.console_output += "Importing {} images...\n".format(len(files))
|
||||
# task.images_count = len(files)
|
||||
# task.pending_action = pending_actions.IMPORT
|
||||
# task.save()
|
||||
|
||||
# Associate the folder url with the project and task
|
||||
combined_id = "{}_{}".format(project_pk, pk)
|
||||
get_current_plugin().get_global_data_store().set_string(combined_id, folder_url)
|
||||
# # Associate the folder url with the project and task
|
||||
# combined_id = "{}_{}".format(project_pk, pk)
|
||||
# get_current_plugin().get_global_data_store().set_string(combined_id, folder_url)
|
||||
|
||||
# Start importing the files in the background
|
||||
serialized = [file.serialize() for file in files]
|
||||
run_function_async(import_files, task.id, serialized)
|
||||
# # Start importing the files in the background
|
||||
# serialized = [file.serialize() for file in files]
|
||||
# run_function_async(import_files, task.id, serialized)
|
||||
|
||||
return Response({}, status=status.HTTP_200_OK)
|
||||
# return Response({}, status=status.HTTP_200_OK)
|
||||
|
||||
class CheckUrlTaskView(TaskView):
|
||||
def get(self, request, project_pk=None, pk=None):
|
||||
# class CheckUrlTaskView(TaskView):
|
||||
# def get(self, request, project_pk=None, pk=None):
|
||||
|
||||
# Assert that task exists
|
||||
self.get_and_check_task(request, pk)
|
||||
# # Assert that task exists
|
||||
# self.get_and_check_task(request, pk)
|
||||
|
||||
# Check if there is an imported url associated with the project and task
|
||||
combined_id = "{}_{}".format(project_pk, pk)
|
||||
folder_url = get_current_plugin().get_global_data_store().get_string(combined_id, default = None)
|
||||
# # Check if there is an imported url associated with the project and task
|
||||
# combined_id = "{}_{}".format(project_pk, pk)
|
||||
# folder_url = get_current_plugin().get_global_data_store().get_string(combined_id, default = None)
|
||||
|
||||
if folder_url == None:
|
||||
return Response({}, status=status.HTTP_200_OK)
|
||||
else:
|
||||
return Response({'folder_url': folder_url}, status=status.HTTP_200_OK)
|
||||
# if folder_url == None:
|
||||
# return Response({}, status=status.HTTP_200_OK)
|
||||
# else:
|
||||
# return Response({'folder_url': folder_url}, status=status.HTTP_200_OK)
|
||||
|
||||
class PlatformsVerifyTaskView(TaskView):
|
||||
def get(self, request, platform_name):
|
||||
# Read the form data
|
||||
folder_url = request.GET.get('folderUrl', None)
|
||||
# class PlatformsVerifyTaskView(TaskView):
|
||||
# def get(self, request, platform_name):
|
||||
# # Read the form data
|
||||
# folder_url = request.GET.get('folderUrl', None)
|
||||
|
||||
# Fetch the platform by name
|
||||
platform = get_platform_by_name(platform_name)
|
||||
# # Fetch the platform by name
|
||||
# platform = get_platform_by_name(platform_name)
|
||||
|
||||
# Make sure that the platform actually exists
|
||||
if platform == None:
|
||||
return Response({'error': 'Failed to find a platform with the name \'{}\''.format(platform_name)}, status=status.HTTP_400_BAD_REQUEST)
|
||||
# # Make sure that the platform actually exists
|
||||
# if platform == None:
|
||||
# return Response({'error': 'Failed to find a platform with the name \'{}\''.format(platform_name)}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# Verify that the folder url is valid
|
||||
folder = platform.verify_folder_url(folder_url)
|
||||
if folder == None:
|
||||
return Response({'error': 'Invalid URL'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
# # Verify that the folder url is valid
|
||||
# folder = platform.verify_folder_url(folder_url)
|
||||
# if folder == None:
|
||||
# return Response({'error': 'Invalid URL'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# Return the folder
|
||||
return Response({'folder': folder.serialize()}, status=status.HTTP_200_OK)
|
||||
# # Return the folder
|
||||
# return Response({'folder': folder.serialize()}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class PlatformsTaskView(TaskView):
|
||||
def get(self, request):
|
||||
# Fetch and return all platforms
|
||||
platforms = get_all_platforms()
|
||||
return Response({'platforms': [platform.serialize(user = request.user) for platform in platforms]}, status=status.HTTP_200_OK)
|
||||
# # class PlatformsTaskView(TaskView):
|
||||
# # def get(self, request):
|
||||
# # # Fetch and return all platforms
|
||||
# # platforms = get_all_platforms()
|
||||
# # return Response({'platforms': [platform.serialize(user = request.user) for platform in platforms]}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
def import_files(task_id, files):
|
||||
import requests
|
||||
from app import models
|
||||
from app.plugins import logger
|
||||
# def import_files(task_id, files):
|
||||
# import requests
|
||||
# from app import models
|
||||
# from app.plugins import logger
|
||||
|
||||
def download_file(task, file):
|
||||
path = task.task_path(file['name'])
|
||||
download_stream = requests.get(file['url'], stream=True, timeout=60)
|
||||
# def download_file(task, file):
|
||||
# path = task.task_path(file['name'])
|
||||
# download_stream = requests.get(file['url'], stream=True, timeout=60)
|
||||
|
||||
with open(path, 'wb') as fd:
|
||||
for chunk in download_stream.iter_content(4096):
|
||||
fd.write(chunk)
|
||||
# with open(path, 'wb') as fd:
|
||||
# for chunk in download_stream.iter_content(4096):
|
||||
# fd.write(chunk)
|
||||
|
||||
models.ImageUpload.objects.create(task=task, image=path)
|
||||
# models.ImageUpload.objects.create(task=task, image=path)
|
||||
|
||||
logger.info("Will import {} files".format(len(files)))
|
||||
task = models.Task.objects.get(pk=task_id)
|
||||
task.create_task_directories()
|
||||
task.save()
|
||||
# logger.info("Will import {} files".format(len(files)))
|
||||
# task = models.Task.objects.get(pk=task_id)
|
||||
# task.create_task_directories()
|
||||
# task.save()
|
||||
|
||||
try:
|
||||
downloaded_total = 0
|
||||
for file in files:
|
||||
download_file(task, file)
|
||||
task.check_if_canceled()
|
||||
models.Task.objects.filter(pk=task.id).update(upload_progress=(float(downloaded_total) / float(len(files))))
|
||||
downloaded_total += 1
|
||||
# try:
|
||||
# downloaded_total = 0
|
||||
# for file in files:
|
||||
# download_file(task, file)
|
||||
# task.check_if_canceled()
|
||||
# models.Task.objects.filter(pk=task.id).update(upload_progress=(float(downloaded_total) / float(len(files))))
|
||||
# downloaded_total += 1
|
||||
|
||||
except (requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
|
||||
raise NodeServerError(e)
|
||||
# except (requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
|
||||
# raise NodeServerError(e)
|
||||
|
||||
task.refresh_from_db()
|
||||
task.pending_action = None
|
||||
task.processing_time = 0
|
||||
task.partial = False
|
||||
task.save()
|
||||
# task.refresh_from_db()
|
||||
# task.pending_action = None
|
||||
# task.processing_time = 0
|
||||
# task.partial = False
|
||||
# task.save()
|
||||
|
|
|
@ -10,57 +10,16 @@ from app.plugins import logger
|
|||
|
||||
#from .platform_helper import get_all_extended_platforms
|
||||
|
||||
""" class DynamicForm(forms.Form):
|
||||
"""This dynamic form will go through all the extended platforms, and retrieve their fields"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
ds = kwargs.pop('data_store')
|
||||
super(DynamicForm, self).__init__(*args, **kwargs)
|
||||
extended_platforms = get_all_extended_platforms()
|
||||
|
||||
for platform in extended_platforms:
|
||||
for form_field in platform.get_form_fields():
|
||||
django_field = form_field.get_django_field(ds)
|
||||
django_field.group = platform.name
|
||||
self.fields[form_field.field_id] = django_field
|
||||
"""
|
||||
|
||||
def HomeView(plugin):
|
||||
@login_required
|
||||
def view(request):
|
||||
""" ds = plugin.get_user_data_store(request.user)
|
||||
# def LoadButtonsView(plugin):
|
||||
# def view(request):
|
||||
|
||||
# if this is a POST request we need to process the form data
|
||||
if request.method == "POST":
|
||||
form = DynamicForm(request.POST, data_store = ds)
|
||||
if form.is_valid():
|
||||
extended_platforms = get_all_extended_platforms()
|
||||
for platform in extended_platforms:
|
||||
for form_field in platform.get_form_fields():
|
||||
form_field.save_value(ds, form)
|
||||
|
||||
messages.success(request, "Configuration updated successfuly!")
|
||||
else:
|
||||
form = DynamicForm(data_store = ds) """
|
||||
# return render(
|
||||
# request,
|
||||
# plugin.template_path("load_buttons.js"),
|
||||
# {
|
||||
# "api_url": "/api" + plugin.public_url("").rstrip("/"),
|
||||
# },
|
||||
# content_type="text/javascript",
|
||||
# )
|
||||
|
||||
return render(
|
||||
request,
|
||||
plugin.template_path("app.html"),
|
||||
{"title": "DroneDB"},
|
||||
)
|
||||
|
||||
return view
|
||||
|
||||
|
||||
def LoadButtonsView(plugin):
|
||||
def view(request):
|
||||
|
||||
return render(
|
||||
request,
|
||||
plugin.template_path("load_buttons.js"),
|
||||
{
|
||||
"api_url": "/api" + plugin.public_url("").rstrip("/"),
|
||||
},
|
||||
content_type="text/javascript",
|
||||
)
|
||||
|
||||
return view
|
||||
# return view
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "DroneDB",
|
||||
"webodmMinVersion": "1.1.2",
|
||||
"description": "Integrate WebODM with DroneDB: import images and export results",
|
||||
"version": "0.0.1",
|
||||
"author": "Luca Di Leo",
|
||||
"email": "ldileo@digipa.it",
|
||||
"repository": "https://github.com/OpenDroneMap/WebODM",
|
||||
"tags": ["ddb", "DroneDB", "cloud"],
|
||||
"homepage": "https://github.com/OpenDroneMap/WebODM",
|
||||
"experimental": true,
|
||||
"deprecated": false
|
||||
}
|
|
@ -1,25 +1,33 @@
|
|||
from app.plugins import PluginBase, Menu, MountPoint, logger
|
||||
|
||||
from .api_views import PlatformsTaskView, PlatformsVerifyTaskView, ImportFolderTaskView, CheckUrlTaskView
|
||||
from .app_views import HomeView, LoadButtonsView
|
||||
#from .api_views import PlatformsTaskView, PlatformsVerifyTaskView, ImportFolderTaskView, CheckUrlTaskView
|
||||
#from .app_views import HomeView, LoadButtonsView
|
||||
#from .platform_helper import get_all_extended_platforms
|
||||
from django.contrib import messages
|
||||
from django.shortcuts import render
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django import forms
|
||||
|
||||
class SettingsForm(forms.Form):
|
||||
registry_url = forms.CharField(label='Registry Url', required=False, max_length=1024, widget=forms.TextInput(attrs={'placeholder': 'Registry Url'}))
|
||||
username = forms.CharField(label='Username', required=False, max_length=1024, widget=forms.TextInput(attrs={'placeholder': 'Username'}))
|
||||
password = forms.CharField(label='Password', required=False, max_length=1024, widget=forms.PasswordInput(attrs={'placeholder': 'Password'}))
|
||||
|
||||
class Plugin(PluginBase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def main_menu(self):
|
||||
return [Menu("DroneDB", self.public_url(""), "fa-cloud-download-alt fa fa-fw")]
|
||||
return [Menu("DroneDB", self.public_url(""), "fas fa-cloud fa-fw")]
|
||||
|
||||
def include_js_files(self):
|
||||
return ["load_buttons.js"]
|
||||
#def include_js_files(self):
|
||||
# return ["load_buttons.js"]
|
||||
|
||||
def include_css_files(self):
|
||||
return ["build/ImportView.css", "build/TaskView.css"]
|
||||
#def include_css_files(self):
|
||||
# return ["build/ImportView.css", "build/TaskView.css"]
|
||||
|
||||
def build_jsx_components(self):
|
||||
return ["ImportView.jsx", "TaskView.jsx"]
|
||||
#def build_jsx_components(self):
|
||||
# return ["ImportView.jsx", "TaskView.jsx"]
|
||||
|
||||
""" def api_mount_points(self):
|
||||
#api_views = [api_view for platform in get_all_extended_platforms() for api_view in platform.get_api_views()]
|
||||
|
@ -33,8 +41,33 @@ class Plugin(PluginBase):
|
|||
MountPoint("platforms", PlatformsTaskView.as_view()),
|
||||
] """
|
||||
|
||||
def HomeView(self):
|
||||
@login_required
|
||||
def home(request):
|
||||
ds = self.get_user_data_store(request.user)
|
||||
|
||||
# if this is a POST request we need to process the form data
|
||||
if request.method == 'POST':
|
||||
form = SettingsForm(request.POST)
|
||||
if form.is_valid():
|
||||
ds.set_string('registry_url', form.cleaned_data['registry_url'])
|
||||
ds.set_string('username', form.cleaned_data['username'])
|
||||
ds.set_string('password', form.cleaned_data['password'])
|
||||
messages.success(request, 'Settings updated.')
|
||||
|
||||
form = SettingsForm(initial={'username': ds.get_string('username', default=""),
|
||||
'password': ds.get_string('password', default=""),
|
||||
'registry_url': ds.get_string('registry_url', default="https://hub.dronedb.app")})
|
||||
|
||||
return render(request, self.template_path("app.html"), {
|
||||
'title': 'DroneDB',
|
||||
'form': form
|
||||
})
|
||||
|
||||
return home
|
||||
|
||||
def app_mount_points(self):
|
||||
return [
|
||||
MountPoint("$", HomeView(self)),
|
||||
MountPoint("load_buttons.js$", LoadButtonsView(self)),
|
||||
]
|
||||
MountPoint("$", self.HomeView()),
|
||||
#MountPoint("load_buttons.js$", LoadButtonsView(self)),
|
||||
]
|
|
@ -1,31 +1,16 @@
|
|||
{% extends "app/plugins/templates/base.html" %}
|
||||
{% load bootstrap_extras %}
|
||||
{% block content %}
|
||||
<h3>Welcome to Cloud Import!</h3>
|
||||
<h3>Welcome to DroneDB!</h3>
|
||||
<h5><strong>Instructions</strong></h5>
|
||||
On this screen, you will be able to configure everything that is necessary for your different platforms.<BR/>
|
||||
You might need to set up a server URL, an authentication token or something else. If so, this is the place!
|
||||
<BR/>
|
||||
<BR/>
|
||||
<h3>Platforms</h3>
|
||||
<form action="" method="post" class="oam-form">
|
||||
On this screen, you can provide the registry url and credentials to access DroneDB
|
||||
<br/>
|
||||
<br/>
|
||||
<form action="" method="post" class="oam-form oam-token-form">
|
||||
<h4>Settings</h4>
|
||||
{% csrf_token %}
|
||||
{% regroup form by field.group as field_groups %}
|
||||
{% for field_group in field_groups %}
|
||||
<h4><strong>{{field_group.grouper}}</strong></h4>
|
||||
{% for field in field_group.list %}
|
||||
<div class="form-group {% if field.errors %}has-error{% endif %}">
|
||||
<label for="{{ field.id_for_label }}" class="control-label">{{ field.label }}</label>
|
||||
{{ field|with_class:'form-control' }}
|
||||
{% if field.errors %}
|
||||
<span class='text-danger'>{{ field.errors|join:'<br />' }}</span>
|
||||
{% elif field.help_text %}
|
||||
<span class="help-block ">{{ field.help_text }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save fa-fw"></i> Save Configuration</button>
|
||||
{% include "app/plugins/templates/form.html" %}
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-save fa-fw"></i> Save Configuration</i></button>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
|
|
Ładowanie…
Reference in New Issue