add installer endpoint

This commit is contained in:
Matthias 2021-11-18 01:24:14 +01:00
parent e728dc8fdf
commit a9fbfaf6af
No known key found for this signature in database
GPG Key ID: F50EF5741D33E076
2 changed files with 87 additions and 1 deletions

View File

@ -5,7 +5,7 @@ JSON API for the plugin app
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.conf.urls import url
from django.conf.urls import url, include
from django.utils.translation import ugettext_lazy as _
from rest_framework import generics
@ -56,11 +56,22 @@ class PluginDetail(generics.RetrieveUpdateDestroyAPIView):
serializer_class = PluginSerializers.PluginConfigSerializer
class PluginInstall(generics.CreateAPIView):
"""
Endpoint for installing a new plugin
"""
queryset = PluginConfig.objects.none()
serializer_class = PluginSerializers.PluginConfigInstallSerializer
plugin_api_urls = [
# Detail views for a single PluginConfig item
url(r'^(?P<pk>\d+)/', include([
url(r'^.*$', PluginDetail.as_view(), name='api-plugin-detail'),
])),
url(r'^install/', PluginInstall.as_view(), name='api-plugin-install'),
# Anything else
url(r'^.*$', PluginList.as_view(), name='api-plugin-list'),
]

View File

@ -5,6 +5,11 @@ JSON serializers for Stock app
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import os
import subprocess
from django.core.exceptions import ValidationError
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
@ -28,3 +33,73 @@ class PluginConfigSerializer(serializers.ModelSerializer):
'meta',
'mixins',
]
class PluginConfigInstallSerializer(serializers.Serializer):
"""
Serializer for installing a new plugin
"""
url = serializers.CharField(required=False)
packagename = serializers.CharField(required=False)
confirm = serializers.BooleanField()
class Meta:
fields = [
'url',
'packagename',
'confirm',
]
def validate(self, data):
super().validate(data)
# check the base requirements are met
if not data.get('confirm'):
raise ValidationError({'confirm': _('Installation not confirmed')})
if (not data.get('url')) and (not data.get('packagename')):
msg = _('Either packagenmae of url must be provided')
raise ValidationError({'url': msg, 'packagename': msg})
return data
def save(self):
data = self.validated_data
packagename = data.get('packagename', '')
url = data.get('url', '')
# build up the command
command = 'python -m pip install'.split()
if url:
# use custom registration / VCS
if True in [identifier in url for identifier in ['git+https', 'hg+https', 'svn+svn', '']]:
# using a VCS provider
if packagename:
command.append(f'{packagename}@{url}')
else:
command.append(url)
else:
# using a custom package repositories
command.append('-i')
command.append(url)
command.append(packagename)
elif packagename:
# use pypi
command.append(packagename)
ret = {'command': command}
# execute pypi
try:
result = subprocess.check_output(command, cwd=os.path.dirname(settings.BASE_DIR))
ret['result'] = str(result, 'utf-8')
except subprocess.CalledProcessError as error:
ret['result'] = str(error.output, 'utf-8')
ret['error'] = True
# register plugins
# TODO
return ret