class CeleryTask(TypedModel): STATUS = Choices( (0, 'started', _('started')), (1, 'retried', _('retried')), (2, 'failed', _('failed')), (3, 'succeeded', _('succeeded')), ) uuid = models.UUIDField(db_index=True, unique=True) name = models.TextField(blank=True, db_index=True) args = models.TextField(blank=True) kwargs = models.TextField(blank=True) timestamp = models.DateTimeField(auto_now_add=True, db_index=True) started_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='started_by', null=True) # TODO rename to 'source' provider = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='provider', null=True) status = models.IntegerField(choices=STATUS) objects = FuzzyCountManager() class Meta: ordering = ('-timestamp', ) index_together = ('type', 'name', 'app_label', 'timestamp')
class ExtraData(models.Model, metaclass=ShareObjectMeta): data = fields.DateTimeAwareJSONField(default=dict) objects = FuzzyCountManager() versions = VersionManager() class Meta: abstract = False
class ShareObject(models.Model, metaclass=ShareObjectMeta): id = models.AutoField(primary_key=True) objects = FuzzyCountManager() versions = VersionManager() changes = GenericRelation('Change', related_query_name='share_objects', content_type_field='target_type', object_id_field='target_id') class Meta: abstract = True
class CeleryTask(TypedModel): STATUS = Choices( (0, 'started', _('started')), (1, 'retried', _('retried')), (2, 'failed', _('failed')), (3, 'succeeded', _('succeeded')), ) uuid = models.UUIDField(db_index=True, unique=True) name = models.TextField(blank=True, db_index=True) args = models.TextField(blank=True) kwargs = models.TextField(blank=True) timestamp = models.DateTimeField(auto_now_add=True, db_index=True) status = models.IntegerField(choices=STATUS) objects = FuzzyCountManager() class Meta: ordering = ('-timestamp', ) index_together = ('type', 'name', 'app_label', 'timestamp')
class Encounter(ValueModel): url_id = models.TextField(max_length=255, editable=False, unique=True, default=_generate_url_id, verbose_name="URL ID") started_at = models.IntegerField(db_index=True) duration = models.FloatField() success = models.BooleanField() filename = models.CharField(max_length=255) uploaded_at = models.IntegerField(db_index=True) uploaded_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='uploaded_encounters') area = models.ForeignKey(Area, on_delete=models.PROTECT, related_name='encounters') era = models.ForeignKey(Era, on_delete=models.PROTECT, related_name='encounters') category = models.ForeignKey(Category, on_delete=models.SET_NULL, related_name='encounters', null=True, blank=True) accounts = models.ManyToManyField(Account, through='Participation', related_name='encounters') # hack to try to ensure uniqueness account_hash = models.CharField(max_length=32, editable=False) started_at_full = models.IntegerField(editable=False) started_at_half = models.IntegerField(editable=False) # Google Drive gdrive_id = models.CharField(max_length=255, editable=False, null=True, blank=True) gdrive_url = models.CharField(max_length=255, editable=False, null=True, blank=True) tags = TaggableManager(blank=True) has_evtc = models.BooleanField(default=True, editable=False) objects = FuzzyCountManager() def __str__(self): if self.uploaded_by: uploader = self.uploaded_by.username else: uploader = 'Unknown' return '%s (%s, %s, #%s)' % (self.area.name, self.filename, uploader, self.id) # Returns timestamp of closest non-future raid reset (Monday 08:30 UTC) @staticmethod def week_for(started_at): encounter_dt = datetime.utcfromtimestamp(started_at).replace(tzinfo=pytz.UTC) reset_dt = (encounter_dt - timedelta(days=encounter_dt.weekday())).replace(hour=7, minute=30, second=0, microsecond=0) if reset_dt > encounter_dt: reset_dt -= timedelta(weeks=1) return int(reset_dt.timestamp()) def week(self): return Encounter.week_for(self.started_at) def save(self, *args, **kwargs): self.started_at_full, self.started_at_half = Encounter.calculate_start_guards(self.started_at) super(Encounter, self).save(*args, **kwargs) def diskname(self): if not self.uploaded_by: return None if hasattr(settings, 'UPLOAD_DIR'): upload_dir = settings.UPLOAD_DIR else: upload_dir = 'uploads' return path_join(upload_dir, 'encounters', self.uploaded_by.username, self.filename) def update_has_evtc(self): self.has_evtc = os.path.isfile(self.diskname()) self.save() @property def tagstring(self): return ','.join(self.tags.names()) @tagstring.setter def tagstring(self, value): self.tags.set(*value.split(',')) @staticmethod def calculate_account_hash(account_names): conc = ':'.join(sorted(account_names)) hash_object = md5(conc.encode()) return hash_object.hexdigest() @staticmethod def calculate_start_guards(started_at): started_at_full = round(started_at / START_RESOLUTION) * START_RESOLUTION started_at_half = round((started_at + START_RESOLUTION / 2) / START_RESOLUTION) * START_RESOLUTION return (started_at_full, started_at_half) class Meta: index_together = ('area', 'started_at') ordering = ('started_at',) unique_together = ( ('area', 'account_hash', 'started_at_full'), ('area', 'account_hash', 'started_at_half'), )