From 9736c15faa0aeb2a4a9e985c116aa027b09e9157 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Wed, 28 May 2014 13:51:42 -0700 Subject: [PATCH] Subjects get a key name to enforce uniqueness. --- lib/models.py | 33 ++++++++++++++++++++------------- static/test.js | 4 ++-- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/lib/models.py b/lib/models.py index 4fa3ffb..4b6056f 100644 --- a/lib/models.py +++ b/lib/models.py @@ -14,7 +14,9 @@ # limitations under the License. import json +import hashlib import logging +import struct from google.appengine.api import channel from google.appengine.ext import db @@ -110,32 +112,37 @@ class Subject(db.Model): next_message_id = db.IntegerProperty(required=True, default=1) + @classmethod + def _UpdateHashWithString(cls, hashobj, string): + string = string.encode('utf8') + hashobj.update(struct.pack('!i', len(string))) + hashobj.update(string) + + @classmethod + def _KeyName(cls, subject): + hashobj = hashlib.sha256() + cls._UpdateHashWithString(hashobj, subject['name']) + cls._UpdateHashWithString(hashobj, subject.get('readable_only_by', '')) + cls._UpdateHashWithString(hashobj, subject.get('writable_only_by', '')) + return hashobj.hexdigest() + @classmethod def FindOrCreate(cls, subject): if 'readable_only_by' in subject: - readable_only_by = Profile.get(subject['readable_only_by']) + readable_only_by = db.Key(subject['readable_only_by']) else: readable_only_by = None if 'writable_only_by' in subject: - writable_only_by = Profile.get(subject['writable_only_by']) + writable_only_by = db.Key(subject['writable_only_by']) else: writable_only_by = None - subjects = ( - cls.all() - .filter('name =', subject['name']) - .filter('readable_only_by =', readable_only_by) - .filter('writable_only_by =', writable_only_by) - .fetch(1)) - if subjects: - return subjects[0] - subject = cls( + return cls.get_or_insert( + cls._KeyName(subject), name=subject['name'], readable_only_by=readable_only_by, writable_only_by=writable_only_by) - subject.put() - return subject @db.transactional() def GetRecentMessages(self, num_messages): diff --git a/static/test.js b/static/test.js index 3be125b..a070c52 100644 --- a/static/test.js +++ b/static/test.js @@ -479,7 +479,7 @@ asyncTest('Repin', function() { }); asyncTest('Duplicate subject', function() { - expect(8); + expect(4); var subject = randstring(); var message1 = randstring(); @@ -498,7 +498,7 @@ asyncTest('Duplicate subject', function() { if (e['message'] == message1) { equal(message1, e['message'], 'message1 matches'); } else { - equal(message2, e['message'], 'message1 matches'); + equal(message2, e['message'], 'message2 matches'); } if (++messages == 2) { cosmo.shutdown();