kopia lustrzana https://github.com/OpenDroneMap/WebODM
New Administration menu, plugins panel, changed plugins UI enable/disable workflow
rodzic
5d269516a3
commit
e11a58739a
74
app/admin.py
74
app/admin.py
|
@ -1,8 +1,14 @@
|
|||
from django.conf.urls import url
|
||||
from django.contrib import admin
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.urls import reverse
|
||||
from django.utils.html import format_html
|
||||
from guardian.admin import GuardedModelAdmin
|
||||
|
||||
from app.models import PluginDatum
|
||||
from app.models import Preset
|
||||
from app.models import Plugin
|
||||
from app.plugins import get_plugin_by_name
|
||||
from .models import Project, Task, ImageUpload, Setting, Theme
|
||||
from django import forms
|
||||
from codemirror2.widgets import CodeMirrorEditor
|
||||
|
@ -61,5 +67,71 @@ class ThemeAdmin(admin.ModelAdmin):
|
|||
|
||||
|
||||
admin.site.register(Theme, ThemeAdmin)
|
||||
admin.site.register(PluginDatum, admin.ModelAdmin)
|
||||
|
||||
admin.site.register(PluginDatum, admin.ModelAdmin)
|
||||
|
||||
class PluginAdmin(admin.ModelAdmin):
|
||||
list_display = ("name", "description", "version", "author", "enabled", "plugin_actions")
|
||||
readonly_fields = ("name", )
|
||||
|
||||
def has_add_permission(self, request):
|
||||
return False
|
||||
def has_delete_permission(self, request, obj=None):
|
||||
return False
|
||||
|
||||
def description(self, obj):
|
||||
manifest = get_plugin_by_name(obj.name, only_active=False).get_manifest()
|
||||
return manifest.get('description', '')
|
||||
|
||||
def version(self, obj):
|
||||
manifest = get_plugin_by_name(obj.name, only_active=False).get_manifest()
|
||||
return manifest.get('version', '')
|
||||
|
||||
def author(self, obj):
|
||||
manifest = get_plugin_by_name(obj.name, only_active=False).get_manifest()
|
||||
return manifest.get('author', '')
|
||||
|
||||
def get_urls(self):
|
||||
urls = super().get_urls()
|
||||
print(urls)
|
||||
custom_urls = [
|
||||
url(
|
||||
r'^(?P<plugin_name>.+)/enable/$',
|
||||
self.admin_site.admin_view(self.plugin_enable),
|
||||
name='plugin-enable',
|
||||
),
|
||||
url(
|
||||
r'^(?P<plugin_name>.+)/disable/$',
|
||||
self.admin_site.admin_view(self.plugin_disable),
|
||||
name='plugin-disable',
|
||||
),
|
||||
]
|
||||
return custom_urls + urls
|
||||
|
||||
def plugin_enable(self, request, plugin_name, *args, **kwargs):
|
||||
p = Plugin.objects.get(pk=plugin_name)
|
||||
p.enabled = True
|
||||
p.save()
|
||||
return HttpResponseRedirect(reverse('admin:app_plugin_changelist'))
|
||||
|
||||
def plugin_disable(self, request, plugin_name, *args, **kwargs):
|
||||
p = Plugin.objects.get(pk=plugin_name)
|
||||
p.enabled = False
|
||||
p.save()
|
||||
return HttpResponseRedirect(reverse('admin:app_plugin_changelist'))
|
||||
|
||||
def plugin_actions(self, obj):
|
||||
return format_html(
|
||||
'<a class="button" href="{}" {}>Disable</a> '
|
||||
'<a class="button" href="{}" {}>Enable</a>',
|
||||
reverse('admin:plugin-disable', args=[obj.pk]) if obj.enabled else '#',
|
||||
'disabled' if not obj.enabled else '',
|
||||
reverse('admin:plugin-enable', args=[obj.pk]) if not obj.enabled else '#',
|
||||
'disabled' if obj.enabled else '',
|
||||
)
|
||||
|
||||
plugin_actions.short_description = 'Actions'
|
||||
plugin_actions.allow_tags = True
|
||||
|
||||
|
||||
admin.site.register(Plugin, PluginAdmin)
|
||||
|
|
10
app/boot.py
10
app/boot.py
|
@ -11,7 +11,7 @@ from guardian.shortcuts import assign_perm
|
|||
from worker import tasks as worker_tasks
|
||||
from app.models import Preset
|
||||
from app.models import Theme
|
||||
from app.plugins import register_plugins
|
||||
from app.plugins import init_plugins
|
||||
from nodeodm.models import ProcessingNode
|
||||
# noinspection PyUnresolvedReferences
|
||||
from webodm.settings import MEDIA_ROOT
|
||||
|
@ -81,7 +81,7 @@ def boot():
|
|||
|
||||
logger.info("Created settings")
|
||||
|
||||
register_plugins()
|
||||
init_plugins()
|
||||
|
||||
if not settings.TESTING:
|
||||
try:
|
||||
|
@ -96,6 +96,12 @@ def boot():
|
|||
|
||||
def add_default_presets():
|
||||
try:
|
||||
Preset.objects.update_or_create(name='Volume Analysis', system=True,
|
||||
defaults={'options': [{'name': 'use-opensfm-dense', 'value': True},
|
||||
{'name': 'dsm', 'value': True},
|
||||
{'name': 'dem-resolution', 'value': '2'},
|
||||
{'name': 'depthmap-resolution', 'value': '1000'},
|
||||
{'name': 'opensfm-depthmap-min-patch-sd', 'value': '0'}]})
|
||||
Preset.objects.update_or_create(name='3D Model', system=True,
|
||||
defaults={'options': [{'name': 'mesh-octree-depth', 'value': "11"},
|
||||
{'name': 'use-3dmesh', 'value': True},
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# Generated by Django 2.1.7 on 2019-03-19 16:34
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0026_update_images_count'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Plugin',
|
||||
fields=[
|
||||
('name', models.CharField(help_text='Plugin name', max_length=255, primary_key=True, serialize=False)),
|
||||
('enabled', models.BooleanField(db_index=True, default=True, help_text='Whether this plugin is enabled.')),
|
||||
],
|
||||
),
|
||||
]
|
|
@ -5,4 +5,5 @@ from .preset import Preset
|
|||
from .theme import Theme
|
||||
from .setting import Setting
|
||||
from .plugin_datum import PluginDatum
|
||||
from .plugin import Plugin
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
from django.db import models
|
||||
|
||||
|
||||
class Plugin(models.Model):
|
||||
name = models.CharField(max_length=255, primary_key=True, blank=False, null=False, help_text="Plugin name")
|
||||
enabled = models.BooleanField(db_index=True, default=True, help_text="Whether this plugin is enabled.")
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
|
@ -11,14 +11,48 @@ from string import Template
|
|||
|
||||
from django.http import HttpResponse
|
||||
|
||||
from app.models import Plugin
|
||||
from app.models import Setting
|
||||
from webodm import settings
|
||||
|
||||
logger = logging.getLogger('app.logger')
|
||||
|
||||
def register_plugins():
|
||||
for plugin in get_active_plugins():
|
||||
def init_plugins():
|
||||
build_plugins()
|
||||
sync_plugin_db()
|
||||
register_plugins()
|
||||
|
||||
def sync_plugin_db():
|
||||
"""
|
||||
Creates db entries for undiscovered plugins to keep track
|
||||
of enabled/disabled plugins
|
||||
"""
|
||||
db_plugins = Plugin.objects.all()
|
||||
fs_plugins = get_plugins()
|
||||
|
||||
# Remove plugins that are in the database but not on the file system
|
||||
for db_plugin in db_plugins:
|
||||
fs_found = next((fs_plugin for fs_plugin in fs_plugins if db_plugin.name == fs_plugin.get_name()), None)
|
||||
if not fs_found:
|
||||
Plugin.objects.filter(name=db_plugin.name).delete()
|
||||
logger.info("Cleaned [{}] plugin from database (not found in file system)".format(db_plugin.name))
|
||||
|
||||
# Add plugins found in the file system, but not yet in the database
|
||||
for plugin in get_plugins():
|
||||
# Plugins that have a "disabled" file are disabled
|
||||
disabled_path = plugin.get_path("disabled")
|
||||
disabled = os.path.isfile(disabled_path)
|
||||
if not disabled:
|
||||
_, created = Plugin.objects.get_or_create(
|
||||
name=plugin.get_name(),
|
||||
defaults={'enabled': not disabled},
|
||||
)
|
||||
if created:
|
||||
logger.info("Added [{}] plugin to database".format(plugin.get_name()))
|
||||
|
||||
|
||||
def build_plugins():
|
||||
for plugin in get_plugins():
|
||||
# Check for package.json in public directory
|
||||
# and run npm install if needed
|
||||
if plugin.path_exists("public/package.json") and not plugin.path_exists("public/node_modules"):
|
||||
|
@ -27,8 +61,6 @@ def register_plugins():
|
|||
|
||||
# Check if we need to generate a webpack.config.js
|
||||
if len(plugin.build_jsx_components()) > 0 and plugin.path_exists('public'):
|
||||
logger.info("Generating webpack.config.js for {}".format(plugin))
|
||||
|
||||
build_paths = map(lambda p: os.path.join(plugin.get_path('public'), p), plugin.build_jsx_components())
|
||||
paths_ok = not (False in map(lambda p: os.path.exists, build_paths))
|
||||
|
||||
|
@ -48,14 +80,17 @@ def register_plugins():
|
|||
with open(plugin.get_path('public/webpack.config.js'), 'w') as f:
|
||||
f.write(wpc_content)
|
||||
else:
|
||||
logger.warning("Cannot generate webpack.config.js for {}, a path is missing: {}".format(plugin, ' '.join(build_paths)))
|
||||
|
||||
logger.warning(
|
||||
"Cannot generate webpack.config.js for {}, a path is missing: {}".format(plugin, ' '.join(build_paths)))
|
||||
|
||||
# Check for webpack.config.js (if we need to build it)
|
||||
if plugin.path_exists("public/webpack.config.js") and not plugin.path_exists("public/build"):
|
||||
logger.info("Running webpack for {}".format(plugin.get_name()))
|
||||
subprocess.call(['webpack-cli'], cwd=plugin.get_path("public"))
|
||||
|
||||
|
||||
def register_plugins():
|
||||
for plugin in get_active_plugins():
|
||||
plugin.register()
|
||||
logger.info("Registered {}".format(plugin))
|
||||
|
||||
|
@ -94,22 +129,23 @@ def get_api_url_patterns():
|
|||
|
||||
return url_patterns
|
||||
|
||||
|
||||
plugins = None
|
||||
def get_active_plugins():
|
||||
def get_plugins():
|
||||
"""
|
||||
:return: all plugins instances (enabled or not)
|
||||
"""
|
||||
# Cache plugins search
|
||||
global plugins
|
||||
if plugins != None: return plugins
|
||||
|
||||
plugins = []
|
||||
plugins_path = get_plugins_path()
|
||||
plugins = []
|
||||
|
||||
for dir in [d for d in os.listdir(plugins_path) if os.path.isdir(plugins_path)]:
|
||||
# Each plugin must have a manifest.json and a plugin.py
|
||||
plugin_path = os.path.join(plugins_path, dir)
|
||||
manifest_path = os.path.join(plugin_path, "manifest.json")
|
||||
pluginpy_path = os.path.join(plugin_path, "plugin.py")
|
||||
disabled_path = os.path.join(plugin_path, "disabled")
|
||||
manifest_path = os.path.join(plugin_path, "manifest.json")
|
||||
|
||||
# Do not load test plugin unless we're in test mode
|
||||
if os.path.basename(plugin_path) == 'test' and not settings.TESTING:
|
||||
|
@ -119,37 +155,50 @@ def get_active_plugins():
|
|||
if os.path.basename(plugin_path) == '.gitignore':
|
||||
continue
|
||||
|
||||
# Check plugin required files
|
||||
if not os.path.isfile(manifest_path) or not os.path.isfile(pluginpy_path):
|
||||
logger.warning("Found invalid plugin in {}".format(plugin_path))
|
||||
continue
|
||||
|
||||
# Plugins that have a "disabled" file are disabled
|
||||
if os.path.isfile(disabled_path):
|
||||
continue
|
||||
# Instantiate the plugin
|
||||
try:
|
||||
module = importlib.import_module("plugins.{}".format(dir))
|
||||
plugin = (getattr(module, "Plugin"))()
|
||||
|
||||
# Read manifest
|
||||
with open(manifest_path) as manifest_file:
|
||||
manifest = json.load(manifest_file)
|
||||
# Check version
|
||||
manifest = plugin.get_manifest()
|
||||
if 'webodmMinVersion' in manifest:
|
||||
min_version = manifest['webodmMinVersion']
|
||||
|
||||
if versionToInt(min_version) > versionToInt(settings.VERSION):
|
||||
logger.warning("In {} webodmMinVersion is set to {} but WebODM version is {}. Plugin will not be loaded. Update WebODM.".format(manifest_path, min_version, settings.VERSION))
|
||||
logger.warning(
|
||||
"In {} webodmMinVersion is set to {} but WebODM version is {}. Plugin will not be loaded. Update WebODM.".format(
|
||||
manifest_path, min_version, settings.VERSION))
|
||||
continue
|
||||
|
||||
# Instantiate the plugin
|
||||
try:
|
||||
module = importlib.import_module("plugins.{}".format(dir))
|
||||
cls = getattr(module, "Plugin")
|
||||
plugins.append(cls())
|
||||
plugins.append(plugin)
|
||||
except Exception as e:
|
||||
logger.warning("Failed to instantiate plugin {}: {}".format(dir, e))
|
||||
|
||||
return plugins
|
||||
|
||||
|
||||
def get_plugin_by_name(name):
|
||||
plugins = get_active_plugins()
|
||||
def get_active_plugins():
|
||||
plugins = []
|
||||
enabled_plugins = [p.name for p in Plugin.objects.filter(enabled=True).all()]
|
||||
for plugin in get_plugins():
|
||||
if plugin.get_name() in enabled_plugins:
|
||||
plugins.append(plugin)
|
||||
|
||||
return plugins
|
||||
|
||||
|
||||
def get_plugin_by_name(name, only_active=True):
|
||||
if only_active:
|
||||
plugins = get_active_plugins()
|
||||
else:
|
||||
plugins = get_plugins()
|
||||
|
||||
res = list(filter(lambda p: p.get_name() == name, plugins))
|
||||
return res[0] if res else None
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import json
|
||||
import logging, os, sys
|
||||
from abc import ABC
|
||||
from app.plugins import UserDataStore, GlobalDataStore
|
||||
|
@ -7,6 +8,7 @@ logger = logging.getLogger('app.logger')
|
|||
class PluginBase(ABC):
|
||||
def __init__(self):
|
||||
self.name = self.get_module_name().split(".")[-2]
|
||||
self.manifest = None
|
||||
|
||||
def register(self):
|
||||
pass
|
||||
|
@ -130,5 +132,17 @@ class PluginBase(ABC):
|
|||
from app.plugins import get_dynamic_script_handler
|
||||
return get_dynamic_script_handler(self.get_path(script_path), callback, **template_args)
|
||||
|
||||
def get_manifest(self):
|
||||
# Lazy loading
|
||||
if self.manifest: return self.manifest
|
||||
|
||||
manifest_path = self.get_path("manifest.json")
|
||||
|
||||
# Read manifest
|
||||
with open(manifest_path) as manifest_file:
|
||||
self.manifest = json.load(manifest_file)
|
||||
|
||||
return self.manifest
|
||||
|
||||
def __str__(self):
|
||||
return "[{}]".format(self.get_module_name())
|
|
@ -9,6 +9,10 @@
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
#changelist .field-plugin_actions a[disabled]{
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.change-list .hiddenfields { display:none; }
|
||||
|
||||
.change-list .filtered table {
|
||||
|
|
|
@ -270,22 +270,25 @@
|
|||
|
||||
{% if user.is_staff %}
|
||||
<li>
|
||||
<a href="/admin/"><i class="fa fa-gears fa-fw"></i> {% trans 'Administration' %}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
<a href="/api/"><i class="fa fa-book fa-fw"></i> {% trans 'API' %}</a>
|
||||
</li>
|
||||
|
||||
{% if user.is_staff %}
|
||||
<li>
|
||||
<a href="#"><i class="fa fa-magic fa-fw"></i> {% trans 'Customize' %}<span class="fa arrow"></span></a>
|
||||
<a href="#"><i class="fa fa-gears fa-fw"></i> {% trans 'Administration' %}<span class="fa arrow"></span></a>
|
||||
<ul class="nav nav-second-level">
|
||||
<li>
|
||||
<a href="{% url 'admin:app_setting_change' SETTINGS.id %}"><i class="fa fa-hand-o-right"></i> {% trans 'Brand' %}</a>
|
||||
<a href="/admin/auth/user/"><i class="fa fa-user fa-fw"></i> {% trans 'Accounts' %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'admin:app_theme_change' SETTINGS.theme.id %}"><i class="fa fa-paint-brush"></i> {% trans 'Theme' %}</a>
|
||||
<a href="/admin/auth/group/"><i class="fa fa-group fa-fw"></i> {% trans 'Groups' %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'admin:app_setting_change' SETTINGS.id %}"><i class="fa fa-magic fa-fw"></i> {% trans 'Brand' %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'admin:app_theme_change' SETTINGS.theme.id %}"><i class="fa fa-paint-brush fa-fw"></i> {% trans 'Theme' %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/admin/app/plugin/"><i class="fa fa-plug fa-fw"></i> {% trans 'Plugins' %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/admin/app/"><i class="fa fa-gear fa-fw"></i> {% trans 'Application' %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
|
|
@ -158,6 +158,9 @@ class TestApp(BootTestCase):
|
|||
admin_menu_items = ['/admin/app/setting/{}/change/'.format(settingId),
|
||||
'/admin/app/theme/{}/change/'.format(themeId),
|
||||
'/admin/',
|
||||
'/admin/app/plugin/',
|
||||
'/admin/auth/user/',
|
||||
'/admin/auth/group/',
|
||||
]
|
||||
|
||||
for url in admin_menu_items:
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
version: '2.1'
|
||||
services:
|
||||
webapp:
|
||||
volumes:
|
||||
- ./plugins:/webodm/plugins
|
||||
worker:
|
||||
volumes:
|
||||
- ./plugins:/webodm/plugins
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"name": "Diagnostic",
|
||||
"webodmMinVersion": "0.6.2",
|
||||
"description": "description",
|
||||
"version": "0.1.0",
|
||||
"description": "Display program version, memory and disk space usage statistics",
|
||||
"version": "1.0.0",
|
||||
"author": "Piero Toffanin",
|
||||
"email": "pt@masseranolabs.com",
|
||||
"repository": "https://github.com/OpenDroneMap/WebODM",
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"name": "Lightning Network Bridge",
|
||||
"webodmMinVersion": "0.7.1",
|
||||
"description": "A plugin to sync accounts from webodm.net",
|
||||
"version": "0.1.0",
|
||||
"description": "Sync accounts from webodm.net",
|
||||
"version": "0.9.0",
|
||||
"author": "Piero Toffanin",
|
||||
"email": "pt@masseranolabs.com",
|
||||
"repository": "https://github.com/OpenDroneMap/WebODM",
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"name": "Volume/Area/Length Measurements",
|
||||
"webodmMinVersion": "0.5.0",
|
||||
"description": "A plugin to compute volume, area and length measurements on Leaflet",
|
||||
"version": "0.1.0",
|
||||
"description": "Compute volume, area and length measurements on Leaflet",
|
||||
"version": "1.0.0",
|
||||
"author": "Abdelkoddouss Izem, Piero Toffanin",
|
||||
"email": "pt@masseranolabs.com",
|
||||
"repository": "https://github.com/OpenDroneMap/WebODM",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "OpenAerialMap",
|
||||
"webodmMinVersion": "0.6.0",
|
||||
"description": "A plugin to upload orthophotos to OpenAerialMap",
|
||||
"version": "0.1.0",
|
||||
"version": "0.9.0",
|
||||
"author": "Piero Toffanin",
|
||||
"email": "pt@masseranolabs.com",
|
||||
"repository": "https://github.com/OpenDroneMap/WebODM",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "OSM Quick Editor Button",
|
||||
"webodmMinVersion": "0.5.2",
|
||||
"description": "A plugin to add a button for quickly opening OpenStreetMap's iD editor and setup a TMS basemap.",
|
||||
"version": "0.1.1",
|
||||
"version": "0.9.1",
|
||||
"author": "Piero Toffanin",
|
||||
"email": "pt@masseranolabs.com",
|
||||
"repository": "https://github.com/OpenDroneMap/WebODM",
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
"name": "POSM GCP Interface",
|
||||
"webodmMinVersion": "0.5.0",
|
||||
"description": "A plugin to create GCP files from images",
|
||||
"version": "0.1.0",
|
||||
"author": "Piero Toffanin",
|
||||
"version": "0.4.0",
|
||||
"author": "Eric Brelsford, Piero Toffanin",
|
||||
"email": "pt@masseranolabs.com",
|
||||
"repository": "https://github.com/OpenDroneMap/WebODM",
|
||||
"tags": ["gcp", "posm"],
|
||||
|
|
111
webodm.sh
111
webodm.sh
|
@ -18,16 +18,6 @@ if [[ $platform = "Windows" ]]; then
|
|||
export COMPOSE_CONVERT_WINDOWS_PATHS=1
|
||||
fi
|
||||
|
||||
# Plugin commands require us to mount a docker volume
|
||||
# but older version of Windows and certain macOS directory locations
|
||||
# require user interaction. We will add better support for these in the near future.
|
||||
plugins_volume=false
|
||||
if [[ $platform = "Linux" ]]; then
|
||||
plugins_volume=true
|
||||
elif [[ $platform = "MacOS / OSX" ]] && [[ $(pwd) == /Users* ]]; then
|
||||
plugins_volume=true
|
||||
fi
|
||||
|
||||
load_default_node=true
|
||||
dev_mode=false
|
||||
|
||||
|
@ -95,10 +85,6 @@ case $key in
|
|||
shift # past argument
|
||||
shift # past value
|
||||
;;
|
||||
--mount-plugins-volume)
|
||||
plugins_volume=true
|
||||
shift # past argument
|
||||
;;
|
||||
--no-default-node)
|
||||
load_default_node=false
|
||||
shift # past argument
|
||||
|
@ -125,13 +111,6 @@ usage(){
|
|||
echo " checkenv Do an environment check and install missing components"
|
||||
echo " test Run the unit test suite (developers only)"
|
||||
echo " resetadminpassword <new password> Reset the administrator's password to a new one. WebODM must be running when executing this command."
|
||||
if [[ $plugins_volume = true ]]; then
|
||||
echo ""
|
||||
echo " plugin enable <plugin name> Enable a plugin"
|
||||
echo " plugin disable <plugin name> Disable a plugin"
|
||||
echo " plugin list List all available plugins"
|
||||
echo " plugin cleanup Cleanup plugins build directories"
|
||||
fi
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --port <port> Set the port that WebODM should bind to (default: $DEFAULT_PORT)"
|
||||
|
@ -145,9 +124,6 @@ usage(){
|
|||
echo " --debug Enable debug for development environments (default: disabled)"
|
||||
echo " --dev Enable development mode. In development mode you can make modifications to WebODM source files and changes will be reflected live. (default: disabled)"
|
||||
echo " --broker Set the URL used to connect to the celery broker (default: $DEFAULT_BROKER)"
|
||||
if [[ $plugins_volume = false ]]; then
|
||||
echo " --mount-plugins-volume Always mount the ./plugins volume, even on unsupported platforms (developers only) (default: disabled)"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
|
@ -260,10 +236,6 @@ start(){
|
|||
echo "Will enable SSL ($method)"
|
||||
fi
|
||||
|
||||
if [[ $plugins_volume = true ]]; then
|
||||
command+=" -f docker-compose.plugins.yml"
|
||||
fi
|
||||
|
||||
run "$command start || $command up"
|
||||
}
|
||||
|
||||
|
@ -273,7 +245,6 @@ down(){
|
|||
|
||||
rebuild(){
|
||||
run "docker-compose down --remove-orphans"
|
||||
plugin_cleanup
|
||||
run "rm -fr node_modules/ || sudo rm -fr node_modules/"
|
||||
run "rm -fr nodeodm/external/NodeODM || sudo rm -fr nodeodm/external/NodeODM"
|
||||
run "docker-compose -f docker-compose.yml -f docker-compose.build.yml build --no-cache"
|
||||
|
@ -281,68 +252,6 @@ rebuild(){
|
|||
echo -e "\033[1mDone!\033[0m You can now start WebODM by running $0 start"
|
||||
}
|
||||
|
||||
plugin_cleanup(){
|
||||
# Delete all node_modules and build directories within plugins' public/ folders
|
||||
find plugins/ -type d \( -name build -o -name node_modules \) -path 'plugins/*/public/*' -exec rm -frv '{}' \;
|
||||
}
|
||||
|
||||
plugin_list(){
|
||||
plugins=$(ls plugins/ --hide test)
|
||||
for plugin in $plugins; do
|
||||
if [ -e "plugins/$plugin/disabled" ]; then
|
||||
echo "$plugin [disabled]"
|
||||
else
|
||||
echo "$plugin"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
plugin_check(){
|
||||
plugin_name="$1"
|
||||
if [ ! -e "plugins/$plugin_name" ]; then
|
||||
echo "Plugin $plugin_name does not exist."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
plugin_volume_check(){
|
||||
if [[ $plugins_volume = false ]]; then
|
||||
path=$(realpath ./plugins)
|
||||
echo "================"
|
||||
echo "WARNING: Your platform does not support automatic volume mounting. If you want to enable/disable/develop plugins you need to:"
|
||||
echo "1. Make sure docker can mount [$path] by modifying the docker File Sharing options"
|
||||
echo "2. Pass the --mount-plugins-volume option to ./webodm.sh commands"
|
||||
echo "================"
|
||||
echo
|
||||
fi
|
||||
}
|
||||
|
||||
plugin_enable(){
|
||||
plugin_name="$1"
|
||||
plugin_check $plugin_name
|
||||
plugin_volume_check
|
||||
|
||||
if [ -e "plugins/$plugin_name/disabled" ]; then
|
||||
rm "plugins/$plugin_name/disabled"
|
||||
echo "Plugin enabled. Run ./webodm.sh restart to apply the changes."
|
||||
else
|
||||
echo "Plugin already enabled."
|
||||
fi
|
||||
}
|
||||
|
||||
plugin_disable(){
|
||||
plugin_name="$1"
|
||||
plugin_check $plugin_name
|
||||
plugin_volume_check
|
||||
|
||||
if [ ! -e "plugins/$plugin_name/disabled" ]; then
|
||||
touch "plugins/$plugin_name/disabled"
|
||||
echo "Plugin disabled. Run ./webodm.sh restart to apply the changes."
|
||||
else
|
||||
echo "Plugin already disabled."
|
||||
fi
|
||||
}
|
||||
|
||||
run_tests(){
|
||||
# If in a container, we run the actual test commands
|
||||
# otherwise we launch this command from the container
|
||||
|
@ -417,26 +326,6 @@ elif [[ $1 = "test" ]]; then
|
|||
run_tests
|
||||
elif [[ $1 = "resetadminpassword" ]]; then
|
||||
resetpassword $2
|
||||
elif [[ $1 = "plugin" ]]; then
|
||||
if [[ $2 = "cleanup" ]]; then
|
||||
plugin_cleanup
|
||||
elif [[ $2 = "list" ]]; then
|
||||
plugin_list
|
||||
elif [[ $2 = "enable" ]]; then
|
||||
if [[ ! -z "$3" ]]; then
|
||||
plugin_enable $3
|
||||
else
|
||||
usage
|
||||
fi
|
||||
elif [[ $2 = "disable" ]]; then
|
||||
if [[ ! -z "$3" ]]; then
|
||||
plugin_disable $3
|
||||
else
|
||||
usage
|
||||
fi
|
||||
else
|
||||
usage
|
||||
fi
|
||||
else
|
||||
usage
|
||||
fi
|
||||
|
|
Ładowanie…
Reference in New Issue