OpenDroneMap-WebODM/app/boot.py

169 wiersze
9.4 KiB
Python

import os
import sys
import kombu
from django.contrib.auth.models import Permission
from django.contrib.auth.models import User, Group
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
from django.core.files import File
from django.db.utils import ProgrammingError
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 init_plugins
from nodeodm.models import ProcessingNode
# noinspection PyUnresolvedReferencesapp/boot.py#L20
from webodm.settings import MEDIA_ROOT
from . import signals
import logging
from .models import Task, Setting
from webodm import settings
from webodm.wsgi import booted
def boot():
# booted is a shared memory variable to keep track of boot status
# as multiple gunicorn workers could trigger the boot sequence twice
if (not settings.DEBUG and booted.value) or settings.MIGRATING: return
booted.value = True
logger = logging.getLogger('app.logger')
logger.info("Booting WebODM {}".format(settings.VERSION))
if settings.DEBUG:
logger.warning("Debug mode is ON (for development this is OK)")
# Silence django's "Warning: Session data corrupted" messages
session_logger = logging.getLogger("django.security.SuspiciousSession")
session_logger.disabled = True
# Make sure our app/media/tmp folder exists
if not os.path.exists(settings.MEDIA_TMP):
os.makedirs(settings.MEDIA_TMP)
# Check default group
try:
default_group, created = Group.objects.get_or_create(name='Default')
if created:
logger.info("Created default group")
# Assign viewprocessing node object permission to default processing node (if present)
# Otherwise non-root users will not be able to process
try:
pnode = ProcessingNode.objects.get(hostname="node-odm-1")
assign_perm('view_processingnode', default_group, pnode)
logger.info("Added view_processingnode permissions to default group")
except ObjectDoesNotExist:
pass
# Add default permissions (view_project, change_project, delete_project, etc.)
for permission in ('_project', '_task', '_preset'):
default_group.permissions.add(
*list(Permission.objects.filter(codename__endswith=permission))
)
# Add permission to view processing nodes
default_group.permissions.add(Permission.objects.get(codename="view_processingnode"))
add_default_presets()
# Add settings
default_theme, created = Theme.objects.get_or_create(name='Default')
if created:
logger.info("Created default theme")
if settings.DEFAULT_THEME_CSS:
default_theme.css = settings.DEFAULT_THEME_CSS
default_theme.save()
if Setting.objects.all().count() == 0:
s = Setting.objects.create(
app_name=settings.APP_NAME,
theme=default_theme)
s.app_logo.save(os.path.basename(settings.APP_DEFAULT_LOGO), File(open(settings.APP_DEFAULT_LOGO, 'rb')))
logger.info("Created settings")
init_plugins()
if not settings.TESTING:
try:
worker_tasks.update_nodes_info.delay()
except kombu.exceptions.OperationalError as e:
logger.error("Cannot connect to celery broker at {}. Make sure that your redis-server is running at that address: {}".format(settings.CELERY_BROKER_URL, str(e)))
except ProgrammingError:
logger.warning("Could not touch the database. If running a migration, this is expected.")
def add_default_presets():
try:
Preset.objects.update_or_create(name='Multispectral', system=True,
defaults={'options': [{'name': 'auto-boundary', 'value': True},
{'name': 'radiometric-calibration', 'value': 'camera'}]})
Preset.objects.update_or_create(name='Volume Analysis', system=True,
defaults={'options': [{'name': 'auto-boundary', 'value': True},
{'name': 'dsm', 'value': True},
{'name': 'dem-resolution', 'value': '2'},
{'name': 'pc-quality', 'value': 'high'},
{'name': 'use-3dmesh', 'value': True}]})
Preset.objects.update_or_create(name='3D Model', system=True,
defaults={'options': [{'name': 'auto-boundary', 'value': True},
{'name': 'mesh-octree-depth', 'value': "12"},
{'name': 'use-3dmesh', 'value': True},
{'name': 'pc-quality', 'value': 'high'},
{'name': 'mesh-size', 'value': '300000'}]})
Preset.objects.update_or_create(name='Buildings', system=True,
defaults={'options': [{'name': 'auto-boundary', 'value': True},
{'name': 'mesh-size', 'value': '300000'},
{'name': 'pc-geometric', 'value': True},
{'name': 'feature-quality', 'value': 'high'},
{'name': 'pc-quality', 'value': 'high'}]})
Preset.objects.update_or_create(name='Buildings Ultra Quality', system=True,
defaults={'options': [{'name': 'auto-boundary', 'value': True},
{'name': 'mesh-size', 'value': '300000'},
{'name': 'pc-geometric', 'value': True},
{'name': 'feature-quality', 'value': 'ultra'},
{'name': 'pc-quality', 'value': 'ultra'}]})
Preset.objects.update_or_create(name='Point of Interest', system=True,
defaults={'options': [{'name': 'auto-boundary', 'value': True},
{'name': 'mesh-size', 'value': '300000'},
{'name': 'use-3dmesh', 'value': True}]})
Preset.objects.update_or_create(name='Forest', system=True,
defaults={'options': [{'name': 'auto-boundary', 'value': True},
{'name': 'min-num-features', 'value': '18000'},
{'name': 'use-3dmesh', 'value': True},
{'name': 'feature-quality', 'value': 'ultra'}]})
Preset.objects.update_or_create(name='DSM + DTM', system=True,
defaults={'options': [{'name': 'auto-boundary', 'value': True},
{'name': 'dsm', 'value': True},
{'name': 'dtm', 'value': True}]})
Preset.objects.update_or_create(name='Field', system=True,
defaults={'options': [{'name': 'sfm-algorithm', 'value': 'planar'},
{'name': 'fast-orthophoto', 'value': True},
{'name': 'matcher-neighbors', 'value': 4}]})
Preset.objects.update_or_create(name='Fast Orthophoto', system=True,
defaults={'options': [{'name': 'auto-boundary', 'value': True},
{'name': 'fast-orthophoto', 'value': True}]})
Preset.objects.update_or_create(name='High Resolution', system=True,
defaults={'options': [{'name': 'auto-boundary', 'value': True},
{'name': 'dsm', 'value': True},
{'name': 'pc-quality', 'value': 'high'},
{'name': 'dem-resolution', 'value': "2.0"},
{'name': 'orthophoto-resolution', 'value': "2.0"}]})
Preset.objects.update_or_create(name='Default', system=True,
defaults={'options': [{'name': 'auto-boundary', 'value': True},
{'name': 'dsm', 'value': True}]})
except MultipleObjectsReturned:
# Mostly to handle a legacy code problem where
# multiple system presets with the same name were
# created if we changed the options
Preset.objects.filter(system=True).delete()
add_default_presets()