class ExperimentParameter(models.Model): parameterset = models.ForeignKey(ExperimentParameterSet) name = models.ForeignKey(ParameterName) string_value = models.TextField(null=True, blank=True, db_index=True) numerical_value = models.FloatField(null=True, blank=True, db_index=True) datetime_value = models.DateTimeField(null=True, blank=True, db_index=True) objects = OracleSafeManager() def save(self, *args, **kwargs): super(ExperimentParameter, self).save(*args, **kwargs) try: from .hooks import publish_public_expt_rifcs publish_public_expt_rifcs(self.parameterset.experiment) except StandardError: logger.exception('') def get(self): return _getParameter(self) def __unicode__(self): return 'Experiment Param: %s=%s' % (self.name.name, self.get()) class Meta: app_label = 'tardis_portal' ordering = ['name']
class Dataset(models.Model): """Class to link datasets to experiments :attribute experiment: a forign key to the :class:`tardis.tardis_portal.models.Experiment` :attribute description: description of this dataset """ experiment = models.ForeignKey(Experiment) description = models.TextField(blank=True) immutable = models.BooleanField(default=False) objects = OracleSafeManager() def getParameterSets(self, schemaType=None): """Return the dataset parametersets associated with this experiment. """ if schemaType == Schema.DATASET or schemaType is None: return self.datasetparameterset_set.filter( schema__type=Schema.DATASET) else: raise Schema.UnsupportedType def addDatafile(self, filepath, protocol='', url='', size=None, commit=True): """Add Datafile helper function :param filepath: the file path within the repository :type filepath: string """ full_file_path = path.join(settings.FILE_STORE_PATH, str(self.experiment.id), filepath) datafile = Dataset_File(dataset=self) datafile.filename = path.basename(filepath) if protocol: datafile.protocol = protocol if url: datafile.url = url else: datafile.url = 'file://' + filepath if size: datafile.size = size elif path.exists(full_file_path): datafile.size = path.getsize(full_file_path) def __unicode__(self): return self.description def get_absolute_filepath(self): return path.join(self.experiment.get_absolute_filepath(), str(self.id))
class Parameter(models.Model): name = models.ForeignKey(ParameterName) string_value = models.TextField(null=True, blank=True, db_index=True) numerical_value = models.FloatField(null=True, blank=True, db_index=True) datetime_value = models.DateTimeField(null=True, blank=True, db_index=True) objects = OracleSafeManager() parameter_type = 'Abstract' class Meta: abstract = True app_label = 'tardis_portal' ordering = ['name'] def get(self): return _getParameter(self) def __unicode__(self): try: return '%s Param: %s=%s' % (self.parameter_type, self.name.name, self.get()) except: return 'Unitialised %sParameter' % self.parameter_type def set_value(self, value): if self.name.isNumeric(): self.numerical_value = float(value) elif self.name.isDateTime(): if settings.USE_TZ and is_naive(value): value = make_aware(value, LOCAL_TZ) elif not settings.USE_TZ and is_aware(value): value = make_naive(value, LOCAL_TZ) self.datetime_value = value else: self.string_value = unicode(value) def _has_any_perm(self, user_obj): if not hasattr(self, 'id'): return False return self.parameterset def _has_view_perm(self, user_obj): return self._has_any_perm(user_obj) def _has_change_perm(self, user_obj): return self._has_any_perm(user_obj) def _has_delete_perm(self, user_obj): return self._has_any_perm(user_obj)
class DatasetParameter(models.Model): parameterset = models.ForeignKey(DatasetParameterSet) name = models.ForeignKey(ParameterName) string_value = models.TextField(null=True, blank=True, db_index=True) numerical_value = models.FloatField(null=True, blank=True, db_index=True) datetime_value = models.DateTimeField(null=True, blank=True, db_index=True) objects = OracleSafeManager() def get(self): return _getParameter(self) def __unicode__(self): return 'Dataset Param: %s=%s' % (self.name.name, self.get()) class Meta: app_label = 'tardis_portal' ordering = ['name']
class DatafileParameter(models.Model): parameterset = models.ForeignKey(DatafileParameterSet) name = models.ForeignKey(ParameterName) string_value = models.TextField(null=True, blank=True, db_index=True) numerical_value = models.FloatField(null=True, blank=True, db_index=True) datetime_value = models.DateTimeField(null=True, blank=True, db_index=True) objects = OracleSafeManager() def get(self): return _getParameter(self) def getExpId(self): return self.parameterset.dataset_file.dataset.experiment.id def __unicode__(self): return 'Datafile Param: %s=%s' % (self.name.name, self.get()) class Meta: ordering = ['name']
class Token(models.Model): token = models.CharField(max_length=30, unique=True) experiment = models.ForeignKey(Experiment) expiry_date = models.DateField(default=_token_expiry) user = models.ForeignKey(User) _TOKEN_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' objects = OracleSafeManager() class Meta: app_label = 'tardis_portal' def __unicode__(self): return '%s %s' % (self.expiry_date, self.token) def _randomise_token(self): from random import choice self.token = ''.join( choice(self._TOKEN_CHARS) for _ in range(settings.TOKEN_LENGTH)) def save_with_random_token(self): from django.db import IntegrityError if not self.user or not self.experiment: # fail if success impossible self.save() for _ in range(30): # 30 is an arbitrary number self._randomise_token() try: logger.debug(self.token) self.save() except IntegrityError as e: logger.debug(e) continue else: return logger.warning('failed to generate a random token') self.save() # give up and raise the exception @models.permalink def get_absolute_url(self): return ('tardis.tardis_portal.views.token_login', (), { 'token': self.token }) def is_expired(self): import datetime as dt return self.expiry_date and self.expiry_date < dt.datetime.now().date() def _get_expiry_as_datetime(self): import datetime as dt exp = self.expiry_date return dt.datetime(exp.year, exp.month, exp.day, 23, 59, 59) @staticmethod def _tomorrow_4am(): import datetime as dt today = dt.datetime.now().date() tomorrow = today + dt.timedelta(1) tomorrow_4am = dt.datetime(tomorrow.year, tomorrow.month, tomorrow.day, 4) return tomorrow_4am def get_session_expiry(self): ''' A token login should expire at the earlier of a) tomorrow at 4am b) the (end of) the token's expiry date It is the responsibility of token_auth to set the session expiry ''' if self.is_expired(): import datetime as dt return dt.datetime.now() expire_tomorrow_morning = self._tomorrow_4am() token_as_datetime = self._get_expiry_as_datetime() print expire_tomorrow_morning print token_as_datetime if expire_tomorrow_morning < token_as_datetime: return expire_tomorrow_morning else: return token_as_datetime
class Dataset(models.Model): """Class to link datasets to experiments :attribute experiment: a forign key to the :class:`tardis.tardis_portal.models.Experiment` :attribute description: description of this dataset """ experiments = models.ManyToManyField(Experiment, related_name='datasets') description = models.TextField(blank=True) directory = DirectoryField(blank=True, null=True) immutable = models.BooleanField(default=False) objects = OracleSafeManager() class Meta: app_label = 'tardis_portal' ordering = ['-id'] def getParameterSets(self, schemaType=None): """Return the dataset parametersets associated with this experiment. """ from tardis.tardis_portal.models.parameters import Schema if schemaType == Schema.DATASET or schemaType is None: return self.datasetparameterset_set.filter( schema__type=Schema.DATASET) else: raise Schema.UnsupportedType def __unicode__(self): return self.description def get_first_experiment(self): return self.experiments.order_by('created_time')[:1].get() def get_path(self): return path.join(str(self.get_first_experiment().id), str(self.id)) @models.permalink def get_absolute_url(self): """Return the absolute url to the current ``Dataset``""" return ('tardis.tardis_portal.views.view_dataset', (), { 'dataset_id': self.id }) @models.permalink def get_edit_url(self): """Return the absolute url to the edit view of the current ``Dataset`` """ return ('tardis.tardis_portal.views.edit_dataset', (self.id, )) def get_images(self): from .datafile import IMAGE_FILTER images = self.dataset_file_set.order_by('filename')\ .filter(IMAGE_FILTER) return images def _get_image(self): try: return self.get_images()[0] except IndexError: return None image = property(_get_image) def get_thumbnail_url(self): if self.image is None: return None return reverse('tardis.tardis_portal.iiif.download_image', kwargs={ 'datafile_id': self.image.id, 'region': 'full', 'size': '100,', 'rotation': 0, 'quality': 'native', 'format': 'jpg' }) def get_size(self): from .datafile import Dataset_File return Dataset_File.sum_sizes(self.dataset_file_set) def _has_any_perm(self, user_obj): if not hasattr(self, 'id'): return False return self.experiments.all() def _has_view_perm(self, user_obj): return self._has_any_perm(user_obj) def _has_change_perm(self, user_obj): if self.immutable: return False return self._has_any_perm(user_obj) def _has_delete_perm(self, user_obj): if self.immutable: return False return self._has_any_perm(user_obj)
class Experiment(models.Model): """The ``Experiment`` model inherits from :class:`django.db.models.Model` :attribute url: **Undocumented** :attribute approved: **Undocumented** :attribute title: the title of the experiment. :attribute institution_name: the name of the institution who created the dataset. :attribute start_time: **Undocumented** :attribute end_time: **Undocumented** :attribute created_time: **Undocumented** :attribute handle: **Undocumented** :attribute public: **Undocumented** :attribute objects: default model manager :attribute safe: ACL aware model manager """ url = models.URLField(verify_exists=False, max_length=255, null=True, blank=True) approved = models.BooleanField() title = models.CharField(max_length=400) institution_name = models.CharField(max_length=400, default=settings.DEFAULT_INSTITUTION) description = models.TextField(blank=True) start_time = models.DateTimeField(null=True, blank=True) end_time = models.DateTimeField(null=True, blank=True) created_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) created_by = models.ForeignKey(User) handle = models.TextField(null=True, blank=True) public = models.BooleanField() objects = OracleSafeManager() safe = ExperimentManager() # The acl-aware specific manager. def save(self, *args, **kwargs): super(Experiment, self).save(*args, **kwargs) _publish_public_expt_rifcs(self) def getParameterSets(self, schemaType=None): """Return the experiment parametersets associated with this experiment. """ if schemaType == Schema.EXPERIMENT or schemaType is None: return self.experimentparameterset_set.filter( schema__type=Schema.EXPERIMENT) else: raise Schema.UnsupportedType def __unicode__(self): return self.title def get_absolute_filepath(self): """Return the absolute storage path to the current ``Experiment``""" store = settings.FILE_STORE_PATH return path.join(store, str(self.id)) def get_or_create_directory(self): dirname = path.join(settings.FILE_STORE_PATH, str(self.id)) if not path.exists(dirname): from os import chmod, mkdir try: mkdir(dirname) chmod(dirname, 0770) except: dirname = None return dirname @models.permalink def get_absolute_url(self): """Return the absolute url to the current ``Experiment``""" return ('tardis.tardis_portal.views.view_experiment', (), { 'experiment_id': self.id }) @models.permalink def get_edit_url(self): """Return the absolute url to the edit view of the current ``Experiment`` """ return ('tardis.tardis_portal.views.edit_experiment', (), { 'experiment_id': self.id }) @models.permalink def get_create_token_url(self): """Return the absolute url to the create token view of the current ``Experiment`` """ return ('tardis.tardis_portal.views.create_token', (), { 'experiment_id': self.id }) def get_download_urls(self, comptype="zip"): urls = {} kwargs = {'experiment_id': self.id, 'comptype': comptype} distinct = Dataset_File.objects.filter(dataset__experiment=self.id)\ .values('protocol').distinct() for key_value in distinct: protocol = key_value['protocol'] if protocol in ['', 'tardis', 'file', 'http', 'https']: view = 'tardis.tardis_portal.download.download_experiment' if not '' in urls: urls[''] = reverse(view, kwargs=kwargs) else: try: for module in settings.DOWNLOAD_PROVIDERS: if module[0] == protocol: view = '%s.download_experiment' % module[1] urls[protocol] = reverse(view, kwargs=kwargs) except AttributeError: pass return urls
class Experiment(models.Model): """The ``Experiment`` model inherits from :class:`django.db.models.Model` :attribute url: **Undocumented** :attribute approved: **Undocumented** :attribute title: the title of the experiment. :attribute institution_name: the name of the institution who created the dataset. :attribute start_time: **Undocumented** :attribute end_time: **Undocumented** :attribute created_time: **Undocumented** :attribute handle: **Undocumented** :attribute public: **Undocumented** :attribute objects: default model manager :attribute safe: ACL aware model manager """ PUBLIC_ACCESS_NONE = 1 PUBLIC_ACCESS_METADATA = 50 PUBLIC_ACCESS_FULL = 100 PUBLIC_ACCESS_CHOICES = ( (PUBLIC_ACCESS_NONE, 'No public access (hidden)'), (PUBLIC_ACCESS_METADATA, 'Metadata only (no data file access)'), (PUBLIC_ACCESS_FULL, 'Everything'), ) url = models.URLField(verify_exists=False, max_length=255, null=True, blank=True) approved = models.BooleanField() title = models.CharField(max_length=400) institution_name = models.CharField(max_length=400, default=settings.DEFAULT_INSTITUTION) description = models.TextField(blank=True) start_time = models.DateTimeField(null=True, blank=True) end_time = models.DateTimeField(null=True, blank=True) created_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) created_by = models.ForeignKey(User) handle = models.TextField(null=True, blank=True) locked = models.BooleanField() public_access = \ models.PositiveSmallIntegerField(choices=PUBLIC_ACCESS_CHOICES, null=False, default=PUBLIC_ACCESS_NONE) license = models.ForeignKey(License, #@ReservedAssignment blank=True, null=True) objects = OracleSafeManager() safe = ExperimentManager() # The acl-aware specific manager. class Meta: app_label = 'tardis_portal' def save(self, *args, **kwargs): super(Experiment, self).save(*args, **kwargs) from .hooks import publish_public_expt_rifcs publish_public_expt_rifcs(self) def getParameterSets(self, schemaType=None): """Return the experiment parametersets associated with this experiment. """ from tardis.tardis_portal.models.parameters import Schema if schemaType == Schema.EXPERIMENT or schemaType is None: return self.experimentparameterset_set.filter( schema__type=Schema.EXPERIMENT) else: raise Schema.UnsupportedType def __unicode__(self): return self.title def get_or_create_directory(self): dirname = path.join(settings.FILE_STORE_PATH, str(self.id)) if not path.exists(dirname): from os import chmod, mkdir try: mkdir(dirname) chmod(dirname, 0770) except: dirname = None return dirname @models.permalink def get_absolute_url(self): """Return the absolute url to the current ``Experiment``""" return ('tardis.tardis_portal.views.view_experiment', (), {'experiment_id': self.id}) @models.permalink def get_edit_url(self): """Return the absolute url to the edit view of the current ``Experiment`` """ return ('tardis.tardis_portal.views.edit_experiment', (), {'experiment_id': self.id}) @models.permalink def get_create_token_url(self): """Return the absolute url to the create token view of the current ``Experiment`` """ return ('tardis.tardis_portal.views.create_token', (), {'experiment_id': self.id}) def get_datafiles(self): from .datafile import Dataset_File return Dataset_File.objects.filter(dataset__experiments=self) def get_download_urls(self): from .datafile import Dataset_File urls = {} params = (('experiment_id', self.id),) protocols = frozenset(self.get_datafiles()\ .values_list('protocol', flat=True)\ .distinct()) # Get built-in download links local_protocols = frozenset(('', 'tardis', 'file', 'http', 'https')) if any(p in protocols for p in local_protocols): view = 'tardis.tardis_portal.download.download_experiment' for comptype in ['tar', 'zip']: kwargs = dict(params+(('comptype', comptype),)) urls[comptype] = reverse(view, kwargs=kwargs) # Get links from download providers for protocol in protocols - local_protocols: try: for module in settings.DOWNLOAD_PROVIDERS: if module[0] == protocol: view = '%s.download_experiment' % module[1] urls[protocol] = reverse(view, kwargs=dict(params)) except AttributeError: pass return urls def get_images(self): from .datafile import IMAGE_FILTER return self.get_datafiles().order_by('-modification_time', '-created_time') \ .filter(IMAGE_FILTER) def get_size(self): from .datafile import Dataset_File return Dataset_File.sum_sizes(self.get_datafiles()) @classmethod def public_access_implies_distribution(cls, public_access_level): ''' Determines if a level of public access implies that distribution should be allowed, or alternately if it should not be allowed. Used to prevent free-distribution licences for essentially private data, and overly-restrictive licences for public data. ''' return public_access_level > cls.PUBLIC_ACCESS_METADATA def get_owners(self): acls = ExperimentACL.objects.filter(pluginId='django_user', experiment=self, isOwner=True) return [acl.get_related_object() for acl in acls]
class Dataset(models.Model): """Class to link datasets to experiments :attribute experiment: a forign key to the :class:`tardis.tardis_portal.models.Experiment` :attribute description: description of this dataset """ experiments = models.ManyToManyField(Experiment, related_name='datasets') description = models.TextField(blank=True) immutable = models.BooleanField(default=False) objects = OracleSafeManager() class Meta: app_label = 'tardis_portal' def getParameterSets(self, schemaType=None): """Return the dataset parametersets associated with this experiment. """ from tardis.tardis_portal.models.parameters import Schema if schemaType == Schema.DATASET or schemaType is None: return self.datasetparameterset_set.filter( schema__type=Schema.DATASET) else: raise Schema.UnsupportedType def __unicode__(self): return self.description def get_first_experiment(self): return self.experiments.order_by('created_time')[:1].get() @models.permalink def get_absolute_url(self): """Return the absolute url to the current ``Dataset``""" return ('tardis.tardis_portal.views.view_dataset', (), { 'dataset_id': self.id }) @models.permalink def get_edit_url(self): """Return the absolute url to the edit view of the current ``Dataset`` """ return ('tardis.tardis_portal.views.edit_dataset', (self.id, )) def get_images(self): from .datafile import IMAGE_FILTER images = self.dataset_file_set.order_by('-modification_time', '-created_time')\ .filter(IMAGE_FILTER) return images def _get_image(self): try: return self.get_images()[0] except IndexError: return None image = property(_get_image) def get_size(self): from .datafile import Dataset_File return Dataset_File.sum_sizes(self.dataset_file_set)
class Dataset(models.Model): """Class to link datasets to experiments :attribute experiment: a forign key to the :class:`tardis.tardis_portal.models.Experiment` :attribute facility: the foreign key to the facility that generated this data :attribute instrument: the foreign key to the instrument that generated this data :attribute description: description of this dataset """ experiments = models.ManyToManyField(Experiment, related_name='datasets') description = models.TextField(blank=True) directory = models.CharField(blank=True, null=True, max_length=255) immutable = models.BooleanField(default=False) instrument = models.ForeignKey(Instrument, null=True, blank=True) objects = OracleSafeManager() class Meta: app_label = 'tardis_portal' ordering = ['-id'] @property def is_online(self): return all(df.is_online for df in self.datafile_set.all()) def getParameterSets(self, schemaType=None): """Return the dataset parametersets associated with this experiment. """ from tardis.tardis_portal.models.parameters import Schema if schemaType == Schema.DATASET or schemaType is None: return self.datasetparameterset_set.filter( schema__type=Schema.DATASET) else: raise Schema.UnsupportedType def __unicode__(self): return self.description def get_first_experiment(self): return self.experiments.order_by('created_time')[:1].get() def get_path(self): return path.join(str(self.get_first_experiment().id), str(self.id)) def get_datafiles(self): from .datafile import DataFile return DataFile.objects.filter(dataset=self) @models.permalink def get_absolute_url(self): """Return the absolute url to the current ``Dataset``""" return ('tardis_portal.view_dataset', (), {'dataset_id': self.id}) def get_download_urls(self): view = 'tardis.tardis_portal.download.streaming_download_' \ 'dataset' urls = {} for comptype in getattr(settings, 'DEFAULT_ARCHIVE_FORMATS', ['tgz', 'tar']): urls[comptype] = reverse(view, kwargs={ 'dataset_id': self.id, 'comptype': comptype }) return urls @models.permalink def get_edit_url(self): """Return the absolute url to the edit view of the current ``Dataset`` """ return ('tardis.tardis_portal.views.edit_dataset', (self.id, )) def get_images(self): from .datafile import IMAGE_FILTER return self.datafile_set.order_by('filename').filter(IMAGE_FILTER) def _get_image(self): try: return self.get_images()[0] except IndexError: return None image = property(_get_image) def get_thumbnail_url(self): if self.image is None: return None return reverse('tardis.tardis_portal.iiif.download_image', kwargs={ 'datafile_id': self.image.id, 'region': 'full', 'size': '100,', 'rotation': 0, 'quality': 'native', 'format': 'jpg' }) def get_size(self): from .datafile import DataFile return DataFile.sum_sizes(self.datafile_set) def _has_any_perm(self, user_obj): if not hasattr(self, 'id'): return False return self.experiments.all() def _has_view_perm(self, user_obj): return self._has_any_perm(user_obj) def _has_change_perm(self, user_obj): if self.immutable: return False return self._has_any_perm(user_obj) def _has_delete_perm(self, user_obj): if self.immutable: return False return self._has_any_perm(user_obj) def get_all_storage_boxes_used(self): boxes = StorageBox.objects.filter(file_objects__datafile__dataset=self) return boxes
class Experiment(models.Model): """The ``Experiment`` model inherits from :class:`django.db.models.Model` :attribute url: **Undocumented** :attribute approved: **Undocumented** :attribute title: the title of the experiment. :attribute institution_name: the name of the institution who created the dataset. :attribute start_time: **Undocumented** :attribute end_time: **Undocumented** :attribute created_time: **Undocumented** :attribute handle: **Undocumented** :attribute public: **Undocumented** :attribute objects: default model manager :attribute safe: ACL aware model manager """ PUBLIC_ACCESS_NONE = 1 PUBLIC_ACCESS_EMBARGO = 25 PUBLIC_ACCESS_METADATA = 50 PUBLIC_ACCESS_FULL = 100 PUBLIC_ACCESS_CHOICES = ( (PUBLIC_ACCESS_NONE, 'No public access (hidden)'), (PUBLIC_ACCESS_EMBARGO, 'Ready to be released pending embargo expiry'), (PUBLIC_ACCESS_METADATA, 'Public Metadata only (no data file access)'), (PUBLIC_ACCESS_FULL, 'Public'), ) PUBLICATION_SCHEMA_ROOT = 'http://www.tardis.edu.au/schemas/publication/' PUBLICATION_DETAILS_SCHEMA = PUBLICATION_SCHEMA_ROOT + 'details/' PUBLICATION_DRAFT_SCHEMA = PUBLICATION_SCHEMA_ROOT + 'draft/' url = models.URLField(max_length=255, null=True, blank=True) approved = models.BooleanField(default=False) title = models.CharField(max_length=400) institution_name = models.CharField(max_length=400, default=settings.DEFAULT_INSTITUTION) description = models.TextField(blank=True) start_time = models.DateTimeField(null=True, blank=True) end_time = models.DateTimeField(null=True, blank=True) created_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) created_by = models.ForeignKey(User) handle = models.TextField(null=True, blank=True) locked = models.BooleanField(default=False) public_access = \ models.PositiveSmallIntegerField(choices=PUBLIC_ACCESS_CHOICES, null=False, default=PUBLIC_ACCESS_NONE) license = models.ForeignKey( License, # @ReservedAssignment blank=True, null=True) objectacls = GenericRelation(ObjectACL) objects = OracleSafeManager() safe = ExperimentManager() # The acl-aware specific manager. class Meta: app_label = 'tardis_portal' def save(self, *args, **kwargs): super(Experiment, self).save(*args, **kwargs) from .hooks import publish_public_expt_rifcs publish_public_expt_rifcs(self) def is_publication_draft(self): return self.experimentparameterset_set.filter( schema__namespace=getattr( settings, 'PUBLICATION_DRAFT_SCHEMA', self.PUBLICATION_DRAFT_SCHEMA)).count() > 0 def is_publication(self): return self.experimentparameterset_set.filter( schema__namespace__startswith=getattr( settings, 'PUBLICATION_SCHEMA_ROOT', self.PUBLICATION_SCHEMA_ROOT)).count() > 0 def getParameterSets(self, schemaType=None): """Return the experiment parametersets associated with this experiment. """ from tardis.tardis_portal.models.parameters import Schema if schemaType == Schema.EXPERIMENT or schemaType is None: return self.experimentparameterset_set.filter( schema__type=Schema.EXPERIMENT) else: raise Schema.UnsupportedType def __unicode__(self): return self.title def get_or_create_directory(self): dirname = path.join(settings.FILE_STORE_PATH, str(self.id)) if not path.exists(dirname): from os import chmod, mkdir try: mkdir(dirname) chmod(dirname, 0770) except: dirname = None return dirname @models.permalink def get_absolute_url(self): """Return the absolute url to the current ``Experiment``""" return ('tardis_portal.view_experiment', (), { 'experiment_id': self.id }) @models.permalink def get_edit_url(self): """Return the absolute url to the edit view of the current ``Experiment`` """ return ('tardis.tardis_portal.views.edit_experiment', (), { 'experiment_id': self.id }) @models.permalink def get_create_token_url(self): """Return the absolute url to the create token view of the current ``Experiment`` """ return ('tardis.tardis_portal.views.create_token', (), { 'experiment_id': self.id }) def get_datafiles(self): from .datafile import DataFile return DataFile.objects.filter(dataset__experiments=self) def get_download_urls(self): urls = {} view = 'tardis.tardis_portal.download.streaming_download_experiment' for comptype in getattr(settings, 'DEFAULT_ARCHIVE_FORMATS', ['tgz', 'tar']): urls[comptype] = reverse(view, kwargs={ 'experiment_id': self.id, 'comptype': comptype }) return urls def get_images(self): from .datafile import IMAGE_FILTER return self.get_datafiles().order_by('-modification_time', '-created_time') \ .filter(IMAGE_FILTER) def get_size(self): from .datafile import DataFile return DataFile.sum_sizes(self.get_datafiles()) @classmethod def public_access_implies_distribution(cls, public_access_level): ''' Determines if a level of public access implies that distribution should be allowed, or alternately if it should not be allowed. Used to prevent free-distribution licences for essentially private data, and overly-restrictive licences for public data. ''' return public_access_level > cls.PUBLIC_ACCESS_METADATA def public_download_allowed(self): ''' instance method version of 'public_access_implies_distribution' ''' return self.public_access > Experiment.PUBLIC_ACCESS_METADATA def get_ct(self): return ContentType.objects.get_for_model(self) def get_owners(self): acls = ObjectACL.objects.filter(pluginId='django_user', content_type=self.get_ct(), object_id=self.id, isOwner=True) return [acl.get_related_object() for acl in acls] def get_groups(self): acls = ObjectACL.objects.filter(pluginId='django_group', content_type=self.get_ct(), object_id=self.id, canRead=True) return [acl.get_related_object() for acl in acls] def _has_view_perm(self, user_obj): if not hasattr(self, 'id'): return False if self.public_access >= self.PUBLIC_ACCESS_METADATA: return True def _has_change_perm(self, user_obj): if not hasattr(self, 'id'): return False if self.locked: return False return None def _has_delete_perm(self, user_obj): if not hasattr(self, 'id'): return False return None
class Parameter(models.Model): name = models.ForeignKey(ParameterName) # string_value has a custom index created via migrations (for Postgresql) string_value = models.TextField(null=True, blank=True) numerical_value = models.FloatField(null=True, blank=True, db_index=True) datetime_value = models.DateTimeField(null=True, blank=True, db_index=True) link_id = models.PositiveIntegerField(null=True, blank=True) link_ct = models.ForeignKey(ContentType, null=True, blank=True) link_gfk = GenericForeignKey('link_ct', 'link_id') objects = OracleSafeManager() parameter_type = 'Abstract' class Meta: abstract = True app_label = 'tardis_portal' ordering = ['name'] def get(self): return _get_parameter(self) def __unicode__(self): try: return '%s Param: %s=%s' % (self.parameter_type, self.name.name, self.get()) except: return 'Unitialised %sParameter' % self.parameter_type @property def link_url(self): if not self.name.isLink(): return None if isinstance(self.link_gfk, DataFile): url = reverse('tardis_portal.view_dataset', kwargs={'dataset_id': self.link_gfk.dataset.id}) elif isinstance(self.link_gfk, Dataset): url = reverse('tardis_portal.view_dataset', kwargs={'dataset_id': self.link_id}) elif isinstance(self.link_gfk, Experiment): url = reverse('tardis_portal.view_experiment', kwargs={'experiment_id': self.link_id}) elif self.link_gfk is None and self.string_value: url = self.string_value else: raise NotImplementedError return url def set_value(self, value): """ Sets the parameter value, converting into the appropriate data type. Deals with date/time strings that are timezone naive or aware, based on the USE_TZ setting. :param basestring value: a string (or string-like) repr of the value :raises SuspiciousOperation: """ if self.name.isNumeric(): self.numerical_value = float(value) elif self.name.isDateTime(): # We convert the value string into datetime object. # dateutil.parser detects and converts many date formats and is # quite permissive in what it accepts (form validation and API # input validation happens elsewhere and may be less permissive) datevalue = dateutil.parser.parse(value) if settings.USE_TZ and is_naive(datevalue): datevalue = make_aware(datevalue, LOCAL_TZ) elif not settings.USE_TZ and is_aware(datevalue): datevalue = make_naive(datevalue, LOCAL_TZ) self.datetime_value = datevalue elif self.name.isLink(): # Always store the raw value as a string, even if setting # the GenericForeignKey via link_id/link_ct if str(value) == '' or value is None: return self.string_value = unicode(value) try: # We detect experiment or dataset view URLs # (eg, /experiment/view/12345/ or /api/v1/dataset/456) # and extract values to populate link_ct and link_id. This # covers two common cases, allowing LINK Parameters to be # properly created via the REST API. match = resolve(value) if match.view_name == u'api_dispatch_detail': model_name = match.kwargs.get(u'resource_name', None) if model_name not in ('experiment', 'dataset'): model_name, pk = None, None else: pk = match.kwargs.get('pk', None) elif match.view_name.endswith('view_experiment'): model_name = 'experiment' pk = match.kwargs.get('experiment_id') elif match.view_name.endswith('view_dataset'): model_name = 'dataset' pk = match.kwargs.get('dataset_id') else: model_name, pk = None, None if pk is not None and model_name is not None: self.link_id = pk self.link_ct = ContentType.objects.get( app_label='tardis_portal', model=model_name.lower()) except (ValueError, IndexError, Resolver404): # If we were unable to successfully match the url to model # instance, return an error. For any URL the URL Parameter # type should be used. raise SuspiciousOperation('Link parameter could not be set ' 'from string: %s' % str(value)) else: self.string_value = unicode(value) def _has_any_perm(self, user_obj): if not hasattr(self, 'id'): return False return self.parameterset def _has_view_perm(self, user_obj): return self._has_any_perm(user_obj) def _has_change_perm(self, user_obj): return self._has_any_perm(user_obj) def _has_delete_perm(self, user_obj): return self._has_any_perm(user_obj)