Add a key field to messages and allow lookup of most recent message by key.

This commit is contained in:
Ian Gulliver
2014-05-11 15:43:45 +03:00
parent b7bd396c9b
commit 0575b8918d
4 changed files with 85 additions and 43 deletions

11
api.py
View File

@@ -50,8 +50,9 @@ def CreateChannel(google_user, client, args):
def SendMessage(google_user, client, args): def SendMessage(google_user, client, args):
subject = args['subject'] subject = args['subject']
message = args['message'] message = args['message']
key = args.get('key', None)
models.Subject.FindOrCreate(subject).SendMessage(message, client.parent_key()) models.Subject.FindOrCreate(subject).SendMessage(message, client.parent_key(), key)
return {} return {}
@@ -90,10 +91,16 @@ def SetValue(google_user, client, args):
def Subscribe(google_user, client, args): def Subscribe(google_user, client, args):
subject = models.Subject.FindOrCreate(args['subject']) subject = models.Subject.FindOrCreate(args['subject'])
messages = args.get('messages', 0) messages = args.get('messages', 0)
keys = args.get('keys', [])
return { ret = {
'events': models.Subscription.FindOrCreate(subject, client, messages), 'events': models.Subscription.FindOrCreate(subject, client, messages),
} }
for key in keys:
message = models.Subject.GetKey(key)
if message:
ret['events'].append(message)
return ret
def Unsubscribe(google_user, client, args): def Unsubscribe(google_user, client, args):

View File

@@ -27,6 +27,7 @@ import utils
# ↳ StateEntry # ↳ StateEntry
# #
# Subject # Subject
# ↳ Message
# ↳ Subscription (⤴︎ Client) # ↳ Subscription (⤴︎ Client)
@@ -132,7 +133,7 @@ class Subject(db.Model):
return cls(key_name=name).put() return cls(key_name=name).put()
@db.transactional() @db.transactional()
def RecentMessages(self, num_messages): def GetRecentMessages(self, num_messages):
query = ( query = (
Message.all() Message.all()
.ancestor(self) .ancestor(self)
@@ -142,8 +143,20 @@ class Subject(db.Model):
return reversed(query.fetch(limit=num_messages)) return reversed(query.fetch(limit=num_messages))
@db.transactional() @db.transactional()
def SendMessage(self, message, sender): def GetKey(self, key):
obj = Message(parent=self, message=message, sender=sender) messages = (
Message.all()
.ancestor(self)
.filter('key_ =', key)
.order('-created')
.fetch(1))
if messages:
return messages[0]
return None
@db.transactional()
def SendMessage(self, message, sender, key=None):
obj = Message(parent=self, message=message, sender=sender, key_=key)
obj.put() obj.put()
event = obj.ToEvent() event = obj.ToEvent()
@@ -169,7 +182,7 @@ class Subscription(db.Model):
cls(parent=subject, client=client).put() cls(parent=subject, client=client).put()
if messages == 0: if messages == 0:
return [] return []
return [m.ToEvent() for m in subject.RecentMessages(messages)] return [m.ToEvent() for m in subject.GetRecentMessages(messages)]
@classmethod @classmethod
@db.transactional() @db.transactional()
@@ -188,9 +201,11 @@ class Message(db.Model):
created = db.DateTimeProperty(required=True, auto_now_add=True) created = db.DateTimeProperty(required=True, auto_now_add=True)
message = db.TextProperty(required=True) message = db.TextProperty(required=True)
sender = db.ReferenceProperty(required=True, reference_class=Profile) sender = db.ReferenceProperty(required=True, reference_class=Profile)
# key and key_name are reserved
key_ = db.StringProperty()
def ToEvent(self): def ToEvent(self):
return { ret = {
'event_type': 'message', 'event_type': 'message',
'id': self.key().id(), 'id': self.key().id(),
'sender': str(Message.sender.get_value_for_datastore(self)), 'sender': str(Message.sender.get_value_for_datastore(self)),
@@ -198,3 +213,6 @@ class Message(db.Model):
'created': self.created, 'created': self.created,
'message': self.message, 'message': self.message,
} }
if self.key_:
ret['key'] = self.key_
return ret

View File

@@ -88,11 +88,15 @@ cosmopolite.Client.prototype.unsubscribe = function(subject) {
}); });
}; };
cosmopolite.Client.prototype.sendMessage = function(subject, message) { cosmopolite.Client.prototype.sendMessage = function(subject, message, key) {
this.sendRPC_('sendMessage', { args = {
'subject': subject, 'subject': subject,
'message': message, 'message': message,
}); };
if (key) {
args['key'] = key;
}
this.sendRPC_('sendMessage', args);
}; };
cosmopolite.Client.prototype.getMessages = function(subject) { cosmopolite.Client.prototype.getMessages = function(subject) {

View File

@@ -10,7 +10,6 @@ a {
<body> <body>
<div>Google user: <span id="google_user"></span></div> <div>Google user: <span id="google_user"></span></div>
<div>
<div> <div>
Key: Key:
<select id="keys"></select> <select id="keys"></select>
@@ -27,23 +26,34 @@ a {
<div> <div>
<textarea id="value" rows="10" cols="40"></textarea> <textarea id="value" rows="10" cols="40"></textarea>
</div> </div>
</div>
<hr> <hr>
<div> <div>
<div> Subject: <input type="text" id="subject">
Subject:
<input type="text" id="subject">
<input type="button" id="subscribe" value="Subscribe"> <input type="button" id="subscribe" value="Subscribe">
</div> </div>
<div> <div>
<select id="subscriptions"></select> <select id="subscriptions"></select>
<input type="button" id="unsubscribe" value="Unsubscribe"> <input type="button" id="unsubscribe" value="Unsubscribe">
</div> </div>
<hr>
<div>
Message: <input type="text" id="message">
</div>
<div>
Key: <input type="text" id="key">
</div>
<div> <div>
<input type="text" id="message">
<input type="button" id="send" value="Send"> <input type="button" id="send" value="Send">
</div> </div>
<hr>
<div id="messages"></div> <div id="messages"></div>
<script> <script>
var keys = document.getElementById('keys'); var keys = document.getElementById('keys');
var value = document.getElementById('value'); var value = document.getElementById('value');
@@ -52,8 +62,11 @@ var is_public = document.getElementById('public');
var subject = document.getElementById('subject'); var subject = document.getElementById('subject');
var subscriptions = document.getElementById('subscriptions'); var subscriptions = document.getElementById('subscriptions');
var messages = document.getElementById('messages');
var message = document.getElementById('message'); var message = document.getElementById('message');
var key = document.getElementById('key');
var messages = document.getElementById('messages');
var selectKey = function(new_key) { var selectKey = function(new_key) {
keys.value = new_key; keys.value = new_key;
@@ -150,7 +163,7 @@ window.addEventListener('load', function() {
}); });
document.getElementById('send').addEventListener('click', function() { document.getElementById('send').addEventListener('click', function() {
debug.sendMessage(subscriptions.value, message.value); debug.sendMessage(subscriptions.value, message.value, key.value);
}); });
document.getElementById('subscriptions').addEventListener('change', function() { document.getElementById('subscriptions').addEventListener('change', function() {