Esempio n. 1
0
    def plugin_upload(self, request, *args, **kwargs):
        file = request.FILES.get('file')
        if file is not None:
            # Save to tmp dir
            tmp_zip_path = tempfile.mktemp('plugin.zip',
                                           dir=settings.MEDIA_TMP)
            tmp_extract_path = tempfile.mkdtemp('plugin',
                                                dir=settings.MEDIA_TMP)

            try:
                with open(tmp_zip_path, 'wb+') as fd:
                    if isinstance(file, InMemoryUploadedFile):
                        for chunk in file.chunks():
                            fd.write(chunk)
                    else:
                        with open(file.temporary_file_path(), 'rb') as f:
                            shutil.copyfileobj(f, fd)

                # Extract
                with zipfile.ZipFile(tmp_zip_path, "r") as zip_h:
                    zip_h.extractall(tmp_extract_path)

                # Validate
                folders = os.listdir(tmp_extract_path)
                if len(folders) != 1:
                    raise ValueError(
                        "The plugin has more than 1 root directory (it should have only one)"
                    )

                plugin_name = folders[0]
                plugin_path = os.path.join(tmp_extract_path, plugin_name)
                if not valid_plugin(plugin_path):
                    raise ValueError(
                        "This doesn't look like a plugin. Are plugin.py and manifest.json in the proper place?"
                    )

                if os.path.exists(get_plugins_persistent_path(plugin_name)):
                    raise ValueError(
                        "A plugin with the name {} already exist. Please remove it before uploading one with the same name."
                        .format(plugin_name))

                # Move
                shutil.move(plugin_path, get_plugins_persistent_path())

                # Initialize
                clear_plugins_cache()
                init_plugins()

                messages.info(request, "Plugin added successfully")
            except Exception as e:
                messages.warning(request,
                                 "Cannot load plugin: {}".format(str(e)))
                if os.path.exists(tmp_zip_path):
                    os.remove(tmp_zip_path)
                if os.path.exists(tmp_extract_path):
                    shutil.rmtree(tmp_extract_path)
        else:
            messages.error(request, "You need to upload a zip file")

        return HttpResponseRedirect(reverse('admin:app_plugin_changelist'))
Esempio n. 2
0
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)")

    # 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 Setting.objects.all().count() == 0:
            default_logo = os.path.join('app', 'static', 'app', 'img',
                                        'logo512.png')

            s = Setting.objects.create(app_name='WebODM', theme=default_theme)
            s.app_logo.save(os.path.basename(default_logo),
                            File(open(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."
        )