|
|
|
import yaml
|
|
|
|
import os.path
|
|
|
|
|
|
|
|
from django.conf import settings
|
|
|
|
from django.core.files.storage import default_storage
|
|
|
|
from django.db import models
|
|
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
|
|
|
|
from common.utils import lazyproperty
|
|
|
|
from common.db.models import JMSBaseModel
|
|
|
|
|
|
|
|
|
|
|
|
__all__ = ['Applet', 'AppletPublication']
|
|
|
|
|
|
|
|
|
|
|
|
class Applet(JMSBaseModel):
|
|
|
|
class Type(models.TextChoices):
|
|
|
|
general = 'general', _('General')
|
|
|
|
web = 'web', _('Web')
|
|
|
|
|
|
|
|
name = models.CharField(max_length=128, verbose_name=_('Name'), unique=True)
|
|
|
|
display_name = models.CharField(max_length=128, verbose_name=_('Display name'))
|
|
|
|
version = models.CharField(max_length=16, verbose_name=_('Version'))
|
|
|
|
author = models.CharField(max_length=128, verbose_name=_('Author'))
|
|
|
|
type = models.CharField(max_length=16, verbose_name=_('Type'), default='general', choices=Type.choices)
|
|
|
|
is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
|
|
|
|
protocols = models.JSONField(default=list, verbose_name=_('Protocol'))
|
|
|
|
tags = models.JSONField(default=list, verbose_name=_('Tags'))
|
|
|
|
comment = models.TextField(default='', blank=True, verbose_name=_('Comment'))
|
|
|
|
hosts = models.ManyToManyField(
|
|
|
|
through_fields=('applet', 'host'), through='AppletPublication',
|
|
|
|
to='AppletHost', verbose_name=_('Hosts')
|
|
|
|
)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
@property
|
|
|
|
def path(self):
|
|
|
|
return default_storage.path('applets/{}'.format(self.name))
|
|
|
|
|
|
|
|
@property
|
|
|
|
def manifest(self):
|
|
|
|
path = os.path.join(self.path, 'manifest.yml')
|
|
|
|
if not os.path.exists(path):
|
|
|
|
return None
|
|
|
|
with open(path, 'r') as f:
|
|
|
|
return yaml.safe_load(f)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def icon(self):
|
|
|
|
path = os.path.join(self.path, 'icon.png')
|
|
|
|
if not os.path.exists(path):
|
|
|
|
return None
|
|
|
|
return os.path.join(settings.MEDIA_URL, 'applets', self.name, 'icon.png')
|
|
|
|
|
|
|
|
|
|
|
|
class AppletPublication(JMSBaseModel):
|
|
|
|
applet = models.ForeignKey('Applet', on_delete=models.PROTECT, related_name='publications', verbose_name=_('Applet'))
|
|
|
|
host = models.ForeignKey('AppletHost', on_delete=models.PROTECT, related_name='publications', verbose_name=_('Host'))
|
|
|
|
status = models.CharField(max_length=16, default='', verbose_name=_('Status'))
|
|
|
|
comment = models.TextField(default='', blank=True, verbose_name=_('Comment'))
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
unique_together = ('applet', 'host')
|