class LayerMeta(Model): """ Immutable state of layer uploading & geoprocessing progress. To maintain an audit trail of each status change for a layer, these records should *not* be mutated. Instead, a new record should be created for each status change. The data in this table will primarily be maintained by the geoprocessing side of things. """ layer = ForeignKey(Layer, related_name='layer_metas') state = CharField(max_length=16) error = TextField(null=True, blank=True) thumb_small = URLField( null=True, blank=True, help_text='80x80 pixels', ) thumb_large = URLField( null=True, blank=True, help_text='400x150 pixels', ) created_at = DateTimeField(auto_now_add=True) # TileJSON fields min_zoom = IntegerField(default=0) max_zoom = IntegerField(default=11) bounds = CharField( null=True, max_length=120, help_text='JSON array', ) center = CharField( null=True, max_length=60, help_text='JSON array', ) def to_json(self): return { 'id': self.id, 'state': self.state, 'error': self.error, 'thumb_small': self.thumb_small, 'thumb_large': self.thumb_large, 'created_at': self.created_at.isoformat(), 'min_zoom': self.min_zoom, 'max_zoom': self.max_zoom, 'bounds': self.bounds, 'center': self.center, }
class Project(Model): name = CharField(max_length=128) creator = ForeignKey(User, on_delete=PROTECT, related_name='creator') created = DateTimeField(auto_now_add=True) size = BigIntegerField(default=0) """Size of all media in project in bytes. """ num_files = IntegerField(default=0) summary = CharField(max_length=1024) filter_autocomplete = JSONField(null=True, blank=True) section_order = ArrayField(CharField(max_length=128), default=list) def has_user(self, user_id): return self.membership_set.filter(user_id=user_id).exists() def user_permission(self, user_id): permission = None qs = self.membership_set.filter(user_id=user_id) if qs.exists(): permission = qs[0].permission return permission def __str__(self): return self.name def delete(self, *args, **kwargs): # Delete attribute types AttributeTypeBase.objects.filter(project=self).delete() # Delete entities qs = EntityBase.objects.filter(project=self) delete_polymorphic_qs(qs) # Delete entity types qs = EntityTypeBase.objects.filter(project=self) delete_polymorphic_qs(qs) super().delete(*args, **kwargs)
class Project(Model): name = CharField(max_length=128) creator = ForeignKey(User, on_delete=PROTECT, related_name='creator') created = DateTimeField(auto_now_add=True) size = BigIntegerField(default=0) """Size of all media in project in bytes. """ num_files = IntegerField(default=0) summary = CharField(max_length=1024) filter_autocomplete = JSONField(null=True, blank=True) def has_user(self, user_id): return self.membership_set.filter(user_id=user_id).exists() def user_permission(self, user_id): permission = None qs = self.membership_set.filter(user_id=user_id) if qs.exists(): permission = qs[0].permission return permission def __str__(self): return self.name def delete(self, *args, **kwargs): Version.objects.filter(project=self).delete() MediaType.objects.filter(project=self).delete() LocalizationType.objects.filter(project=self).delete() StateType.objects.filter(project=self).delete() LeafType.objects.filter(project=self).delete() super().delete(*args, **kwargs)
class Resource(Model): path = CharField(db_index=True, max_length=256) count = IntegerField(null=True, default=1) @transaction.atomic def add_resource(path_or_link): 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 not created: obj.count += 1 obj.save() @transaction.atomic def delete_resource(path_or_link): if os.path.islink(path_or_link): path = os.readlink(path_or_link) os.remove(path_or_link) else: path = path_or_link try: obj = Resource.objects.get(path=path) obj.count -= 1 if obj.count <= 0: obj.delete() os.remove(path) else: obj.save() 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}")
class Order(Base): complete = BooleanField(default=False) duration = IntegerField(null=True) # how long it took to process the order edited = BooleanField(default=False) # tells you whether they opened it for editing... not whether any actual edits were made end = DateTimeField(null=True) end_user_timezone = CharField(max_length=20, null=True) map_format = CharField(max_length=20, null=True) open_source = BooleanField(default=False) #is this map open-sourced, such that it can be included in open source training data? start = DateTimeField(auto_now_add=True, null=True) # it will never be null, but have to do this because migration asks for default otherwise style = ForeignKey("MapStyle", null=True, on_delete=SET_NULL) token = CharField(max_length=200, null=True, unique=True) # the random string that's used to find the order in the maps url = URLField(null=True, max_length=1000, unique=True) # URL if started from url or iframe embeded on a webpage def __str__(self): return self.token def d(self): self.delete_map() self.delete() def delete_map(self): rmtree("/home/usrfd/maps/" + self.token) def finish(self): self.complete = True self.end = end = datetime.now().replace(tzinfo=utc) self.duration = (end - self.start).total_seconds() self.save()
class MediaType(Model): dtype = CharField(max_length=16, choices=[('image', 'image'), ('video', 'video'), ('multi', 'multi')]) 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.""" editTriggers = JSONField(null=True, blank=True) file_format = CharField(max_length=4, null=True, blank=True, default=None) keep_original = BooleanField(default=True, null=True, blank=True) default_volume = IntegerField(default=0) """ Default Volume for Videos (default is muted) """ 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: (optional) 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. """ archive_config = JSONField(default=None, null=True, blank=True) streaming_config = JSONField(default=None, null=True, blank=True) overlay_config = JSONField(default=None, null=True, blank=True) """ Overlay configuration provides text overlay on video / image based on configruation examples: Example: {"mode": "constant", "source": "name"} Overlays file name Time example: {"mode": "datetime", "locale": [locale], "options" : [options]} options can contain 'timeZone' which comes from the TZ database name https://en.wikipedia.org/wiki/List_of_tz_database_time_zones Example: America/Los_Angeles or America/New_York """ def __str__(self): return f'{self.name} | {self.project}'
class LandBaseModel(BaseOfferModel, WithOtherDetails, WithDestination, WithExclusivity, WithOtherZoneDetails): land_type = CharField('tip teren', max_length=12, choices=LandType.choices, default=LandType.CONSTRUCTII) street_fronts_nr = PositiveIntegerField('nr. fronturi stradale', default=None, blank=True) classification = CharField('clasificare', max_length=12, choices=LandClassification.choices, default=LandClassification.INTRAVILAN) street_front = PositiveIntegerField('front stradal (m)', default=None, blank=True) terrain_surface = PositiveIntegerField('suprafaţă teren', default=None, blank=True) terrain_surface_type = CharField('', max_length=3, choices=SurfaceType.choices, default=SurfaceType.M) terrain_angle = IntegerField('înclinaţie teren (%)', default=None, blank=True) pot = IntegerField('P.O.T (%)', default=None, blank=True, help_text='Procentajul de ocupare al terenului (suprafaţa ocupată/suprafaţa totală * 100') cut = IntegerField('C.U.T (%)', default=None, blank=True, help_text='Coeficientul de utilizare al terenului (suma suprafeţelor desfăşurate/suprafaţa totală * 100') height_regime = PositiveIntegerField('regim înălţime (m)', default=None, blank=True) urban_coefficients_source = CharField('sursă informaţii coef. urbanistici', max_length=25, choices=URBAN_COEFF_SOURCES, default=None, blank=True) terrain_construction = BooleanField('construcţie pe teren', default=False) constructed_surface = PositiveIntegerField('suprafaţă construită (mp)', default=None, blank=True) access_road_width = PositiveIntegerField('lăţime drum de acces (m)', default=None, blank=True) documents = TextField('acte/avize', default=None, blank=True) plots_lot = BooleanField('lot parcele', default=False) plots_lot_name = CharField('nume lot parcele', max_length=100, default=None, blank=True) has_current = BooleanField('curent', default=False) has_three_phase_current = BooleanField('curent trifazic', default=False) has_water = BooleanField('apă', default=False) has_sewerage = BooleanField('canalizare', default=False) has_irrigation_system = BooleanField('sistem irigaţie', default=False) has_gas = BooleanField('gaz', default=False) has_utilities_nearby = BooleanField('utilităţi în zonă', default=False) has_investment_opportunity = BooleanField('oportunitate de investiţie', default=False) can_be_demolished = BooleanField('construcţie demolabilă', default=False) can_be_splitted = BooleanField('parcelabil', default=False) is_near_road = BooleanField('la şosea', default=False) has_auto_access = BooleanField('acces auto', default=False) is_surrounded_terrain = BooleanField('teren împrejmuit', default=False) class Meta: abstract = True
class User(AbstractUser): middle_initial = CharField(max_length=1) initials = CharField(max_length=3) organization = ForeignKey(Organization, on_delete=SET_NULL, null=True, blank=True) last_login = DateTimeField(null=True, blank=True) last_failed_login = DateTimeField(null=True, blank=True) failed_login_count = IntegerField(default=0) def __str__(self): if self.first_name or self.last_name: return f"{self.first_name} {self.last_name}" else: return "---"
class WorldBorder(Model): # Regular Django fields corresponding to the attributes in the # world borders shapefile. name = CharField(max_length=50) area = IntegerField() pop2005 = IntegerField('Population 2005') fips = CharField('FIPS Code', max_length=2) iso2 = CharField('2 Digit ISO', max_length=2) iso3 = CharField('3 Digit ISO', max_length=3) un = IntegerField('United Nations Code') region = IntegerField('Region Code') subregion = IntegerField('Sub-Region Code') lon = FloatField() lat = FloatField() # GeoDjango-specific: a geometry field (MultiPolygonField), and # overriding the default manager with a GeoManager instance. mpoly = MultiPolygonField() # Returns the string representation of the model. def __str__(self): # __unicode__ on Python 2 return self.name
class Frequency(CompanyBoundModel): """Headway (time between trips) for routes with variable frequency of service. This will be used instead of writing so many stop_times.txt; however, transitfeed.ScheduleViewer can't verified or display them yet. headway_secs the time between departures from the same stop (headway) for this trip type, during the time interval specified by start_time and end_time. The headway value must be entered in seconds. """ trip = ForeignKey('Trip') start_time = TimeField('Start time') end_time = TimeField('End time') headway_secs = IntegerField('Headway seconds', default=1800) # optional EXACT_TIME_CHOICES = ( ('0', 'Frequency-based trips are not exactly scheduled.'), ('1', 'Frequency-based trips are exactly scheduled'), # For a frequencies.txt row, trips are scheduled starting with # trip_start_time = start_time + x * headway_secs for all x in # (0, 1, 2, ...) where trip_start_time < end_time. ) exact_times = CharField('Exact times', max_length=1, default='0', choices=EXACT_TIME_CHOICES) class Meta: verbose_name_plural = "Frequencies" def __str__(self): return '%s [%s-%s] %s' % (self.trip.trip_id, self.start_time, self.end_time, self.headway_secs) @property def gtfs_header(self): return [ 'trip_id', 'start_time', 'end_time', 'headway_secs', 'exact_times' ] def gtfs_format(self): data = [ ('trip_id', self.trip.trip_id), ('start_time', self.start_time), ('end_time', self.end_time), ('headway_secs', self.headway_secs), ('exact_times', self.exact_times), ] return OrderedDict(data)
class AttributeTypeBase(PolymorphicModel): """ Generic entity in a JSON-B field. """ name = CharField(max_length=64) """ Name refers to the key in the JSON structure """ description = CharField(max_length=256, blank=True) """ Human readable description of the column """ applies_to = ForeignKey(EntityTypeBase, on_delete=CASCADE) """ Pointer to the owner of this type description. Either a media, state or sequence 'owns' this type and combines it into a set with other AttributeTypes to describe an AttributeSet """ project = ForeignKey(Project, on_delete=CASCADE) order = IntegerField(default=0) """ Controls order (lower numbers first, negative is hide) """ def __str__(self): return self.name
class Project(Model): name = CharField(max_length=128) creator = ForeignKey(User, on_delete=PROTECT, related_name='creator', db_column='creator') organization = ForeignKey(Organization, on_delete=SET_NULL, null=True, blank=True, db_column='organization') created = DateTimeField(auto_now_add=True) size = BigIntegerField(default=0) """Size of all media in project in bytes. """ num_files = IntegerField(default=0) duration = BigIntegerField(default=0) """ Duration of all videos in this project. """ summary = CharField(max_length=1024) filter_autocomplete = JSONField(null=True, blank=True) attribute_type_uuids = JSONField(default=dict, null=True, blank=True) enable_downloads = BooleanField(default=True) thumb = CharField(max_length=1024, null=True, blank=True) usernames = ArrayField(CharField(max_length=256), default=list) """ Mapping between attribute type names and UUIDs. Used internally for maintaining elasticsearch field aliases. """ def has_user(self, user_id): return self.membership_set.filter(user_id=user_id).exists() def user_permission(self, user_id): permission = None qs = self.membership_set.filter(user_id=user_id) if qs.exists(): permission = qs[0].permission return permission def __str__(self): return self.name def delete(self, *args, **kwargs): Version.objects.filter(project=self).delete() MediaType.objects.filter(project=self).delete() LocalizationType.objects.filter(project=self).delete() StateType.objects.filter(project=self).delete() LeafType.objects.filter(project=self).delete() super().delete(*args, **kwargs)
class User(AbstractUser): objects = TatorUserManager() cognito_id = UUIDField(primary_key=False, db_index=True, null=True, blank=True, editable=False) middle_initial = CharField(max_length=1) initials = CharField(max_length=3) last_login = DateTimeField(null=True, blank=True) last_failed_login = DateTimeField(null=True, blank=True) failed_login_count = IntegerField(default=0) def __str__(self): if self.first_name or self.last_name: return f"{self.first_name} {self.last_name}" else: return "---"
class Route(CompanyBoundModel): """Transit routes. A route is a group of trips that are displayed to riders as a single service. # GTFS Feed ## routes.txt This is obvious, basic fields "route_id", "agency_id", "route_short_name", "route_long_name", "route_desc", "route_type", "route_url", "route_color", "route_text_color" ## shapes.txt This is generated by `self.shapes` for `trips.txt` ### required shape_id, shape_pt_lat, shape_pt_lon, shape_pt_sequence, ### optional shape_dist_traveled (in km) """ route_id = CharField('route_id', max_length=25) short_name = CharField('short name', max_length=150) long_name = CharField('long name', max_length=500) shapes = LineStringField(srid=4326, null=True, blank=True) agency = ForeignKey('Agency', blank=True, null=True) desc = CharField('Route desc', max_length=250, blank=True) ROUTE_TYPES = ( ('0', 'Tram, Streetcar, Light rail'), ('1', 'Subway, Metro. Any underground rail system ' \ 'within a metropolitan area.'), ('2', 'Rail'), ('3', 'Bus'), ('4', 'Ferry'), ('5', 'Cable car'), ('6', 'Gondola, Suspended cable car'), ('7', 'Funicular. Any rail system designed for steep inclines.'), ) route_type = CharField('Route type', max_length=1, default='2', choices=ROUTE_TYPES) route_url = CharField('Route URL', max_length=240, blank=True) route_color = CharField('Route color', max_length=6, blank=True) route_text_color = CharField('Route text color', max_length=6, blank=True) route_sort_order = IntegerField('Route sort order', default=0, blank=True) class Meta: unique_together = ('company', 'route_id') ordering = ('agency', 'route_id') def __str__(self): return self.route_id @property def gtfs_header(self): return [ 'route_type', 'route_id', 'route_short_name', 'route_long_name', 'agency_id', 'route_url', 'route_color', 'route_text_color', 'route_sort_order' ] @property def routes_gtfs_header(self): return self.gtfs_header @property def shapes_gtfs_header(self): return [ 'shape_id', 'shape_pt_lat', 'shape_pt_lon', 'shape_pt_sequence' ] def gtfs_format(self): data = [ ('route_type', self.route_type), ('route_id', self.route_id), ('route_short_name', self.short_name.encode('utf-8')), ('route_long_name', self.long_name.encode('utf-8')), ('agency_id', self.agency.agency_id), ('route_url', self.route_url), ('route_color', self.route_color.upper()), ('route_text_color', self.route_text_color.upper()), ('route_sort_order', str(self.route_sort_order)), ] return OrderedDict(data) def export_to_shapes(self): """Export to shapes Output: list of dict for shapes.txt """ if not self.shapes: return [] results = [] seq = 1 for o in self.shapes.coords: _ = [ ('shape_id', self.route_id), ('shape_pt_lat', o[1]), ('shape_pt_lon', o[0]), ('shape_pt_sequence', seq), ] seq += 1 results.append(OrderedDict(_)) return results
class ST_SRID(Func): function = 'ST_SRID' output_field = IntegerField()
class LayerImage(Model): """ Geospatial image uploaded by the user. `meta_json` may be populated during geoprocessing and should contain a serialized JSON blob of image metadata. This blob should be in the form of key value pairs (object literal) and will be displayed as-is. """ layer = ForeignKey(Layer, related_name='layer_images') priority = IntegerField( default=0, help_text='The order which images are layered (starting from 0)') thumb_small_key = CharField(max_length=255, blank=True, default='', help_text='S3 key for small thumbnail') thumb_large_key = CharField(max_length=255, blank=True, default='', help_text='S3 key for large thumbnail') meta_json = TextField( null=True, blank=True, help_text='Serialized JSON of image metadata', ) min_x = FloatField(default=None, blank=True, null=True) max_x = FloatField(default=None, blank=True, null=True) min_y = FloatField(default=None, blank=True, null=True) max_y = FloatField(default=None, blank=True, null=True) file_name = CharField( blank=False, default='', max_length=255, help_text='Filename of original file', ) s3_uuid = UUIDField(default=uuid.uuid4, editable=False) file_extension = CharField(blank=False, default='', max_length=10, help_text='Extension of file') bucket_name = CharField(blank=False, default='', max_length=255, help_text='Name of S3 bucket') source_s3_bucket_key = CharField( blank=True, null=True, max_length=255, help_text='S3 <bucket>/<key> for source image (optional)') status_created = DateTimeField(auto_now_add=True) status_transfer_start = DateTimeField(null=True, blank=True) status_transfer_end = DateTimeField(null=True, blank=True) status_validate_start = DateTimeField(null=True, blank=True) status_validate_end = DateTimeField(null=True, blank=True) status_thumbnail_start = DateTimeField(null=True, blank=True) status_thumbnail_end = DateTimeField(null=True, blank=True) status_upload_error = CharField(max_length=255, blank=True, null=True) status_transfer_error = CharField(max_length=255, blank=True, null=True) status_validate_error = CharField(max_length=255, blank=True, null=True) status_thumbnail_error = CharField(max_length=255, blank=True, null=True) def reset(self): """ Resets fields to prepare for a retry. """ self.status_transfer_start = None self.status_transfer_end = None self.status_validate_start = None self.status_validate_end = None self.status_thumbnail_start = None self.status_thumbnail_end = None self.status_upload_error = None self.status_transfer_error = None self.status_validate_error = None self.status_thumbnail_error = None self.save() def has_been_validated(self): return self.status_validate_end is not None def is_copy_image(self): return self.source_s3_bucket_key is not None def get_s3_key(self): return '%d-%s.%s' % (self.layer.user.id, self.s3_uuid, self.file_extension) def get_s3_uri(self): return 's3://{}/{}-{}.{}'.format(self.bucket_name, self.layer.user_id, self.s3_uuid, self.file_extension) def to_json(self): return { 'id': self.id, 'thumb_small': generate_thumb_url(self.thumb_small_key), 'thumb_large': generate_thumb_url(self.thumb_large_key), 'meta_json': self.meta_json, 'min_x': self.min_x, 'max_x': self.max_x, 'min_y': self.min_y, 'max_y': self.max_y, 'file_name': self.file_name, 's3_uuid': str(self.s3_uuid), 'file_extension': self.file_extension, 'bucket_name': self.bucket_name, 'source_s3_bucket_key': self.source_s3_bucket_key, 'status_created': self.status_created is not None, 'status_transfer_start': self.status_transfer_start is not None, 'status_transfer_end': self.status_transfer_end is not None, 'status_validate_start': self.status_validate_start is not None, 'status_validate_end': self.status_validate_end is not None, 'status_thumbnail_start': self.status_thumbnail_start is not None, 'status_thumbnail_end': self.status_thumbnail_end is not None, 'status_upload_error': self.status_upload_error, 'status_transfer_error': self.status_transfer_error, 'status_validate_error': self.status_validate_error, 'status_thumbnail_error': self.status_thumbnail_error, 'source_s3_bucket_key': self.source_s3_bucket_key } def update_status_start(self, status): value = datetime.now() if status == enums.STATUS_TRANSFER: self.status_transfer_start = (value if self.status_transfer_start is None else self.status_transfer_start) elif status == enums.STATUS_VALIDATE: self.status_validate_start = (value if self.status_validate_start is None else self.status_validate_start) elif status == enums.STATUS_THUMBNAIL: self.status_thumbnail_start = (value if self.status_thumbnail_start is None else self.status_thumbnail_start) def update_status_end(self, status, error_message=None): value = datetime.now() if status == enums.STATUS_TRANSFER: self.status_transfer_end = value self.status_transfer_error = error_message elif status == enums.STATUS_VALIDATE: self.status_validate_end = value self.status_validate_error = error_message elif status == enums.STATUS_THUMBNAIL: self.status_thumbnail_end = value self.status_thumbnail_error = error_message def set_bounds(self, bounds): self.min_x = bounds[0] self.max_x = bounds[1] self.min_y = bounds[2] self.max_y = bounds[3] self.save(update_fields=['min_x', 'max_x', 'min_y', 'max_y'])
class Place(Base): # attribution attribution = TextField(null=True, blank=True, db_index=DB_INDEX) # concordances enwiki_title = TextField(null=True, blank=True, db_index=DB_INDEX) geonames_id = IntegerField(null=True, blank=True, db_index=DB_INDEX) osm_id = TextField(null=True, blank=True, db_index=DB_INDEX) pcode = TextField(null=True, blank=True, db_index=DB_INDEX) fips = IntegerField(null=True, blank=True, db_index=DB_INDEX) # admin stuff admin1_code = TextField(null=True, blank=True, db_index=DB_INDEX) admin2_code = TextField(null=True, blank=True, db_index=DB_INDEX) admin3_code = TextField(null=True, blank=True, db_index=DB_INDEX) admin4_code = TextField(null=True, blank=True, db_index=DB_INDEX) admin_level = IntegerField(null=True, blank=True, db_index=DB_INDEX) # bounding box stuff east = FloatField(null=True, blank=True) north = FloatField(null=True, blank=True) south = FloatField(null=True, blank=True) west = FloatField(null=True, blank=True) # name stuff name = TextField(null=True, blank=True, db_index=DB_INDEX) name_ascii = TextField(null=True, blank=True, db_index=DB_INDEX) name_display = TextField(null=True, blank=True, db_index=DB_INDEX) name_en = TextField(null=True, blank=True, db_index=DB_INDEX) name_normalized = TextField(null=True, blank=True, db_index=DB_INDEX) other_names = TextField(null=True, blank=True, db_index=False) # place types geonames_feature_class = TextField(null=True, blank=True, db_index=DB_INDEX) geonames_feature_code = TextField(null=True, blank=True, db_index=DB_INDEX) place_type = TextField(null=True, blank=True, db_index=DB_INDEX) # geometries objects = GeoManager() latitude = FloatField(null=True, blank=True) longitude = FloatField(null=True, blank=True) mls = MultiLineStringField(null=True, blank=True) mpoly = MultiPolygonField(null=True, blank=True) point = PointField(null=True, blank=True) area_sqkm = IntegerField(null=True, blank=True) # osm stuff importance = FloatField(null=True, blank=True) osmname_class = TextField(null=True, blank=True, db_index=DB_INDEX) osmname_type = TextField(null=True, blank=True, db_index=DB_INDEX) osm_type = TextField(null=True, blank=True, db_index=DB_INDEX) place_rank = IntegerField(null=True, blank=True, db_index=DB_INDEX) # dem and elevation stuff dem = FloatField(null=True, blank=True) elevation = FloatField(null=True, blank=True) # geocoder stuff city = TextField(null=True, blank=True, db_index=DB_INDEX) county = TextField(null=True, blank=True, db_index=DB_INDEX) # should be 100 country = TextField(null=True, blank=True, db_index=DB_INDEX) country_code = TextField(null=True, blank=True, db_index=DB_INDEX) state = TextField(null=True, blank=True, db_index=DB_INDEX) street = TextField(null=True, blank=True, db_index=DB_INDEX) #misc note = TextField(null=True, blank=True) population = BigIntegerField(null=True, blank=True, db_index=DB_INDEX) # number of times name appeared and meant this place minus number of times didn't mean this place popularity = BigIntegerField(null=True, blank=True, db_index=DB_INDEX) timezone = TextField(null=True, blank=True, db_index=DB_INDEX) topic = ForeignKey("Topic", null=True, on_delete=SET_NULL, db_index=DB_INDEX) # represents the most common topic associated with this place wikidata_id = TextField(null=True, blank=True, db_index=DB_INDEX) def get_all_names(self): if not hasattr(self, "all_names"): names = set() names.add(self.name) names.add(self.name_ascii) names.add(self.name_display) names.add(self.name_en) names.add(self.name_normalized) if self.other_names: for other_name in self.other_names.split(","): names.add(other_name) names.discard(None) self.all_names = names return self.all_names class Meta: ordering = ['name']
def output_field(self): return IntegerField()
class Media(Model): """ Fields: original: Originally uploaded file. Users cannot interact with it except by downloading it. .. deprecated :: Use media_files object segment_info: File for segment files to support MSE playback. .. deprecated :: Use meda_files instead media_files: Dictionary to contain a map of all files for this media. The schema looks like this: .. code-block :: map = {"archival": [ VIDEO_DEF, VIDEO_DEF,... ], "streaming": [ VIDEO_DEF, VIDEO_DEF, ... ], <"audio": [AUDIO_DEF]>} video_def = {"path": <path_to_disk>, "codec": <human readable codec>, "resolution": [<vertical pixel count, e.g. 720>, width] audio_def = {"path": <path_to_disk>, "codec": <human readable codec>} ################### # Optional Fields # ################### # Path to the segments.json file for streaming files. # not expected/required for archival. Required for # MSE playback with seek support for streaming files. segment_info = <path_to_json> # If supplied will use this instead of currently # connected host. e.g. https://example.com "host": <host url> # If specified will be used for HTTP authorization # in the request for media. I.e. "bearer <token>" "http_auth": <http auth header> # Example mime: 'video/mp4; codecs="avc1.64001e"' # Only relevant for straming files, will assume # example above if not present. "codec_mime": <mime for MSE decode> "codec_description": <description other than codec>} """ project = ForeignKey(Project, on_delete=SET_NULL, null=True, blank=True, db_column='project') meta = ForeignKey(MediaType, 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 MediaType 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. """ gid = CharField(max_length=36, null=True, blank=True) """ Group ID for the upload that created this media. Note we intentionally do not use UUIDField because this field is provided by the uploader and not guaranteed to be an actual UUID. """ uid = CharField(max_length=36, null=True, blank=True) """ Unique ID for the upload that created this media. Note we intentionally do not use UUIDField because this field is provided by the uploader and not guaranteed to be an actual UUID. """ 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='media_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='media_modified_by', db_column='modified_by') name = CharField(max_length=256) md5 = SlugField(max_length=32) """ md5 hash of the originally uploaded file. """ file = FileField(null=True, blank=True) last_edit_start = DateTimeField(null=True, blank=True) """ Start datetime of a session in which the media's annotations were edited. """ last_edit_end = DateTimeField(null=True, blank=True) """ End datetime of a session in which the media's annotations were edited. """ original = FilePathField(path=settings.RAW_ROOT, null=True, blank=True) thumbnail = ImageField(null=True, blank=True) thumbnail_gif = ImageField(null=True, blank=True) num_frames = IntegerField(null=True, blank=True) fps = FloatField(null=True, blank=True) codec = CharField(null=True, blank=True, max_length=256) width = IntegerField(null=True) height = IntegerField(null=True) segment_info = FilePathField(path=settings.MEDIA_ROOT, null=True, blank=True) media_files = JSONField(null=True, blank=True) def update_media_files(self, media_files): """ Updates media files by merging a new key into existing JSON object. """ # Handle null existing value. if self.media_files is None: self.media_files = {} # Append to existing definitions. new_streaming = media_files.get('streaming', []) old_streaming = self.media_files.get('streaming', []) streaming = new_streaming + old_streaming new_archival = media_files.get('archival', []) old_archival = self.media_files.get('archival', []) archival = new_archival + old_archival new_audio = media_files.get('audio', []) old_audio = self.media_files.get('audio', []) audio = new_audio + old_audio for fp in new_streaming: path = fp['path'] seg_path = fp['segment_info'] Resource.add_resource(path) Resource.add_resource(seg_path) for fp in new_archival: Resource.add_resource(fp['path']) for fp in new_audio: Resource.add_resource(fp['path']) # Only fill in a key if it has at least one definition. self.media_files = {} if streaming: streaming.sort(key=lambda x: x['resolution'][0], reverse=True) self.media_files['streaming'] = streaming if archival: self.media_files['archival'] = archival if audio: self.media_files['audio'] = audio # Handle roi, layout, and quality for x in ['layout', 'ids', 'quality']: if x in media_files: self.media_files[x] = media_files[x]
class Media(Model): """ Fields: original: Originally uploaded file. Users cannot interact with it except by downloading it. .. deprecated :: Use media_files object segment_info: File for segment files to support MSE playback. .. deprecated :: Use meda_files instead media_files: Dictionary to contain a map of all files for this media. The schema looks like this: .. code-block :: map = {"archival": [ VIDEO_DEF, VIDEO_DEF,... ], "streaming": [ VIDEO_DEF, VIDEO_DEF, ... ], <"audio": [AUDIO_DEF]>} video_def = {"path": <path_to_disk>, "codec": <human readable codec>, "resolution": [<vertical pixel count, e.g. 720>, width] audio_def = {"path": <path_to_disk>, "codec": <human readable codec>} ################### # Optional Fields # ################### # Path to the segments.json file for streaming files. # not expected/required for archival. Required for # MSE playback with seek support for streaming files. segment_info = <path_to_json> # If supplied will use this instead of currently # connected host. e.g. https://example.com "host": <host url> # If specified will be used for HTTP authorization # in the request for media. I.e. "bearer <token>" "http_auth": <http auth header> # Example mime: 'video/mp4; codecs="avc1.64001e"' # Only relevant for straming files, will assume # example above if not present. "codec_mime": <mime for MSE decode> "codec_description": <description other than codec>} """ project = ForeignKey(Project, on_delete=SET_NULL, null=True, blank=True, db_column='project', related_name='media_project') meta = ForeignKey(MediaType, 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 MediaType 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. """ gid = CharField(max_length=36, null=True, blank=True) """ Group ID for the upload that created this media. Note we intentionally do not use UUIDField because this field is provided by the uploader and not guaranteed to be an actual UUID. """ uid = CharField(max_length=36, null=True, blank=True) """ Unique ID for the upload that created this media. Note we intentionally do not use UUIDField because this field is provided by the uploader and not guaranteed to be an actual UUID. """ 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='media_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='media_modified_by', db_column='modified_by') name = CharField(max_length=256) md5 = SlugField(max_length=32) """ md5 hash of the originally uploaded file. """ file = FileField(null=True, blank=True) last_edit_start = DateTimeField(null=True, blank=True) """ Start datetime of a session in which the media's annotations were edited. """ last_edit_end = DateTimeField(null=True, blank=True) """ End datetime of a session in which the media's annotations were edited. """ original = FilePathField(path=settings.RAW_ROOT, null=True, blank=True) thumbnail = ImageField(null=True, blank=True) thumbnail_gif = ImageField(null=True, blank=True) num_frames = IntegerField(null=True, blank=True) fps = FloatField(null=True, blank=True) codec = CharField(null=True, blank=True, max_length=256) width = IntegerField(null=True) height = IntegerField(null=True) segment_info = FilePathField(path=settings.MEDIA_ROOT, null=True, blank=True) media_files = JSONField(null=True, blank=True) recycled_from = ForeignKey(Project, on_delete=SET_NULL, null=True, blank=True, related_name='recycled_from')
class EntityMediaImage(EntityMediaBase): thumbnail = ImageField() width=IntegerField(null=True) height=IntegerField(null=True)
class AttributeTypeInt(AttributeTypeBase): attr_name = "Integer" dtype = "int" default = IntegerField(null=True, blank=True) lower_bound = IntegerField(null=True, blank=True) upper_bound = IntegerField(null=True, blank=True)
class StopTime(CompanyBoundModel): """ "trip_id", "arrival_time", "departure_time", "stop_id", "stop_sequence", "stop_headsign", "pickup_type", "drop_off_type", "shape_dist_traveled", "timepoint", "continuous_drop_off", "continuous_pickup" """ trip = ForeignKey('trip') stop = ForeignKey('stop') arrival = TimeField('Arrival time') departure = TimeField('Departure time') sequence = IntegerField('Stop sequence', default=0) # optional stop_headsign = CharField('Stop headsign', max_length=30, blank=True) PICKUP_CHOICES = ( ('0', 'Regularly scheduled pickup'), ('1', 'No pickup available'), ('2', 'Must phone agency to arrange pickup'), ('3', 'Must coordinate with driver to arrange pickup'), ) pickup_type = CharField('Pickup type', max_length=1, default='0', choices=PICKUP_CHOICES) DROPOFF_CHOICES = ( ('0', 'Regularly scheduled drop off'), ('1', 'No drop off available'), ('2', 'Must phone agency to arrange drop off'), ('3', 'Must coordinate with driver to arrange drop off'), ) drop_off_type = CharField('Drop off type', max_length=1, default='0', choices=DROPOFF_CHOICES) shape_dist_traveled = CharField('Travel distance in km', max_length=5, blank=True) TIMEPOINT_CHOICES = ( ('', 'Times are considered exact.'), ('0', 'Times are considered approximate.'), ('1', 'Times are considered exact.'), ) timepoint = CharField('Timepoint', max_length=1, default='', choices=TIMEPOINT_CHOICES) class Meta: verbose_name_plural = "Stop times" ordering = [ 'sequence', ] def __str__(self): return 'trip #%s seq#%s-%s' % (self.trip.id, self.sequence, self.arrival) @property def gtfs_header(self): return [ 'trip_id', 'arrival_time', 'departure_time', 'stop_id', 'stop_sequence', 'stop_headsign', 'pickup_type', 'drop_off_type', 'shape_dist_traveled', 'timepoint' ] def gtfs_format(self): data = [ ('trip_id', self.trip.trip_id), ('arrival_time', self.arrival), ('departure_time', self.departure), ('stop_id', self.stop.stop_id), ('stop_sequence', self.sequence), ('stop_headsign', self.stop_headsign), ('pickup_type', self.pickup_type), ('drop_off_type', self.drop_off_type), ('shape_dist_traveled', self.shape_dist_traveled), ('timepoint', self.timepoint), ] return OrderedDict(data)
class EntityMediaVideo(EntityMediaBase): """ Fields: original: Originally uploaded file. Users cannot interact with it except by downloading it. .. deprecated :: Use media_files object segment_info: File for segment files to support MSE playback. .. deprecated :: Use meda_files instead media_files: Dictionary to contain a map of all files for this media. The schema looks like this: .. code-block :: map = {"archival": [ VIDEO_DEF, VIDEO_DEF,... ], "streaming": [ VIDEO_DEF, VIDEO_DEF, ... ]} video_def = {"path": <path_to_disk>, "codec": <human readable codec>, "resolution": <vertical pixel count, e.g. 720> ################### # Optional Fields # ################### # Path to the segments.json file for streaming files. # not expected/required for archival. Required for # MSE playback with seek support for streaming files. segment_info = <path_to_json> # If supplied will use this instead of currently # connected host. e.g. https://example.com "host": <host url> # If specified will be used for HTTP authorization # in the request for media. I.e. "bearer <token>" "http_auth": <http auth header> # Example mime: 'video/mp4; codecs="avc1.64001e"' # Only relevant for straming files, will assume # example above if not present. "codec-mime": <mime for MSE decode> "description": <description other than codec>} """ original = FilePathField(path=settings.RAW_ROOT, null=True, blank=True) thumbnail = ImageField() thumbnail_gif = ImageField() num_frames = IntegerField(null=True) fps = FloatField(null=True) codec = CharField(null=True,max_length=256) width=IntegerField(null=True) height=IntegerField(null=True) segment_info = FilePathField(path=settings.MEDIA_ROOT, null=True, blank=True) media_files = JSONField(null=True, blank=True)