class User(models.Model): # id bigint NOT NULL, id = models.BigAutoField(primary_key = True) # uuid uuid DEFAULT public.gen_random_uuid(), uuid = models.UUIDField(blank = True, null = False) # name_first character varying, name_first = models.CharField(max_length = 255, blank = True) # name_last character varying, name_last = models.CharField(max_length = 255, blank = True) # nickname character varying, nickname = models.CharField(max_length = 255, blank = True) # avatar_url character varying, avatar_url = models.CharField(max_length = 255, blank = True) # email character varying, email = models.CharField(max_length = 255, blank = True) # created_at timestamp without time zone DEFAULT now() NOT NULL, created_at = models.DateTimeField() # updated_at timestamp without time zone DEFAULT now() NOT NULL, updated_at = models.DateTimeField() # preferences jsonb, preferences = models.JSONField(blank = True) # avatar_image bytea, avatar_image = models.BinaryField(blank = True) # non_user_notification_state jsonb non_user_notification_state = models.JSONField(blank = True) class Meta: managed = False db_table = 'users' required_db_vendor = 'postgis'
class V2OfCollections(models.Model): lon = models.DecimalField(max_digits=10, decimal_places=5, blank=True, null=True) lat = models.DecimalField(max_digits=10, decimal_places=5, blank=True, null=True) geomcol1 = models.BinaryField(blank=True, null=True) geomcol2 = models.GeometryField(blank=True, null=True) time_tx = models.DateTimeField(blank=True, null=True) time_rx = models.DateTimeField(blank=True, null=True) campaign = models.ForeignKey(V2OfCampaigns, on_delete=models.CASCADE, blank=True, null=True) device = models.ForeignKey(V2OfDevices, on_delete=models.CASCADE, blank=True, null=True) class Meta: managed = False db_table = 'v2of_collections' verbose_name_plural = format_lazy('{}', db_table)
class EmailMessage(models.Model): message_id = models.CharField(max_length=998, primary_key=True) pickled_message = models.BinaryField() to = ArrayField(models.CharField(max_length=254, db_index=True)) subject = models.CharField(max_length=200) tags = ArrayField(models.CharField(max_length=100, db_index=True), null=True) created_at = models.DateTimeField(auto_now_add=True, db_index=True) user = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE) send_count = models.SmallIntegerField(default=0) objects = EmailMessageManager() @property def message(self): return pickle.loads(self.pickled_message) @message.setter def message(self, value): self.pickled_message = pickle.dumps(value) def send(self): self.message.send() self.send_count += 1 self.save() def __unicode__(self): return self.subject
class GeoFile(models.Model): uid = models.TextField(primary_key=True) content = models.BinaryField(null=True) filename = models.TextField(null=True) geom = models.GeometryField(null=True) descriptor = models.TextField(null=True) objects = models.GeoManager() @staticmethod def create_and_save_from_file(path, geom, descriptor=None): filename = os.path.basename(path) file = open(path, mode='r') geofile = GeoFile() geofile.uid = get_uid() geofile.filename = filename geofile.content = file.read() geofile.geom = geom geofile.descriptor = descriptor geofile.save() file.close() return geofile def write_to_disk_from_db(self, filepath): file = open(filepath, 'w') file.write(self.content) file.close() @staticmethod def get_geofiles_in_geom(geom): return GeoFile.objects.filter(geom__intersects=geom)
class Changeset(models.Model): """ Model used to record the changes to a Proposal over time. """ proposal = models.ForeignKey(Proposal, related_name="changes") created = models.DateTimeField(auto_now_add=True) change_blob = models.BinaryField() @classmethod def from_changes(kls, proposal, changes): instance = kls(proposal=proposal) instance.changes = changes return instance @property def changes(self): # { "properties": [ { } ] , # "attributes": [ { } ] } d = getattr(self, "_change_dict", None) if not d: d = pickle.loads(self.change_blob) if self.change_blob else {} self._change_dict = d return d @changes.setter def changes(self, d): self._change_dict = d self.change_blob = pickle.dumps(d)
class Calendars(models.Model): name = models.CharField(max_length=128) attributes = models.CharField(max_length=4000) data = models.BinaryField() class Meta: managed = False db_table = 'calendars'
class Extensions(models.Model): idextensio = models.CharField(primary_key=True, max_length=100) extensio = models.CharField(max_length=25, blank=True, null=True) descripcio = models.CharField(max_length=500, blank=True, null=True) fitxericona = models.BinaryField(blank=True, null=True) class Meta: managed = False db_table = 'extensions'
class ImageTemplate(models.Model): created_date = models.DateTimeField(auto_now_add=True) # for example, 38339293847298372.jpg filename = models.CharField(blank=False, null=False, max_length=250) image_template = models.BinaryField(blank=False, null=False) def __unicode__(self): return self.filename
class MVTLayers(models.Model): """ Store generated MVT layers """ zoom = models.PositiveIntegerField() x_coor = models.PositiveIntegerField() y_coor = models.PositiveIntegerField() layer = models.TextField(max_length=64) tile = models.BinaryField() class Meta: unique_together = ("zoom", "x_coor", "y_coor", "layer")
class RLESegmentation(Segmentation): """run-length-encoded (RLE) segmentation. A bit mask of the entire image to label one thing (or a crowd of that thing). The RLE array is stored as a binary blob. """ blob = models.BinaryField() height = models.PositiveIntegerField() width = models.PositiveIntegerField() @staticmethod def _array_to_blob(array): if not isinstance(array, np.ndarray): array = np.array(array) return base64.b64encode(pickle.dumps(array)) @staticmethod def _blob_to_array(blob): return pickle.loads(base64.b64decode(blob)) def from_rle(self, rle): """Populate the entry from an RLE JSON spec. Parameters ---------- rle : dict A dictionary with ``counts`` and ``size`` fields """ counts = rle['counts'] height, width = rle['size'] self.height = height self.width = width self.blob = self._array_to_blob(counts) def to_rle(self): """Generate an RLE JSON spec from the entry.""" counts = self._blob_to_array(self.blob) return {'counts': list(counts), 'size': [self.height, self.width]} def to_mask(self): """Produce a 2D array of booleans for this RLE Segmentation.""" counts = self._blob_to_array(self.blob) shape = (self.height, self.width) mask = np.zeros(shape, dtype=np.bool_).ravel() current = 0 flag = False for count in counts: mask[current : current + count] = flag current += count flag = not flag return mask.reshape(shape)
class Imatges(models.Model): idimatge = models.CharField(primary_key=True, max_length=100) titol = models.CharField(max_length=4000, blank=True, null=True) observacions = models.CharField(max_length=500, blank=True, null=True) nomoriginal = models.CharField(max_length=255, blank=True, null=True) thumbnail = models.BinaryField(blank=True, null=True) fitxer = models.BinaryField(blank=True, null=True) fitxer = models.FileField(upload_to='imatges_especies', blank=True, null=True) visualitzable = models.CharField(max_length=1, blank=True, null=True) tag = models.CharField(max_length=255, blank=True, null=True) # FOREIGN KEYS idextensio = models.ForeignKey(Extensions, models.DO_NOTHING, db_column='idextensio', blank=True, null=True) class Meta: managed = False db_table = 'imatges'
class Documents(models.Model): iddocument = models.CharField(primary_key=True, max_length=100) titol = models.CharField(max_length=500, blank=True, null=True) observacions = models.CharField(max_length=500, blank=True, null=True) idextensio = models.ForeignKey('Extensions', models.DO_NOTHING, db_column='idextensio', blank=True, null=True) nomoriginal = models.CharField(max_length=255, blank=True, null=True) fitxer = models.BinaryField(blank=True, null=True) class Meta: managed = False db_table = 'documents'
class UserSettings(models.Model): ctime = models.DateTimeField(auto_now_add=True, null=True, blank=True) mtime = models.DateTimeField(auto_now=True, null=True, blank=True) session_key = models.CharField( max_length=32, null=True, blank=True, unique=True, db_index=True) # session = models.ForeignKey(Session, null=True, blank=True) key = models.CharField(max_length=32, null=True, blank=True, db_index=True) username = models.CharField(max_length=32, null=True, blank=True) password = models.CharField(max_length=32, null=True, blank=True) level_date = models.TextField(null=True, blank=True) referral = models.CharField(max_length=32, null=True, blank=True) busfav = models.BinaryField(null=True, blank=True) busfavor_amount = models.SmallIntegerField(default=5) stars = models.SmallIntegerField(default=0, null=True, blank=True) comment = models.CharField(max_length=256, null=True, blank=True) premium = models.BooleanField(default=0) vip = models.BooleanField(default=0) noads = models.BooleanField(default=0) theme = models.SmallIntegerField(default=0, choices=THEME_CHOICES) theme_save = models.SmallIntegerField(null=True, blank=True) mode = models.SmallIntegerField(default=1, choices=MODE_CHOICES) sound = models.BooleanField(default=1) sound_plusone = models.BooleanField(default=False) gps_off = models.BooleanField(default=0) city = models.ForeignKey(City, null=True, blank=True) tcard = models.CharField(max_length=20, null=True, blank=True) ip = models.GenericIPAddressField(null=True, blank=True) ua = models.CharField(max_length=512, null=True, blank=True) vk_like_pro = models.SmallIntegerField(default=0) theme_stripes = models.BooleanField(default=1) pro_demo = models.BooleanField(default=False) pro_demo_date = models.DateTimeField(null=True, blank=True) multi_all = models.BooleanField(default=False) matrix_show = models.BooleanField(default=True) map_show = models.BooleanField(default=False) speed_show = models.BooleanField(default=False) font_big = models.BooleanField(default=False) def __unicode__(self): return "%s" % self.id def save(self, *args, **kwargs): if not self.premium and not self.pro_demo: self.busfavor_amount = 5 super(UserSettings, self).save(*args, **kwargs)
class Person(models.Model): gender = models.CharField(max_length=1, choices=GENDER_CHOICES) # Jards Macalé is an amazing brazilian musician! =] enjoy_jards_macale = models.BooleanField(default=True) like_metal_music = models.BooleanField(default=False) name = models.CharField(max_length=30) nickname = models.SlugField(max_length=36) age = models.IntegerField() bio = models.TextField() birthday = models.DateField() birth_time = models.TimeField() appointment = models.DateTimeField() blog = models.URLField() occupation = models.CharField(max_length=10, choices=OCCUPATION_CHOICES) uuid = models.UUIDField(primary_key=False) name_hash = models.BinaryField(max_length=16) days_since_last_login = models.BigIntegerField() duration_of_sleep = models.DurationField() email = models.EmailField() id_document = models.CharField(unique=True, max_length=10) try: from django.contrib.postgres.fields import ArrayField, HStoreField, JSONField from django.contrib.postgres.fields.citext import ( CICharField, CIEmailField, CITextField, ) acquaintances = ArrayField(models.IntegerField()) data = JSONField() hstore_data = HStoreField() ci_char = CICharField(max_length=30) ci_email = CIEmailField() ci_text = CITextField() except ImportError: # Skip PostgreSQL-related fields pass if BAKER_GIS: geom = models.GeometryField() point = models.PointField() line_string = models.LineStringField() polygon = models.PolygonField() multi_point = models.MultiPointField() multi_line_string = models.MultiLineStringField() multi_polygon = models.MultiPolygonField() geom_collection = models.GeometryCollectionField()
class DocumentIndexAttachment(models.Model): """ Attachments for one Document. """ index = models.ForeignKey(DocumentIndex, related_name='attachments') category = models.CharField(max_length=50, db_index=True) content_type = models.CharField(max_length=255) data = models.BinaryField() # Attachments are almost independent from Documents thus they should # have people responsible for them. created_at = models.DateTimeField(auto_now_add=True, editable=False) modified_at = models.DateTimeField(auto_now=True, editable=False) # Users responsible for the aforementioned actions. created_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='attachments_created') modified_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='attachments_modified') objects = DocumentIndexAttachmentManager() class Meta: ordering = ['pk'] verbose_name = 'Attachment' verbose_name_plural = 'Attachments' def __str__(self): return str(self.id) def verbose_name(self): return str(self.data) def format_attachment_id(self): if self.id is None: return url = reverse('admin:%s_%s_change' % (self._meta.app_label, self._meta.object_name.lower()), args=[self.id]) return "<a href='%s'>%d</a>" % (url, self.id) format_attachment_id.allow_tags = True format_attachment_id.short_description = 'Attachment ID' def format_filesize(self): return filesizeformat(len(self.data)) format_filesize.short_description = 'File size' format_filesize.admin_order_field = 'filesize'
class Person(models.Model): gender = models.CharField(max_length=1, choices=GENDER_CHOICES) happy = models.BooleanField(default=True) unhappy = models.BooleanField(default=False) bipolar = models.BooleanField(default=False) name = models.CharField(max_length=30) nickname = models.SlugField(max_length=36) age = models.IntegerField() bio = models.TextField() birthday = models.DateField() birth_time = models.TimeField() appointment = models.DateTimeField() blog = models.URLField() occupation = models.CharField(max_length=10, choices=OCCUPATION_CHOICES) uuid = models.UUIDField(primary_key=False) name_hash = models.BinaryField(max_length=16) wanted_games_qtd = models.BigIntegerField() duration_of_sleep = models.DurationField() email = models.EmailField() try: from django.contrib.postgres.fields import ArrayField, HStoreField, JSONField from django.contrib.postgres.fields.citext import CICharField, CIEmailField, CITextField acquaintances = ArrayField(models.IntegerField()) data = JSONField() hstore_data = HStoreField() ci_char = CICharField(max_length=30) ci_email = CIEmailField() ci_text = CITextField() except ImportError: # Skip PostgreSQL-related fields pass if MOMMY_GIS: geom = models.GeometryField() point = models.PointField() line_string = models.LineStringField() polygon = models.PolygonField() multi_point = models.MultiPointField() multi_line_string = models.MultiLineStringField() multi_polygon = models.MultiPolygonField() geom_collection = models.GeometryCollectionField()
class Changeset(models.Model): """ Model used to record the changes to a Proposal over time. """ proposal = models.ForeignKey(Proposal, related_name="changesets", on_delete=models.CASCADE) created = models.DateTimeField(default=timezone.now) change_blob = models.BinaryField() @classmethod def from_changes(kls, proposal, changes): """Create a new Changeset for a proposal. :param proposal: a Proposal object :param changes: a dictionary with "properties" and "attributes" keys. Each should be a list of dicts containing "name", the name of the change property or attribute; "new", the new value or None; and "old", the old value or None. """ instance = kls(proposal=proposal) instance.changes = changes return instance @property def changes(self): # { "properties": [ { } ] , # "attributes": [ { } ] } d = getattr(self, "_change_dict", None) if not d: d = pickle.loads(self.change_blob) if self.change_blob else {} self._change_dict = d return d @changes.setter def changes(self, d): self._change_dict = d self.change_blob = pickle.dumps(d)
class ImageTile(models.Model): class Meta: verbose_name_plural = 'Image Tiles' imagetile_id = models.AutoField(primary_key=True) imagetile_x = models.IntegerField(null=True, verbose_name="X") imagetile_y = models.IntegerField(null=True, verbose_name="Y") imagetile_zoom = models.IntegerField(null=True, verbose_name="Zoom") imagetile_size = models.IntegerField(null=True, verbose_name="Tile size") imagetile_layer = models.ForeignKey(ImageLayer, null=True, on_delete=models.CASCADE, verbose_name='Image Layer') image = models.BinaryField(null=True) def __str__(self): params = (self.imagetile_layer.imagelayer_name, self.imagetile_zoom, self.imagetile_x, self.imagetile_y) return '%s [Z=%d X=%d Y=%d]' % params def __repr__(self): return self.__str__() @staticmethod def get(imagelayer : object, zoom : int, x : int, y : int) -> object: """ Get image tile by imagelayer, X, Y, Zoom """ # create params params = { 'imagetile_layer' : imagelayer, 'imagetile_x' : x, 'imagetile_y' : y, 'imagetile_zoom' : zoom } # get queryset queryset = ImageTile.objects.filter( **params ) # get first elt tile = queryset.first() # return value return tile
def __init__(self, *expressions, **extra): super().__init__( *expressions, output_field=ArrayField(base_field=models.BinaryField()), **extra )
class ProfilePicture(models.Model): user = models.OneToOneField('accounts.User', on_delete=models.CASCADE, related_name='picture') image = models.BinaryField()
class Person(models.Model): """ ## Fields ### `id` (`integer`) Primary key. ### `first_name` (`string`) First name of person. ### `last_name` (`string`) Last name of person. ### `title` (`string`) Titles bestowed onto the person. ### `email` (`string`) <i class="glyphicon glyphicon-lock"></i> Email address (*only visible when authenticated*). ### `room` (`integer`) Foreign key to [CAMPUSonline room](../room) where this person has their primary workplace. ### `card` (`string`) URL to CAMPUSonline business card. ### `sex` (`string`) Sex of person: * `W` (Female) * `M` (Male) ### `consultation` (`string`) Consultation hours as free form text. Content may contain other information. ### `appendix` (`string`) Miscellaneous information about person as free form text. ### `avatar` (`string`) URL to user avatar picture. May point to an empty image. ### `phone` (`string`) Office phone number of person. ### `phone_external` (`string`) External phone number of person. ### `fax` (`string`) Office fax number of person. ### `functions` (`[integer]`) <i class="glyphicon glyphicon-lock"></i> List of foreign keys to [CAMPUSonline functions](../function) this person carries. ### `organizations` (`[integer]`) <i class="glyphicon glyphicon-lock"></i> List of foreign keys to [CAMPUSonline organizations](../organization) where this person is currently active. ### `organizations_leave` (`[integer]`) <i class="glyphicon glyphicon-lock"></i> List of foreign keys to [CAMPUSonline organizations](../organization) where this person is currently on leave. """ GENDER_CHOICES = ( ("W", _("Female")), ("M", _("Male")), ("X", _("Divers")), ("U", _("Unknown")), ("O", _("Open")), ("I", _("Inter")), ("K", _("No record")), ) id = models.IntegerField(primary_key=True) first_name = models.CharField(max_length=256, blank=True, null=True) last_name = models.CharField(max_length=256, blank=True, null=True) title = models.CharField(max_length=256, blank=True, null=True) email = models.EmailField() room = models.ForeignKey( "Room", models.SET_NULL, db_constraint=False, null=True, blank=True, related_name="+", ) sex = models.CharField(choices=GENDER_CHOICES, max_length=1, blank=True, null=True) username = models.CharField(max_length=256, blank=True, null=True) consultation = models.TextField(blank=True, null=True) appendix = models.TextField(blank=True, null=True) avatar = models.URLField(blank=True, null=True) card = models.URLField(blank=True, null=True) functions = models.ManyToManyField("Function", through="PersonOrganizationFunction") organizations = models.ManyToManyField( "Organization", db_table="campusonline_person_organization", db_constraint=False, related_name="persons", ) organizations_leave = models.ManyToManyField( "Organization", db_table="campusonline_person_organization_leave", db_constraint=False, related_name="persons_leave", ) avatar_private = models.BinaryField() hash = models.CharField(max_length=64) phone = models.CharField(max_length=256, blank=True, null=True) mobile = models.CharField(max_length=256, blank=True, null=True) employed = models.BooleanField() card = models.URLField(blank=True, null=True) fax = models.CharField(max_length=256, blank=True, null=True) phone_external = models.CharField(max_length=256, blank=True, null=True) class Meta: managed = False db_table = "campusonline_person" ordering = ("last_name", "first_name") class Refresh: interval = 1800 def __str__(self): return "{s.last_name}, {s.first_name}".format(s=self)
class Subscription(models.Model): # The subscription belong to a registered user: user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="subscriptions") active = models.BooleanField( default=False, help_text="Users only receive updates for active subscriptions") created = models.DateTimeField(default=datetime.utcnow) updated = models.DateTimeField(default=datetime.utcnow) # Stores the pickle serialization of a dictionary describing the query query = models.BinaryField() include_events = models.CharField( max_length=256, default="", blank=True, help_text="Include events for a specified region") last_notified = models.DateTimeField(default=datetime.now) objects = SubscriptionQuerySet.as_manager() def save(self, *args, **kwargs): self.updated = datetime.now() super().save(*args, **kwargs) def confirm(self): if settings.LIMIT_SUBSCRIPTIONS: # Disable all this user's other subscriptions: self.user.subscriptions\ .filter(active=True)\ .exclude(pk=self.pk)\ .update(active=False) self.user.profile.activate() self.active = True self.save() @property def confirm_url(self): return "{base}?token={token}&uid={uid}&sub={sub_id}".format( base=reverse("confirm"), token=self.user.profile.token, uid=self.user.pk, sub_id=self.pk) @property def query_dict(self): return pickle.loads(self.query) @query_dict.setter def query_dict(self, new_dict): self.query = pickle.dumps(new_dict) def set_validated_query(self, q): self.query_dict = self.validate_query(q) valid_keys = { "projects": lambda v: v.lower() in {"all", "null"}, "text": lambda _: True, "box": lambda v: (len(v.split(",")) == 4 and all( re.match(r"-?\d+\.\d+", c) for c in v.split(","))) } @classmethod def validate_query(kls, q): validated = {} for k, v in q.items(): if k not in kls.valid_keys: continue if kls.valid_keys[k](v): validated[k] = v return validated @staticmethod def readable_query(query): if "project" in query: if query["project"] == "all": desc = "Public proposals " else: desc = "Private proposals " else: desc = "All proposals " if "text" in query: desc += "matching \"" + query["text"] + "\" " if "box" in query: coords = [float(s) for s in query["box"].split(",")] desc += "".join([ "inside the region: ", prettify_lat(coords[0]), ", ", prettify_long(coords[1]), " and ", prettify_lat(coords[2]), ", ", prettify_long(coords[3]) ]) return desc @property def readable_description(self): return self.readable_query(self.query_dict) @property def minimap_src(self): query = self.query_dict if "box" in query: coords = [float(s) for s in query["box"].split(",")] return settings.MINIMAP_SRC\ .format(swlat=coords[0], swlon=coords[1], nelat=coords[2], nelon=coords[3]) else: return None
class Document(models.Model): """ A document of a particular type. Each document within Jane's document database is essentially a file of any type that is described by indices. """ # The type of the document. Depends on the available Jane plug-ins. document_type = models.ForeignKey(DocumentType, related_name='documents') # The name of that particular document. Oftentimes the filename. Unique # together with the document type to enable a nice REST API. name = models.CharField(max_length=255, db_index=True) # The content type of the data. Must be given to be able to provide a # reasonable HTTP view of the data. content_type = models.CharField(max_length=255) # The actual data as a binary field. data = models.BinaryField(editable=False) # The file's size in bytes. filesize = models.IntegerField(editable=False) # sha1 hash of the data to avoid duplicates. sha1 = models.CharField(max_length=40, db_index=True, unique=True, editable=False) created_at = models.DateTimeField(auto_now_add=True, editable=False) modified_at = models.DateTimeField(auto_now=True, editable=False) # Users responsible for the aforementioned actions. created_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='documents_created') modified_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='documents_modified') objects = DocumentManager() class Meta: ordering = ['id'] verbose_name = 'Document' verbose_name_plural = 'Documents' unique_together = ['document_type', 'name'] def __str__(self): return str(self.id) def verbose_name(self): return "Document of type '%s', name: %s" % (self.document_type, self.name) def format_document_type(self): return self.document_type.name format_document_type.short_description = 'Document type' format_document_type.admin_order_field = 'document_type__name' def format_filesize(self): return filesizeformat(self.filesize) format_filesize.short_description = 'File size' format_filesize.admin_order_field = 'filesize' def save(self, *args, **kwargs): """ Manually trigger the signals as they are for some reason unreliable and for example do not get called when a model is updated. """ signals.validate_document(sender=None, instance=self) signals.set_document_metadata(sender=None, instance=self) super().save(*args, **kwargs) signals.index_document(sender=None, instance=self, created=None)
class Subscription(models.Model): """A Subscription contains a saved query. Cornerwise checks it for updates every few days and sends the user a digest """ # The subscription belongs to a registered user: user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="subscriptions", on_delete=models.CASCADE) active = models.DateTimeField(null=True, help_text=("If the subscription is active, " "the datetime when it was last " "activated")) created = models.DateTimeField(default=timezone.now) updated = models.DateTimeField(default=timezone.now) # Stores the pickle serialization of a dictionary describing the query query = models.BinaryField() center = models.PointField( help_text=("Center point of the query. Along with the radius, " "determines the notification region."), geography=True, null=True) radius = models.FloatField(help_text="Radius in meters", db_index=True, validators=[ MinValueValidator( settings.MIN_ALERT_RADIUS), MaxValueValidator(settings.MAX_ALERT_RADIUS) ], null=True) box = models.PolygonField( help_text=("The notification region. Either this or the center and " "radius should be set."), db_index=True, null=True) address = models.CharField( max_length=64, blank=True, help_text="Optional address for the center point") region_name = models.CharField( help_text="Only subscribe to updates in this region", db_index=True, max_length=128, null=True) site_name = models.CharField( help_text="The site where the user created his/her account", db_index=True, max_length=64, default="somerville.cornerwise.org") # Implementation of text search requires more design work # text_search = models.CharField( # max_length=1000, # help_text="") include_events = models.CharField( max_length=256, default="", blank=True, help_text="Include events for a specified region") last_notified = models.DateTimeField(null=True) objects = SubscriptionQuerySet.as_manager() @property def updates_start_date(self): """Returns the datetime for the start of the query time range. """ now = timezone.now() return max(self.last_notified or self.created or now, self.active or now) def save(self, *args, **kwargs): self.updated = datetime.now() super().save(*args, **kwargs) def clean(self): if bool(self.center) != bool(self.radius): # nxor raise ValidationError("center and radius must be set together", params=["center", "radius"]) if not (self.center or self.box): raise ValidationError("must have either a circle or box set", params=["center", "radius"]) def confirm(self): """Activate this subscription. If multiple subscriptions are disallowed, deactivate the user's currently active subscriptions. """ if self.site_name and not site_config( self.site_name).allow_multiple_subscriptions: # Disable this user's other subscriptions on the site: self.user.subscriptions\ .filter(active__isnull=False, site_name=self.site_name)\ .exclude(pk=self.pk)\ .update(active=None) self.user.profile.activate() self.active = timezone.now() self.save() def activate(self): self.active = timezone.now() def deactivate(self): self.active = None def summarize_updates(self, since=None, until=None): """ since: a datetime :returns: a dictionary describing the changes to the query since the given datetime """ return summarize_subscription_updates(self, since or self.updates_start_date, until) def confirm_url(self, absolute=True): relative = "{base}?token={token}&uid={uid}&sub={sub_id}".format( base=reverse("confirm"), token=self.user.profile.get_or_make_token(), uid=self.user.pk, sub_id=self.pk) return utils.make_absolute_url(relative, self.site_name) if absolute \ else relative @property def query_dict(self): """Returns a dictionary representing a JSON serializable query for this Subscription. """ q = {} if self.box: q["box"] = self.box if self.center: q["center"] = self.center q["r"] = self.radius if self.region_name: q["region_name"] = self.region_name return q def set_validated_query(self, q): """Ensures that the query, a dict, is well-formed and valid. """ if "box" in q: self.box = bounds_from_box(q["box"]) elif "center" in q: if "r" in q: self.center = utils.point_from_str(q["center"]) self.radius = utils.distance_from_str(q["r"]).m else: raise ValidationError(f"Missing query parameter: r") if "region_name" in q: self.region_name = q["region_name"] q = self.validate_site_settings(q) self.query = pickle.dumps(q) def validate_site_settings(self, q): """If the Subscription has an associated site name, perform additional validation of the subscription params according to the specific rules for that site. Called after the properties have been successfully deserialized and set. """ if not self.site_name: return q config = site_config(self.site_name) return config.validate_subscription_query(self, q) @staticmethod def readable_query(query, unit="ft"): # NOTE Not currently used, but may be useful again in the future if "projects" in query: if query["project"] == "all": desc = "Public proposals " else: desc = "Private proposals " else: desc = "All proposals " if "text" in query: desc += "matching \"" + query["text"] + "\" " if "box" in query: box = bounds_from_box(query["box"]) sw, ne = poly_bounds(box) desc += "".join([ "inside the region: ", prettify_point(sw), " and ", prettify_point(ne) ]) elif "center" in query: dist = D(m=query["r"]) return desc @property def frequency_description(self): return "once a week" def area_description(self, dist_units="ft"): if self.box: sw, ne = poly_bounds(self.box) return ("inside the region bounded by " f"{prettify_point(sw)} and {prettify_point(ne)}") if self.center: dist = round(getattr(D(m=self.radius), dist_units)) return "within {dist} {dist_units} of {where}".format( dist=dist, dist_units=dist_units, where=(self.address or prettify_point(self.center))) def readable_description(self, dist_units="ft"): """Returns a brief textual description of the subscription. """ return "projects {area} {region}".format( area=self.area_description(dist_units), region=self.region_name) def overlap(self, subscription): """Returns the overlap of the subscription area of this Subscription with another Subscription as a percentage of the total area of the two subscriptions. If only one of the subscriptions has a shape, returns 0. If neither has a shape, returns None. """ my_shape = self.shape other_shape = subscription.shape if my_shape and other_shape: return 2 * my_shape.intersection(other_shape).area / ( my_shape.area + other_shape.area) elif my_shape or other_shape: return 0 return None def similarity(self, subscription): if self.region_name != subscription.region_name: return 0 # Be sure to add other fields as necessary overlap = self.overlap(subscription) if overlap is not None: return overlap if self.address == subscription.address: return 1 @property def map_url(self): """Creates a link to the main map page with the center of the map set to the center of the subscription. """ center = self.center or self.box.centroid params = urllib.parse.urlencode( { "view": "main", "lat": center.y, "lng": center.x, "zoom": 17, "ref.lat": center.y, "ref.lng": center.x, "ref.r": self.radius, "ref.address": self.address, }, quote_via=urllib.parse.quote) return reverse("front-page") + "#" + params @property def shape(self): if self.box: return self.box else: center = self.center # This is good enough for our purposes here: return center.buffer(self.radius / 111000) def minimap_src(self, circle_color=None): box = self.shape if box: sw, ne = poly_bounds(box) circle = f"{int(self.radius)}" if self.radius else "" if circle_color and self.radius: circle += f",{circle_color}" return settings.MINIMAP_SRC\ .format(swlat=sw[1], swlon=sw[0], nelat=ne[1], nelon=ne[0], circle=circle) else: return None def minimap_src_red(self): return self.minimap_src("red")
class Person(models.Model): gender = models.CharField(max_length=1, choices=GENDER_CH) happy = models.BooleanField(default=True) unhappy = models.BooleanField(default=False) bipolar = models.BooleanField(default=False) name = models.CharField(max_length=30) nickname = models.SlugField(max_length=36) age = models.IntegerField() bio = models.TextField() birthday = models.DateField() birth_time = models.TimeField() appointment = models.DateTimeField() blog = models.URLField() occupation = models.CharField(max_length=10, choices=OCCUPATION_CHOCIES) try: uuid = models.UUIDField(primary_key=False) except AttributeError: # New at Django 1.9 pass try: name_hash = models.BinaryField(max_length=16) except AttributeError: # We can't test the binary field if it is not supported # (django < 1,6) pass try: from django.contrib.postgres.fields import ArrayField acquaintances = ArrayField(models.IntegerField()) except ImportError: # New at Django 1.9 pass try: from django.contrib.postgres.fields import JSONField data = JSONField() except ImportError: # New at Django 1.9 pass try: from django.contrib.postgres.fields import HStoreField hstore_data = HStoreField() except ImportError: # New at Django 1.8 pass # backward compatibility with Django 1.1 try: wanted_games_qtd = models.BigIntegerField() except AttributeError: wanted_games_qtd = models.IntegerField() try: duration_of_sleep = models.DurationField() except AttributeError: pass if MOMMY_GIS: geom = models.GeometryField() point = models.PointField() line_string = models.LineStringField() polygon = models.PolygonField() multi_point = models.MultiPointField() multi_line_string = models.MultiLineStringField() multi_polygon = models.MultiPolygonField() geom_collection = models.GeometryCollectionField()
class Measurements(models.Model): id = models.BigAutoField(primary_key=True) geomcol1 = models.BinaryField(db_column='GeomCol1', blank=True, null=True) # Field name made lowercase. timestamp = models.DateTimeField(blank=True, null=True) lon = models.DecimalField(max_digits=10, decimal_places=5) lat = models.DecimalField(max_digits=10, decimal_places=5) level = models.IntegerField(blank=True, null=True) speed = models.FloatField(blank=True, null=True) operatorname = models.CharField(max_length=50, blank=True, null=True) mcc = models.CharField(max_length=3, blank=True, null=True) mnc = models.CharField(max_length=3, blank=True, null=True) node = models.CharField(max_length=11, blank=True, null=True) cellid = models.CharField(max_length=11, blank=True, null=True) lac = models.CharField(max_length=11, blank=True, null=True) network_type = models.CharField(max_length=2, blank=True, null=True) qual = models.IntegerField(blank=True, null=True) snr = models.IntegerField(blank=True, null=True) cqi = models.IntegerField(blank=True, null=True) lterssi = models.IntegerField(blank=True, null=True) appversioncode = models.IntegerField(blank=True, null=True) psc = models.IntegerField(blank=True, null=True) dl_bitrate = models.IntegerField(blank=True, null=True) ul_bitrate = models.IntegerField(blank=True, null=True) nlac1 = models.IntegerField(blank=True, null=True) ncellid1 = models.IntegerField(blank=True, null=True) nrxlev1 = models.IntegerField(blank=True, null=True) nlac2 = models.IntegerField(blank=True, null=True) ncellid2 = models.IntegerField(blank=True, null=True) nrxlev2 = models.IntegerField(blank=True, null=True) nlac3 = models.IntegerField(blank=True, null=True) ncellid3 = models.IntegerField(blank=True, null=True) nrxlev3 = models.IntegerField(blank=True, null=True) nlac4 = models.IntegerField(blank=True, null=True) ncellid4 = models.IntegerField(blank=True, null=True) nrxlev4 = models.IntegerField(blank=True, null=True) nlac5 = models.IntegerField(blank=True, null=True) ncellid5 = models.IntegerField(blank=True, null=True) nrxlev5 = models.IntegerField(blank=True, null=True) nlac6 = models.IntegerField(blank=True, null=True) ncellid6 = models.IntegerField(blank=True, null=True) nrxlev6 = models.IntegerField(blank=True, null=True) ctime = models.DateTimeField(blank=True, null=True) event = models.CharField(max_length=20, blank=True, null=True) accuracy = models.IntegerField(blank=True, null=True) locationsource = models.CharField(max_length=2, blank=True, null=True) altitude = models.IntegerField(blank=True, null=True) conntype = models.CharField(max_length=5, blank=True, null=True) conninfo = models.CharField(max_length=25, blank=True, null=True) avgping = models.IntegerField(blank=True, null=True) minping = models.IntegerField(blank=True, null=True) maxping = models.IntegerField(blank=True, null=True) stdevping = models.IntegerField(blank=True, null=True) pingloss = models.IntegerField(blank=True, null=True) testdlbitrate = models.IntegerField(blank=True, null=True) testulbitrate = models.IntegerField(blank=True, null=True) geomcol2 = models.GeometryField(db_column='GeomCol2', srid=0, blank=True, null=True) # Field name made lowercase. devicemanufacturer = models.CharField( db_column='DeviceManufacturer', max_length=30, blank=True, null=True) # Field name made lowercase. devicemodel = models.CharField(db_column='DeviceModel', max_length=30, blank=True, null=True) # Field name made lowercase. devicename = models.CharField(db_column='DeviceName', max_length=30, blank=True, null=True) # Field name made lowercase. versionname = models.CharField(db_column='VersionName', max_length=30, blank=True, null=True) # Field name made lowercase. brand = models.CharField(db_column='Brand', max_length=30, blank=True, null=True) # Field name made lowercase. androidversion = models.CharField(db_column='AndroidVersion', max_length=30, blank=True, null=True) # Field name made lowercase. servingcelltime = models.IntegerField( db_column='ServingCellTime', blank=True, null=True) # Field name made lowercase. os = models.CharField(max_length=30, blank=True, null=True) os_id = models.CharField(max_length=128, blank=True, null=True) camp = models.ForeignKey(V2OfCampaigns, on_delete=models.CASCADE, blank=True, null=True) ssid = models.CharField(max_length=128, blank=True, null=True) class Meta: managed = False db_table = 'Measurements' verbose_name_plural = format_lazy('{}', db_table)
class Subscription(models.Model): # The subscription belong to a registered user: user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, related_name="subscriptions") # Stores the pickle serialization of a dictionary describing the query query = models.BinaryField() last_notified = models.DateTimeField(auto_now=True) @property def query_dict(self): return pickle.loads(self.query) @query_dict.setter def query_dict(self, new_dict): self.query = pickle.dumps(new_dict) def set_validated_query(self, q): self.query_dict = self.validate_query(q) valid_keys = { "projects": lambda v: v.lower() in {"all", "null"}, "text": lambda _: True, "box": lambda v: (len(v.split(",")) == 4 and all( re.match(r"-?\d+\.\d+", c) for c in v.split(","))) } @classmethod def validate_query(kls, q): validated = {} for k, v in q.items(): if k not in kls.valid_keys: continue if kls.valid_keys[k](v): validated[k] = v return validated @staticmethod def readable_query(query): if "project" in query: if query["project"] == "all": desc = "Public proposals " else: desc = "Private proposals " else: desc = "All proposals " if "text" in query: desc += "matching \"" + query["text"] + "\" " if "box" in query: coords = [float(s) for s in query["box"].split(",")] desc += "".join([ "inside the region: ", prettify_lat(coords[0]), ", ", prettify_long(coords[1]), " and ", prettify_lat(coords[2]), ", ", prettify_long(coords[3]) ]) return desc def readable_description(self): return self.readable_query(self.query_dict)
class User(models.Model): user_id = models.IntegerField(primary_key=True) version = models.IntegerField() name = models.CharField(max_length=100) email = models.CharField(max_length=255, unique=True) password = models.BinaryField() address = models.CharField(max_length=200, blank=True) city = models.CharField(max_length=50, blank=True) province = models.CharField(max_length=100, blank=True) country = models.CharField(max_length=100, blank=True) postal_code = models.CharField(max_length=15, blank=True) institution = models.CharField(max_length=300, blank=True) reference_email = models.CharField(max_length=255, blank=True) confirmation_code = models.CharField(max_length=32, blank=True) enabled = models.CharField(max_length=1) role_id = models.SmallIntegerField(null=True, blank=True) contributor_code = models.CharField(max_length=32, blank=True) contributor_enabled = models.CharField(max_length=1, blank=True) professional_url = models.CharField(max_length=255, blank=True) research_interests = models.CharField(max_length=1024, blank=True) request_contributor = models.CharField(max_length=1, blank=True) django_user = OneToOneField(AuthUser, blank=True, null=True) class Meta: # managed = False db_table = 'users' get_latest_by = "user_id" def save(self, **kwargs): if self.pk is None: self.pk = utils.get_next_id(User) self.confirmation_code = generate_confirmation_code(self.name) super(User, self).save(**kwargs) def __unicode__(self): return str(self.user_id) + ' ' + self.name + ' ' + str(self.django_user) def auto_verify(self, confirmation_code): """Called to perform email verification. Checks confirmation_code and adds the user to public groups so they may read public data. Raises a ValueError if confirmation_code doesn't match the stored code, or if there is no corresponding Django user. Pass confirmation_code=None to bypass this check. """ if confirmation_code is None or confirmation_code == \ self.confirmation_code: if self.django_user is None: raise ValueError( "This user doesn't exist in django.contrib.auth yet.") public_groups = get_public_groups() for group in public_groups.select_for_update(): if group not in self.django_user.groups.all(): self.django_user.groups.add(group) self.enabled = 'Y' self.save() return True else: raise ValueError("Confirmation code incorrect.") def manual_verify(self): """Called to request full verification. Adds the user to a personal group so they may upload and share data. """ if self.django_user is None: raise ValueError( "This user doesn't exist in django.contrib.auth yet.") user_groups = Group.objects.filter(groupextra__group_type='u_uid', groupextra__owner=self.django_user) user_groups = user_groups.select_for_update() if user_groups.count() != 1: """ There isn't, so get rid of whichever do exist and create from scratch""" user_groups.delete() user_group_name = USER_GROUP_DEFAULT_PREFIX + \ self.django_user.username user_group = Group.objects.create(name=user_group_name) user_group.user_set.add(self.django_user) GroupExtra(group=user_group, group_type='u_uid', owner=self.django_user).save() self.contributor_enabled = 'Y' self.save() return True