class IWidget(models.Model): widget = models.ForeignKey('platform.Widget', verbose_name=_('Widget'), null=True) widget_uri = models.CharField(_('Widget URI'), max_length=250, null=False, blank=False) name = models.CharField(_('Name'), max_length=250) tab = models.ForeignKey('platform.Tab', verbose_name=_('Tab')) layout = models.IntegerField(_('Layout'), default=0) positions = JSONField(blank=True) refused_version = models.CharField(_('Refused Version'), max_length=150, blank=True, null=True) readOnly = models.BooleanField(_('Read Only'), default=False) variables = JSONField(blank=True) class Meta: app_label = 'platform' db_table = 'wirecloud_iwidget' def __str__(self): return str(self.pk) def set_variable_value(self, var_name, value): iwidget_info = self.widget.resource.get_processed_info( translate=False, process_variables=True) vardef = iwidget_info['variables']['all'][var_name] if vardef['secure']: from wirecloud.platform.workspace.utils import encrypt_value value = encrypt_value(value) elif vardef['type'] == 'boolean': value = bool(value) elif vardef['type'] == 'number': value = float(value) self.variables[var_name] = value def save(self, *args, **kwargs): if self.widget is not None: self.widget_uri = self.widget.resource.local_uri_part super(IWidget, self).save(*args, **kwargs) self.tab.workspace.save() # Invalidate workspace cache def delete(self, *args, **kwargs): # Delete IWidget from wiring remove_related_iwidget_connections(self.tab.workspace.wiringStatus, self) self.tab.workspace.save() # This also invalidates the workspace cache super(IWidget, self).delete(*args, **kwargs)
class IWidget(models.Model): widget = models.ForeignKey('platform.Widget', on_delete=models.SET_NULL, verbose_name=_('Widget'), null=True) widget_uri = models.CharField(_('Widget URI'), max_length=250, null=False, blank=False) name = models.CharField(_('Name'), max_length=250) tab = models.ForeignKey('platform.Tab', on_delete=models.CASCADE, verbose_name=_('Tab')) layout = models.IntegerField(_('Layout'), default=0) positions = JSONField(blank=True) readOnly = models.BooleanField(_('Read Only'), default=False) variables = JSONField(blank=True) class Meta: app_label = 'platform' db_table = 'wirecloud_iwidget' def __str__(self): return str(self.pk) def set_variable_value(self, var_name, value, user): iwidget_info = self.widget.resource.get_processed_info(translate=False, process_variables=True) vardef = iwidget_info['variables']['all'][var_name] if vardef['secure']: from wirecloud.platform.workspace.utils import encrypt_value value = encrypt_value(value) elif vardef['type'] == 'boolean': if isinstance(value, str): value = value.strip().lower() == "true" else: value = bool(value) elif vardef['type'] == 'number': value = float(value) if "users" in self.variables.get(var_name, ""): self.variables[var_name]["users"] = {"%s" % user.id: value} else: self.variables[var_name] = {"users": {"%s" % user.id: value}} def save(self, *args, **kwargs): updatecache = kwargs.pop('updatecache', True) if self.widget is not None: self.widget_uri = self.widget.resource.local_uri_part super(IWidget, self).save(*args, **kwargs) if updatecache: self.tab.workspace.save() # Invalidate workspace cache def delete(self, *args, **kwargs): # Delete IWidget from wiring remove_widget_from_wiring_status("%s" % self.id, self.tab.workspace.wiringStatus) self.tab.workspace.save() # This also invalidates the workspace cache super(IWidget, self).delete(*args, **kwargs)
class Workspace(models.Model): creator = models.ForeignKey(User, on_delete=models.CASCADE, related_name='creator', verbose_name=_('Creator'), blank=False, null=False) name = models.CharField(_('Name'), max_length=30) title = models.CharField(_('Title'), max_length=255, blank=False, null=True) creation_date = models.BigIntegerField(_('Creation Date'), null=False, blank=False, default=now_timestamp) last_modified = models.BigIntegerField(_('Last Modification Date'), null=True, blank=True) searchable = models.BooleanField(_('Searchable'), default=True) public = models.BooleanField(_('Available to all users'), default=False) users = models.ManyToManyField(User, verbose_name=_('Users'), through='UserWorkspace') groups = models.ManyToManyField(Group, verbose_name=_('Groups'), blank=True) description = models.TextField(_('Description'), max_length=140, blank=True) longdescription = models.TextField(_('Long description'), blank=True) forcedValues = JSONField(blank=True) wiringStatus = JSONField(blank=True) __original_public = False class Meta: app_label = 'platform' db_table = 'wirecloud_workspace' unique_together = ('creator', 'name') def __init__(self, *args, **kwargs): super(Workspace, self).__init__(*args, **kwargs) self.__original_public = self.public def __str__(self): return "%s/%s" % (self.creator.username, self.name) def save(self, *args, **kwargs): if self.public != self.__original_public: from wirecloud.platform.preferences.views import update_workspace_preferences update_workspace_preferences(self, {'public': {'value': self.public}}, invalidate_cache=False) self.__original_public = self.public self.last_modified = int(time.time() * 1000) if 'update_fields' in kwargs and 'last_modified' not in kwargs['update_fields']: kwargs['update_fields'] = tuple(kwargs['update_fields']) + ('last_modified',) super(Workspace, self).save(*args, **kwargs) def is_available_for(self, user): return self.public or user.is_authenticated() and (user.is_superuser or self.creator == user or self.users.filter(id=user.id).exists() or len(set(self.groups.all()) & set(user.groups.all())) > 0) def is_shared(self): return self.public or self.users.count() > 1 or self.groups.count() > 1
class Market(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name=_('User'), blank=True) name = models.CharField(_('Name'), max_length=50) public = models.BooleanField(_('Public'), default=False) options = JSONField(_('Options')) class Meta: unique_together = ('user', 'name') app_label = 'platform' db_table = 'wirecloud_market' def __str__(self): return self.user.username + '/' + self.name
class CatalogueResource(models.Model): RESOURCE_TYPES = ('widget', 'mashup', 'operator') RESOURCE_MIMETYPES = ('application/x-widget+mashable-application-component', 'application/x-mashup+mashable-application-component', 'application/x-operator+mashable-application-component') TYPE_CHOICES = ( (0, 'Widget'), (1, 'Mashup'), (2, 'Operator'), ) vendor = models.CharField(_('Vendor'), max_length=250) short_name = models.CharField(_('Name'), max_length=250) version = models.CharField(_('Version'), max_length=150) type = models.SmallIntegerField(_('Type'), choices=TYPE_CHOICES, null=False, blank=False) # Person who added the resource to catalogue! creator = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True, related_name='uploaded_resources') public = models.BooleanField(_('Available to all users'), default=False) users = models.ManyToManyField(User, verbose_name=_('Users'), related_name='local_resources', blank=True) groups = models.ManyToManyField(Group, verbose_name=_('Groups'), related_name='local_resources', blank=True) creation_date = models.DateTimeField('creation_date') template_uri = models.CharField(_('templateURI'), max_length=200, blank=True) popularity = models.DecimalField(_('popularity'), default=0, max_digits=2, decimal_places=1) json_description = JSONField(_('JSON description')) @property def local_uri_part(self): return self.vendor + '/' + self.short_name + '/' + self.version @property def cache_version_key(self): return '_catalogue_resource_version/%s' % self.id @property def cache_version(self): version = cache.get(self.cache_version_key) if version is None: version = random.randrange(1, 100000) cache.set(self.cache_version_key, version) return version def invalidate_cache(self): try: cache.incr(self.cache_version_key) except ValueError: pass def is_available_for(self, user): return self.public or self.users.filter(id=user.id).exists() or len(set(self.groups.all()) & set(user.groups.all())) > 0 def is_removable_by(self, user): return user.is_superuser or self.creator == user def get_template_url(self, request=None, for_base=False, url_pattern_name='wirecloud_catalogue.media'): return get_template_url(self.vendor, self.short_name, self.version, '' if for_base else self.template_uri, request=request, url_pattern_name=url_pattern_name) def get_template(self, request=None, url_pattern_name='wirecloud_catalogue.media'): template_uri = self.get_template_url(request=request, url_pattern_name=url_pattern_name) parser = TemplateParser(self.json_description, base=template_uri) return parser def get_processed_info(self, request=None, lang=None, process_urls=True, translate=True, process_variables=False, url_pattern_name='wirecloud_catalogue.media'): if translate and lang is None: from django.utils import translation lang = translation.get_language() else: lang = None parser = self.get_template(request, url_pattern_name=url_pattern_name) return parser.get_resource_processed_info(lang=lang, process_urls=process_urls, translate=True, process_variables=process_variables) def delete(self, *args, **kwargs): from wirecloud.catalogue.utils import wgt_deployer old_id = self.id super(CatalogueResource, self).delete(*args, **kwargs) # Preserve the id attribute a bit more so CatalogueResource methods can use it self.id = old_id # Undeploy the resource from the filesystem try: wgt_deployer.undeploy(self.vendor, self.short_name, self.version) except: # TODO log this error pass # ignore errors # Remove cache for this resource self.invalidate_cache() # Remove document from search indexes try: with get_search_engine('resource').get_batch_writer() as writer: writer.delete_by_term('pk', '%s' % old_id) except: pass # ignore errors # Remove id attribute definetly self.id = None def resource_type(self): return self.RESOURCE_TYPES[self.type] @property def mimetype(self): return self.RESOURCE_MIMETYPES[self.type] class Meta: unique_together = ("short_name", "vendor", "version") def __str__(self): return self.local_uri_part
class CatalogueResource(models.Model): RESOURCE_TYPES = ('widget', 'mashup', 'operator') RESOURCE_MIMETYPES = ( 'application/x-widget+mashable-application-component', 'application/x-mashup+mashable-application-component', 'application/x-operator+mashable-application-component') TYPE_CHOICES = ( (0, 'Widget'), (1, 'Mashup'), (2, 'Operator'), ) vendor = models.CharField(_('Vendor'), max_length=250) short_name = models.CharField(_('Name'), max_length=250) version = models.CharField(_('Version'), max_length=150) type = models.SmallIntegerField(_('Type'), choices=TYPE_CHOICES, null=False, blank=False) # Person who added the resource to catalogue! creator = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True, related_name='uploaded_resources') public = models.BooleanField(_('Available to all users'), default=False) users = models.ManyToManyField(User, verbose_name=_('Users'), related_name='local_resources', blank=True) groups = models.ManyToManyField(Group, verbose_name=_('Groups'), related_name='local_resources', blank=True) creation_date = models.DateTimeField('creation_date') # TODO: transform this field into a "trashed" field # We need to make a migration renaming files before removing it # Currently a empty value means that the resource has been marked as a trashed version when deploying a WireCloud catalogue # The idea is to track removed versions to disallow reuploading them # In those cases, users should upload a new version. This is done mimic default behaviour: https://github.com/pypa/packaging-problems/issues/74 # This field should not be used on WireCloud platform, were this behaviour is not required template_uri = models.CharField(_('templateURI'), max_length=200, blank=True) popularity = models.DecimalField(_('popularity'), default=0, max_digits=2, decimal_places=1) json_description = JSONField(_('JSON description')) @property def local_uri_part(self): return self.vendor + '/' + self.short_name + '/' + self.version @property def cache_version_key(self): return '_catalogue_resource_version/%s' % self.id @property def cache_version(self): version = cache.get(self.cache_version_key) if version is None: version = random.randrange(1, 100000) cache.set(self.cache_version_key, version) return version def invalidate_cache(self): try: cache.incr(self.cache_version_key) except ValueError: pass def is_available_for(self, user): return self.public or self.users.filter(id=user.id).exists( ) or len(set(self.groups.all()) & set(user.groups.all())) > 0 def is_removable_by(self, user, vendor=False): from wirecloud.catalogue.utils import check_vendor_permissions if user.is_superuser: return True else: return vendor is False or check_vendor_permissions( user, self.vendor) def get_template_url(self, request=None, for_base=False, url_pattern_name='wirecloud_catalogue.media'): return get_template_url(self.vendor, self.short_name, self.version, '' if for_base else self.template_uri, request=request, url_pattern_name=url_pattern_name) def get_template(self, request=None, url_pattern_name='wirecloud_catalogue.media'): template_uri = self.get_template_url(request=request, url_pattern_name=url_pattern_name) parser = TemplateParser(self.json_description, base=template_uri) return parser def get_processed_info(self, request=None, lang=None, process_urls=True, translate=True, process_variables=False, url_pattern_name='wirecloud_catalogue.media'): if translate and lang is None: from django.utils import translation lang = translation.get_language() else: lang = None parser = self.get_template(request, url_pattern_name=url_pattern_name) return parser.get_resource_processed_info( lang=lang, process_urls=process_urls, translate=True, process_variables=process_variables) def resource_type(self): return self.RESOURCE_TYPES[self.type] @property def mimetype(self): return self.RESOURCE_MIMETYPES[self.type] class Meta: unique_together = ("short_name", "vendor", "version") def __str__(self): return self.local_uri_part