mirror of
https://github.com/zulip/zulip.git
synced 2025-11-06 06:53:25 +00:00
Note that realms aren't actually used for anything, aren't prompted for, etc, so this is mostly just a schema change and the refactoring needed to allow setting the realm in the future. (imported from commit b8b483dcc9601b288702284879e9c99707a50a5c)
168 lines
6.2 KiB
Python
168 lines
6.2 KiB
Python
from django.db import models
|
|
from django.contrib.auth.models import User
|
|
from django.db.models import Q
|
|
from django.db.models.signals import post_save
|
|
import hashlib
|
|
|
|
def get_display_recipient(recipient):
|
|
"""
|
|
recipient: an instance of Recipient.
|
|
|
|
returns: an appropriate string describing the recipient (the class
|
|
name, for a class, or the username, for a user).
|
|
"""
|
|
if recipient.type == "class":
|
|
zephyr_class = ZephyrClass.objects.get(pk=recipient.type_id)
|
|
return zephyr_class.name
|
|
elif recipient.type == "huddle":
|
|
user_list = [UserProfile.objects.get(user=s.userprofile_id) for s in
|
|
Subscription.objects.filter(recipient_id=recipient.id)]
|
|
return [{'name': user.user.username} for user in user_list]
|
|
else:
|
|
user = User.objects.get(pk=recipient.type_id)
|
|
return user.username
|
|
|
|
callback_table = {}
|
|
|
|
class Realm(models.Model):
|
|
domain = models.CharField(max_length=40)
|
|
|
|
def __repr__(self):
|
|
return "<Realm: %s %s>" % (self.domain, self.id)
|
|
def __str__(self):
|
|
return self.__repr__()
|
|
|
|
class UserProfile(models.Model):
|
|
user = models.OneToOneField(User)
|
|
pointer = models.IntegerField()
|
|
realm = models.ForeignKey(Realm)
|
|
|
|
# The user receives this message
|
|
def receive(self, message):
|
|
global callback_table
|
|
|
|
# Should also store in permanent database the receipt
|
|
for cb in callback_table.get(self.user.id, []):
|
|
cb([message])
|
|
|
|
callback_table[self.user.id] = []
|
|
|
|
def add_callback(self, cb, last_received):
|
|
global callback_table
|
|
|
|
new_zephyrs = filter_by_subscriptions(
|
|
Zephyr.objects.filter(id__gt=last_received), self.user)
|
|
|
|
if new_zephyrs:
|
|
return cb(new_zephyrs)
|
|
callback_table.setdefault(self.user.id, []).append(cb)
|
|
|
|
def __repr__(self):
|
|
return "<UserProfile: %s %s>" % (self.user.username, self.realm)
|
|
def __str__(self):
|
|
return self.__repr__()
|
|
|
|
def create_user_profile(user, realm):
|
|
"""When creating a new user, make a profile for him or her."""
|
|
if not UserProfile.objects.filter(user=user):
|
|
profile = UserProfile(user=user, pointer=-1, realm_id=realm.id)
|
|
profile.save()
|
|
# Auto-sub to the ability to receive personals.
|
|
recipient = Recipient(type_id=profile.pk, type="personal")
|
|
recipient.save()
|
|
Subscription(userprofile_id=profile, recipient_id=recipient).save()
|
|
|
|
class ZephyrClass(models.Model):
|
|
name = models.CharField(max_length=30)
|
|
|
|
def __repr__(self):
|
|
return "<ZephyrClass: %s>" % (self.name,)
|
|
|
|
class Recipient(models.Model):
|
|
type_id = models.IntegerField()
|
|
type = models.CharField(max_length=30)
|
|
# Valid types are {personal, class, huddle}
|
|
|
|
def __repr__(self):
|
|
display_recipient = get_display_recipient(self)
|
|
return "<Recipient: %s (%d, %s)>" % (display_recipient, self.type_id, self.type)
|
|
|
|
class Zephyr(models.Model):
|
|
sender = models.ForeignKey(UserProfile)
|
|
recipient = models.ForeignKey(Recipient)
|
|
instance = models.CharField(max_length=30)
|
|
content = models.CharField(max_length=200)
|
|
pub_date = models.DateTimeField('date published')
|
|
|
|
def __repr__(self):
|
|
display_recipient = get_display_recipient(self.recipient)
|
|
return "<Zephyr: %s / %s / %r>" % (display_recipient, self.instance, self.sender)
|
|
|
|
def to_dict(self):
|
|
return {'id' : self.id,
|
|
'sender' : self.sender.user.username,
|
|
'type' : self.recipient.type,
|
|
'display_recipient': get_display_recipient(self.recipient),
|
|
'instance' : self.instance,
|
|
'content' : self.content }
|
|
|
|
def send_zephyr(**kwargs):
|
|
zephyr = kwargs["instance"]
|
|
if zephyr.recipient.type == "personal":
|
|
recipients = UserProfile.objects.filter(Q(user=zephyr.recipient.type_id) | Q(user=zephyr.sender))
|
|
# For personals, you send out either 1 or 2 copies of the zephyr, for
|
|
# personals to yourself or to someone else, respectively.
|
|
assert((len(recipients) == 1) or (len(recipients) == 2))
|
|
elif zephyr.recipient.type == "class" or zephyr.recipient.type == "huddle":
|
|
recipients = [UserProfile.objects.get(user=s.userprofile_id) for
|
|
s in Subscription.objects.filter(recipient_id=zephyr.recipient, active=True)]
|
|
else:
|
|
raise
|
|
for recipient in recipients:
|
|
recipient.receive(zephyr)
|
|
|
|
post_save.connect(send_zephyr, sender=Zephyr)
|
|
|
|
class Subscription(models.Model):
|
|
userprofile_id = models.ForeignKey(UserProfile)
|
|
recipient_id = models.ForeignKey(Recipient)
|
|
active = models.BooleanField(default=True)
|
|
|
|
def __repr__(self):
|
|
return "<Subscription: %r -> %r>" % (self.userprofile_id, self.recipient_id)
|
|
|
|
class Huddle(models.Model):
|
|
huddle_hash = models.CharField(max_length=40)
|
|
|
|
def get_huddle(id_list):
|
|
id_list = sorted(set(id_list))
|
|
hash_key = ",".join(str(x) for x in id_list)
|
|
huddle_hash = hashlib.sha1(hash_key).hexdigest()
|
|
if Huddle.objects.filter(huddle_hash=huddle_hash):
|
|
return Huddle.objects.get(huddle_hash=huddle_hash)
|
|
else:
|
|
# since we don't have one, make a new huddle
|
|
huddle = Huddle(huddle_hash = huddle_hash)
|
|
huddle.save()
|
|
recipient = Recipient(type_id=huddle.pk, type="huddle")
|
|
recipient.save()
|
|
|
|
# Add subscriptions
|
|
for uid in id_list:
|
|
s = Subscription(recipient_id = recipient,
|
|
userprofile_id = UserProfile.objects.get(id=uid))
|
|
s.save()
|
|
return huddle
|
|
|
|
def filter_by_subscriptions(zephyrs, user):
|
|
userprofile = UserProfile.objects.get(user=user)
|
|
subscribed_zephyrs = []
|
|
subscriptions = [sub.recipient_id for sub in Subscription.objects.filter(userprofile_id=userprofile, active=True)]
|
|
for zephyr in zephyrs:
|
|
# If you are subscribed to the personal or class, or if you sent the personal, you can see the zephyr.
|
|
if (zephyr.recipient in subscriptions) or \
|
|
(zephyr.recipient.type == "personal" and zephyr.sender == userprofile):
|
|
subscribed_zephyrs.append(zephyr)
|
|
|
|
return subscribed_zephyrs
|