Added settings page

pull/1122/head
Luca Di Leo 2022-01-05 06:49:33 -08:00
rodzic a9a474ad46
commit 32863c7b33
5 zmienionych plików z 169 dodań i 178 usunięć

Wyświetl plik

@ -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()

Wyświetl plik

@ -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

Wyświetl plik

@ -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
}

Wyświetl plik

@ -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)),
]

Wyświetl plik

@ -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 %}