class Version(Model): name = CharField(max_length=128) description = CharField(max_length=1024, blank=True) number = PositiveIntegerField() project = ForeignKey(Project, on_delete=CASCADE) created_datetime = DateTimeField(auto_now_add=True, null=True, blank=True) created_by = ForeignKey(User, on_delete=SET_NULL, null=True, blank=True, related_name='version_created_by') show_empty = BooleanField(default=True) """ Tells the UI to show this version even if the current media does not have any annotations. """ bases = ManyToManyField('self', symmetrical=False, blank=True) """ This version is a patch to an existing version. A use-case here is using one version for each generation of a state-based inference algorithm; all referencing localizations in another layer. """ def __str__(self): out = f"{self.name}" if self.description: out += f" | {self.description}" return out
class LocalizationAssociation(AssociationType): localizations = ManyToManyField(EntityLocalizationBase) segments = JSONField(null=True) color = CharField(null=True,blank=True,max_length=8) def states(media_id): localizationsForMedia=EntityLocalizationBase.objects.filter(media__in=media_id) localizationAssociations=LocalizationAssociation.objects.filter(localizations__in=localizationsForMedia).distinct() return EntityState.objects.filter(association__in=localizationAssociations)
class EntityTypeState(EntityTypeBase): """ Used to conglomerate AttributeTypes into a set """ entity_name = 'State' dtype = 'state' media = ManyToManyField(EntityTypeMediaBase) markers = BooleanField(default=False) interpolation = EnumField(InterpolationMethods, default=InterpolationMethods.NONE) association = CharField(max_length=64, choices=AssociationTypes, default=AssociationTypes[0][0])
class StateType(Model): dtype = CharField(max_length=16, choices=[('state', 'state')], default='state') project = ForeignKey(Project, on_delete=CASCADE, null=True, blank=True, db_column='project') name = CharField(max_length=64) description = CharField(max_length=256, blank=True) visible = BooleanField(default=True) """ Whether this type should be displayed in the UI.""" grouping_default = BooleanField(default=True) """ Whether to group elements in the UI by default.""" media = ManyToManyField(MediaType) interpolation = CharField(max_length=16, choices=[('none', 'none'), ('latest', 'latest')], default='latest') association = CharField(max_length=64, choices=AssociationTypes, default=AssociationTypes[0][0]) attribute_types = JSONField(default=list, null=True, blank=True) """ User defined attributes. An array of objects, each containing the following fields: name: Name of the attribute. description: Description of the attribute. order: Order that the attribute should appear in web UI. Negative means do not display. dtype: Data type of the attribute. Valid values are bool, int, float, string, enum, datetime, geopos. default: (optional) Default value. Valid for all dtypes except datetime. The type should correspond to the dtype (string/enum are strings, int/float are numbers, geopos is a [lon, lat] list). minimum: (optional) Minimum value. Valid for int and float dtypes. maximum: (optional) Maximum value. Valid for int and float dtypes. choices: (optional) Available choices for enum dtype. labels: (optional) Labels for available choices for enum dtype. autocomplete: (optional) Object of the form {'serviceUrl': '<url>'} that specifies URL of the autocomplete service. Valid for string dtype only. use_current: (optional) Boolean indicating whether to use the current time as the default for datetime dtype. style: (optional) String of GUI-related styles. """ delete_child_localizations = BooleanField(default=False) """ If enabled, child localizations will be deleted when states of this type are deleted. """ def __str__(self): return f'{self.name} | {self.project}'
class AlgorithmResult(Model): algorithm = ForeignKey(Algorithm, on_delete=CASCADE) user = ForeignKey(User, on_delete=CASCADE) media = ManyToManyField(EntityMediaBase) started = DateTimeField() stopped = DateTimeField() result = EnumField(JobResult) message = CharField(max_length=128) setup_log = FileField(null=True, blank=True) algorithm_log = FileField(null=True, blank=True) teardown_log = FileField(null=True, blank=True) def __str__(self): return f"{self.algorithm.name}, {self.result}, started {self.started}"
class AssociationType(PolymorphicModel): media = ManyToManyField(EntityMediaBase) def states(media_ids): # Get localization associations localizationsForMedia=EntityLocalizationBase.objects.filter(media__in=media_ids) localizationAssociations=LocalizationAssociation.objects.filter(localizations__in=localizationsForMedia).distinct() # Downcast to base class ids = [loc.id for loc in localizationAssociations] localizationAssociations=AssociationType.objects.filter(pk__in=ids) # Get other associations (frame, media) associations=AssociationType.objects.filter(media__in=media_ids) associations = list(associations.union(localizationAssociations)) # Get states with these associations states = EntityState.objects.filter(association__in=associations) return states
class User(AbstractBaseUser): email = EmailField(db_index=True, unique=True) is_active = BooleanField(default=True) is_staff = BooleanField(default=False) saved_flats = ManyToManyField(Flat) objects = UserManager() USERNAME_FIELD = 'email' @staticmethod def has_perm(perm: Any, obj: Any = None) -> bool: return True @staticmethod def has_module_perms(app_label: Any) -> bool: return True def __str__(self) -> str: return self.email
class Resource(Model): path = CharField(db_index=True, max_length=256) media = ManyToManyField(Media, related_name='resource_media') @transaction.atomic def add_resource(path_or_link, media): if os.path.islink(path_or_link): path = os.readlink(path_or_link) else: path = path_or_link obj, created = Resource.objects.get_or_create(path=path) if media is not None: obj.media.add(media) @transaction.atomic def delete_resource(path_or_link): path = path_or_link if os.path.exists(path_or_link): if os.path.islink(path_or_link): path = os.readlink(path_or_link) os.remove(path_or_link) if path.startswith('/'): try: obj = Resource.objects.get(path=path) if obj.media.all().count() == 0: logger.info(f"Deleting file {path}") obj.delete() os.remove(path) except Resource.DoesNotExist as dne: logger.info(f"Removing legacy resource {path}") os.remove(path) except Exception as e: logger.error(f"{e} when lowering resource count of {path}") else: # This is an S3 object. obj = Resource.objects.get(path=path) if obj.media.all().count() == 0: logger.info(f"Deleting object {path}") obj.delete() s3 = TatorS3().s3 s3.delete_object(Bucket=os.getenv('BUCKET_NAME'), Key=path)
class Flat(Estate): living_area = FloatField(null=True) kitchen_area = FloatField(null=True) rooms = SmallIntegerField() floor = SmallIntegerField() total_floor = SmallIntegerField() ceiling_height = FloatField(null=True) details = ManyToManyField(Detail, db_table='flats_details') saved_field = 'saved_flats' lookups = { 'state': 'geolocation__state', 'locality': 'geolocation__locality', 'county': 'geolocation__county', 'neighbourhood': 'geolocation__neighbourhood', 'road': 'geolocation__road', 'house_number': 'geolocation__house_number', 'area_from': 'area__gte', 'area_to': 'area__lte', 'living_area_from': 'living_area__gte', 'living_area_to': 'living_area__lte', 'kitchen_area_from': 'kitchen_area__gte', 'kitchen_area_to': 'kitchen_area__lte', 'rooms_from': 'rooms__gte', 'rooms_to': 'rooms__lte', 'floor_from': 'floor__gte', 'floor_to': 'floor__lte', 'total_floor_from': 'total_floor__gte', 'total_floor_to': 'total_floor__lte', 'ceiling_height_from': 'ceiling_height__gte', 'ceiling_height_to': 'ceiling_height__lte' } order_by = {'area', '-area', 'rooms', '-rooms', 'price', '-price'} class Meta: db_table = 'flats' constraints = [ UniqueConstraint( fields=['geolocation_id', 'rooms', 'floor', 'total_floor'], name='flat_geolocation_id_rooms_floor_total_floor_key' ) ]
class State(Model): """ A State is an event that occurs, potentially independent, from that of a media element. It is associated with 0 (1 to be useful) or more media elements. If a frame is supplied it was collected at that time point. """ project = ForeignKey(Project, on_delete=SET_NULL, null=True, blank=True, db_column='project') meta = ForeignKey(StateType, on_delete=SET_NULL, null=True, blank=True, db_column='meta') """ Meta points to the defintion of the attribute field. That is a handful of AttributeTypes are associated to a given EntityType that is pointed to by this value. That set describes the `attribute` field of this structure. """ attributes = JSONField(null=True, blank=True) """ Values of user defined attributes. """ created_datetime = DateTimeField(auto_now_add=True, null=True, blank=True) created_by = ForeignKey(User, on_delete=SET_NULL, null=True, blank=True, related_name='state_created_by', db_column='created_by') modified_datetime = DateTimeField(auto_now=True, null=True, blank=True) modified_by = ForeignKey(User, on_delete=SET_NULL, null=True, blank=True, related_name='state_modified_by', db_column='modified_by') version = ForeignKey(Version, on_delete=SET_NULL, null=True, blank=True, db_column='version') modified = BooleanField(default=True, null=True, blank=True) """ Indicates whether an annotation is original or modified. null: Original upload, no modifications. false: Original upload, but was modified or deleted. true: Modified since upload or created via web interface. """ media = ManyToManyField(Media, related_name='media') localizations = ManyToManyField(Localization) segments = JSONField(null=True, blank=True) color = CharField(null=True, blank=True, max_length=8) frame = PositiveIntegerField(null=True, blank=True) extracted = ForeignKey(Media, on_delete=SET_NULL, null=True, blank=True, related_name='extracted', db_column='extracted') def selectOnMedia(media_id): return State.objects.filter(media__in=media_id)
class EntityTypeLocalizationBase(EntityTypeBase): media = ManyToManyField(EntityTypeMediaBase) bounded = BooleanField(default=True) colorMap = JSONField(null=True, blank=True)