Files
website-v2/slack/models.py

79 lines
2.3 KiB
Python

import datetime
from django.db import models
from django.db.models.expressions import Func
"""
`ts` fields from slack are actually IDs that can be interpreted into
timestamps. We store them in a string as we get them from slack instead
of a DateTimeField to be able to pass them back exactly to slack without
precision or something causing round-tripping errors.
"""
def parse_ts(ts):
seconds = float(ts)
return datetime.datetime.fromtimestamp(seconds, tz=datetime.timezone.utc)
class ToTimestamp(Func):
"""
Implements the postgres to_timestamp(double precision) function.
https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-TABLE
"""
function = "to_timestamp"
output_field = models.DateTimeField()
class SlackUser(models.Model):
id = models.CharField(max_length=16, primary_key=True)
name = models.TextField()
real_name = models.TextField()
email = models.TextField()
image_48 = models.URLField()
class Channel(models.Model):
id = models.CharField(max_length=16, primary_key=True)
name = models.TextField()
topic = models.TextField()
purpose = models.TextField()
# We only need to check for new messages newer than this.
last_update_ts = models.CharField(max_length=32, null=True)
# use as a starting point on fresh data load
channel_created_ts = models.CharField(max_length=32, null=True)
class SeenMessage(models.Model):
"""
DEBUG ONLY: Store all seen messages to double-check we don't see them
twice.
Invariant:
SeenMessage.objects.count() == \
SlackActivityBucket.objects.aggregate(sum=Sum('count'))['sum']
"""
channel = models.ForeignKey(Channel, on_delete=models.CASCADE)
ts = models.CharField(max_length=32)
message_time = models.DateTimeField(blank=True, null=True)
db_created_at = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(SlackUser, null=True, blank=True, on_delete=models.CASCADE)
class SlackActivityBucket(models.Model):
"""
Message count per user per channel per UTC day.
"""
day = models.DateField()
user = models.ForeignKey(SlackUser, on_delete=models.CASCADE)
channel = models.ForeignKey(Channel, on_delete=models.CASCADE)
count = models.PositiveIntegerField()
class Meta:
unique_together = [("channel", "day", "user")]