Files
zulip/analytics/models.py
Rishi Gupta 82b814a1cd analytics: Simplify frequency and measurement interval options.
Change the CountStat object to take an is_gauge variable instead of a
smallest_interval variable. Previously, (smallest_interval, frequency)
could be any of (hour, hour), (hour, day), (hour, gauge), (day, hour),
(day, day), or (day, gauge).
The current change is equivalent to excluding (hour, day) and (day, hour)
from the list above.

This change, along with other recent changes, allows us to simplify how we
handle time intervals. This commit also removes the TimeInterval object.
2016-10-14 10:18:37 -07:00

153 lines
4.5 KiB
Python

from django.db import models
from django.utils import timezone
from zerver.models import Realm, UserProfile, Stream, Recipient
from zerver.lib.str_utils import ModelReprMixin
from zerver.lib.timestamp import datetime_to_UTC, floor_to_day
import datetime
from six import text_type
from typing import Optional, Tuple, Union, Dict, Any
class FillState(ModelReprMixin, models.Model):
property = models.CharField(max_length=40, unique=True) # type: text_type
end_time = models.DateTimeField() # type: datetime.datetime
# Valid states are {DONE, STARTED}
DONE = 1
STARTED = 2
state = models.PositiveSmallIntegerField() # type: int
last_modified = models.DateTimeField(auto_now=True) # type: datetime.datetime
def __unicode__(self):
# type: () -> text_type
return u"<FillState: %s %s %s>" % (self.property, self.end_time, self.state)
def get_fill_state(property):
# type: (text_type) -> Optional[Dict[str, Any]]
try:
return FillState.objects.filter(property = property).values('end_time', 'state')[0]
except IndexError:
return None
# The earliest/starting end_time in FillState
# We assume there is at least one realm
def installation_epoch():
# type: () -> datetime.datetime
earliest_realm_creation = Realm.objects.aggregate(models.Min('date_created'))['date_created__min']
return floor_to_day(datetime_to_UTC(earliest_realm_creation))
# would only ever make entries here by hand
class Anomaly(ModelReprMixin, models.Model):
info = models.CharField(max_length=1000) # type: text_type
def __unicode__(self):
# type: () -> text_type
return u"<Anomaly: %s... %s>" % (self.info, self.id)
class BaseCount(ModelReprMixin, models.Model):
# Note: When inheriting from BaseCount, you may want to rearrange
# the order of the columns in the migration to make sure they
# match how you'd like the table to be arranged.
property = models.CharField(max_length=40) # type: text_type
end_time = models.DateTimeField() # type: datetime.datetime
interval = models.CharField(max_length=20) # type: text_type
value = models.BigIntegerField() # type: int
anomaly = models.ForeignKey(Anomaly, null=True) # type: Optional[Anomaly]
class Meta(object):
abstract = True
@staticmethod
def extended_id():
# type: () -> Tuple[str, ...]
raise NotImplementedError
@staticmethod
def key_model():
# type: () -> models.Model
raise NotImplementedError
class InstallationCount(BaseCount):
class Meta(object):
unique_together = ("property", "end_time", "interval")
@staticmethod
def extended_id():
# type: () -> Tuple[str, ...]
return ()
@staticmethod
def key_model():
# type: () -> models.Model
return None
def __unicode__(self):
# type: () -> text_type
return u"<InstallationCount: %s %s>" % (self.property, self.value)
class RealmCount(BaseCount):
realm = models.ForeignKey(Realm)
class Meta(object):
unique_together = ("realm", "property", "end_time", "interval")
@staticmethod
def extended_id():
# type: () -> Tuple[str, ...]
return ('realm_id',)
@staticmethod
def key_model():
# type: () -> models.Model
return Realm
def __unicode__(self):
# type: () -> text_type
return u"<RealmCount: %s %s %s>" % (self.realm, self.property, self.value)
class UserCount(BaseCount):
user = models.ForeignKey(UserProfile)
realm = models.ForeignKey(Realm)
class Meta(object):
unique_together = ("user", "property", "end_time", "interval")
@staticmethod
def extended_id():
# type: () -> Tuple[str, ...]
return ('user_id', 'realm_id')
@staticmethod
def key_model():
# type: () -> models.Model
return UserProfile
def __unicode__(self):
# type: () -> text_type
return u"<UserCount: %s %s %s>" % (self.user, self.property, self.value)
class StreamCount(BaseCount):
stream = models.ForeignKey(Stream)
realm = models.ForeignKey(Realm)
class Meta(object):
unique_together = ("stream", "property", "end_time", "interval")
@staticmethod
def extended_id():
# type: () -> Tuple[str, ...]
return ('stream_id', 'realm_id')
@staticmethod
def key_model():
# type: () -> models.Model
return Stream
def __unicode__(self):
# type: () -> text_type
return u"<StreamCount: %s %s %s %s>" % (self.stream, self.property, self.value, self.id)