[manual] Use ujson instead of simplejson.

This saves something like 15ms on our 1000 message get_old_messages
queries, and will save even more when we start sending JSON dumps into
our memcached system.

We need to install python-ujson on servers and dev instances before
pushing this to prod.

(imported from commit 373690b7c056d00d2299a7588a33f025104bfbca)
This commit is contained in:
Tim Abbott
2013-06-18 17:55:55 -04:00
parent 678dd502ef
commit 222ef672b5
25 changed files with 120 additions and 119 deletions

View File

@@ -8,7 +8,7 @@ class humbug::app_frontend {
"python-pygments", "python-flup", "ipython", "python-psycopg2", "python-pygments", "python-flup", "ipython", "python-psycopg2",
"yui-compressor", "python-django-auth-openid", "yui-compressor", "python-django-auth-openid",
"python-django-statsd-mozilla", "python-django-statsd-mozilla",
"build-essential", "libssl-dev", "build-essential", "libssl-dev", "python-ujson",
"python-boto", "python-defusedxml", "python-twitter", "python-boto", "python-defusedxml", "python-twitter",
"python-twisted", "python-markdown", "python-twisted", "python-markdown",
"python-django-south", "python-mock", "python-pika", "python-django-south", "python-mock", "python-pika",

View File

@@ -1,7 +1,7 @@
from __future__ import absolute_import from __future__ import absolute_import
from django.conf import settings from django.conf import settings
import simplejson import ujson
def add_settings(request): def add_settings(request):
return { return {
@@ -11,5 +11,5 @@ def add_settings(request):
def add_metrics(request): def add_metrics(request):
return { return {
'mixpanel_token': settings.MIXPANEL_TOKEN, 'mixpanel_token': settings.MIXPANEL_TOKEN,
'enable_metrics': simplejson.dumps(settings.DEPLOYED), 'enable_metrics': ujson.dumps(settings.DEPLOYED),
} }

View File

@@ -10,7 +10,7 @@ from zephyr.lib.response import json_success, json_error, HttpResponseUnauthoriz
from django.utils.timezone import now from django.utils.timezone import now
from django.db import transaction, IntegrityError from django.db import transaction, IntegrityError
from django.conf import settings from django.conf import settings
import simplejson import ujson
from StringIO import StringIO from StringIO import StringIO
from zephyr.lib.cache import cache_with_key from zephyr.lib.cache import cache_with_key
from zephyr.lib.queue import queue_json_publish from zephyr.lib.queue import queue_json_publish
@@ -333,7 +333,7 @@ def to_non_negative_int(x):
return x return x
def json_to_foo(json, type): def json_to_foo(json, type):
data = simplejson.loads(json) data = ujson.loads(json)
if not isinstance(data, type): if not isinstance(data, type):
raise ValueError("argument is not a %s" % (type().__class__.__name__)) raise ValueError("argument is not a %s" % (type().__class__.__name__))
return data return data

View File

@@ -40,7 +40,7 @@ import confirmation.settings
from zephyr import tornado_callbacks from zephyr import tornado_callbacks
import subprocess import subprocess
import simplejson import ujson
import time import time
import traceback import traceback
import re import re
@@ -65,7 +65,7 @@ def log_event(event):
with lockfile(template % ('lock',)): with lockfile(template % ('lock',)):
with open(template % ('events',), 'a') as log: with open(template % ('events',), 'a') as log:
log.write(simplejson.dumps(event) + '\n') log.write(ujson.dumps(event) + '\n')
def do_create_user(email, password, realm, full_name, short_name, def do_create_user(email, password, realm, full_name, short_name,
active=True, bot=False, bot_owner=None, active=True, bot=False, bot_owner=None,
@@ -379,7 +379,7 @@ def already_sent_mirrored_message(message):
def extract_recipients(raw_recipients): def extract_recipients(raw_recipients):
try: try:
recipients = json_to_list(raw_recipients) recipients = json_to_list(raw_recipients)
except (simplejson.decoder.JSONDecodeError, ValueError): except ValueError:
recipients = [raw_recipients] recipients = [raw_recipients]
# Strip recipients, and then remove any duplicates and any that # Strip recipients, and then remove any duplicates and any that
@@ -927,7 +927,7 @@ def subscribed_to_stream(user_profile, stream):
return False return False
def do_update_onboarding_steps(user_profile, steps): def do_update_onboarding_steps(user_profile, steps):
user_profile.onboarding_steps = simplejson.dumps(steps) user_profile.onboarding_steps = ujson.dumps(steps)
user_profile.save() user_profile.save()
log_event({'type': 'update_onboarding', log_event({'type': 'update_onboarding',
@@ -959,7 +959,7 @@ def do_update_message(user_profile, message_id, subject, content):
# contains a prev_rendered_content element. # contains a prev_rendered_content element.
first_rendered_content = message.rendered_content first_rendered_content = message.rendered_content
if message.edit_history is not None: if message.edit_history is not None:
edit_history = simplejson.loads(message.edit_history) edit_history = ujson.loads(message.edit_history)
for old_edit_history_event in edit_history: for old_edit_history_event in edit_history:
if 'prev_rendered_content' in old_edit_history_event: if 'prev_rendered_content' in old_edit_history_event:
first_rendered_content = old_edit_history_event['prev_rendered_content'] first_rendered_content = old_edit_history_event['prev_rendered_content']
@@ -997,7 +997,7 @@ def do_update_message(user_profile, message_id, subject, content):
edit_history.insert(0, edit_history_event) edit_history.insert(0, edit_history_event)
else: else:
edit_history = [edit_history_event] edit_history = [edit_history_event]
message.edit_history = simplejson.dumps(edit_history) message.edit_history = ujson.dumps(edit_history)
log_event(event) log_event(event)
message.save(update_fields=["subject", "content", "rendered_content", message.save(update_fields=["subject", "content", "rendered_content",

View File

@@ -7,7 +7,7 @@ import os.path
import glob import glob
import urllib2 import urllib2
import itertools import itertools
import simplejson import ujson
import twitter import twitter
import platform import platform
import time import time

View File

@@ -1,10 +1,10 @@
import simplejson import ujson
def twitter(tweet_id): def twitter(tweet_id):
if tweet_id not in ["112652479837110273", "287977969287315456", "287977969287315457"]: if tweet_id not in ["112652479837110273", "287977969287315456", "287977969287315457"]:
return None return None
return simplejson.loads("""{ return ujson.loads("""{
"coordinates": null, "coordinates": null,
"created_at": "Sat Sep 10 22:23:38 +0000 2011", "created_at": "Sat Sep 10 22:23:38 +0000 2011",
"truncated": false, "truncated": false,

View File

@@ -5,7 +5,7 @@ from django.utils import timezone
from zephyr.models import UserProfile, Recipient, Subscription from zephyr.models import UserProfile, Recipient, Subscription
import base64 import base64
import hashlib import hashlib
import simplejson import ujson
import random import random
import string import string
@@ -14,7 +14,7 @@ import string
onboarding_steps = ["sent_stream_message", "sent_private_message", "made_app_sticky"] onboarding_steps = ["sent_stream_message", "sent_private_message", "made_app_sticky"]
def create_onboarding_steps_blob(): def create_onboarding_steps_blob():
return simplejson.dumps([(step, False) for step in onboarding_steps]) return ujson.dumps([(step, False) for step in onboarding_steps])
# create_user_profile is based on Django's User.objects.create_user, # create_user_profile is based on Django's User.objects.create_user,
# except that we don't save to the database so it can used in # except that we don't save to the database so it can used in

View File

@@ -6,7 +6,7 @@ import os
import time import time
import socket import socket
import logging import logging
import simplejson import ujson
import requests import requests
import cPickle as pickle import cPickle as pickle
import atexit import atexit
@@ -247,11 +247,11 @@ def request_event_queue(user_profile, user_client, apply_markdown,
event_types=None): event_types=None):
if settings.TORNADO_SERVER: if settings.TORNADO_SERVER:
req = {'dont_block' : 'true', req = {'dont_block' : 'true',
'apply_markdown': simplejson.dumps(apply_markdown), 'apply_markdown': ujson.dumps(apply_markdown),
'client' : 'internal', 'client' : 'internal',
'user_client' : user_client.name} 'user_client' : user_client.name}
if event_types is not None: if event_types is not None:
req['event_types'] = simplejson.dumps(event_types) req['event_types'] = ujson.dumps(event_types)
resp = requests.get(settings.TORNADO_SERVER + '/api/v1/events', resp = requests.get(settings.TORNADO_SERVER + '/api/v1/events',
auth=requests.auth.HTTPBasicAuth(user_profile.email, auth=requests.auth.HTTPBasicAuth(user_profile.email,
user_profile.api_key), user_profile.api_key),

View File

@@ -3,7 +3,7 @@ from __future__ import absolute_import
from django.conf import settings from django.conf import settings
import pika import pika
import logging import logging
import simplejson import ujson
import random import random
import time import time
import threading import threading
@@ -84,12 +84,12 @@ class SimpleQueueClient(object):
def json_publish(self, queue_name, body): def json_publish(self, queue_name, body):
try: try:
return self.publish(queue_name, simplejson.dumps(body)) return self.publish(queue_name, ujson.dumps(body))
except (AttributeError, pika.exceptions.AMQPConnectionError): except (AttributeError, pika.exceptions.AMQPConnectionError):
self.log.warning("Failed to send to rabbitmq, trying to reconnect and send again") self.log.warning("Failed to send to rabbitmq, trying to reconnect and send again")
self._reconnect() self._reconnect()
return self.publish(queue_name, simplejson.dumps(body)) return self.publish(queue_name, ujson.dumps(body))
def register_consumer(self, queue_name, consumer): def register_consumer(self, queue_name, consumer):
def wrapped_consumer(ch, method, properties, body): def wrapped_consumer(ch, method, properties, body):
@@ -103,7 +103,7 @@ class SimpleQueueClient(object):
def register_json_consumer(self, queue_name, callback): def register_json_consumer(self, queue_name, callback):
def wrapped_callback(ch, method, properties, body): def wrapped_callback(ch, method, properties, body):
return callback(ch, method, properties, simplejson.loads(body)) return callback(ch, method, properties, ujson.loads(body))
return self.register_consumer(queue_name, wrapped_callback) return self.register_consumer(queue_name, wrapped_callback)
def drain_queue(self, queue_name, json=False): def drain_queue(self, queue_name, json=False):
@@ -118,7 +118,7 @@ class SimpleQueueClient(object):
self.channel.basic_ack(meta.delivery_tag) self.channel.basic_ack(meta.delivery_tag)
if json: if json:
message = simplejson.loads(message) message = ujson.loads(message)
messages.append(message) messages.append(message)
self.ensure_queue(queue_name, opened) self.ensure_queue(queue_name, opened)

View File

@@ -1,7 +1,7 @@
from __future__ import absolute_import from __future__ import absolute_import
from django.http import HttpResponse, HttpResponseNotAllowed from django.http import HttpResponse, HttpResponseNotAllowed
import simplejson import ujson
class HttpResponseUnauthorized(HttpResponse): class HttpResponseUnauthorized(HttpResponse):
status_code = 401 status_code = 401
@@ -12,7 +12,7 @@ class HttpResponseUnauthorized(HttpResponse):
def json_method_not_allowed(methods): def json_method_not_allowed(methods):
resp = HttpResponseNotAllowed(methods) resp = HttpResponseNotAllowed(methods)
resp.content = simplejson.dumps({"result": "error", resp.content = ujson.dumps({"result": "error",
"msg": "Method Not Allowed", "msg": "Method Not Allowed",
"allowed_methods": methods}) "allowed_methods": methods})
return resp return resp
@@ -20,7 +20,7 @@ def json_method_not_allowed(methods):
def json_response(res_type="success", msg="", data={}, status=200): def json_response(res_type="success", msg="", data={}, status=200):
content = {"result": res_type, "msg": msg} content = {"result": res_type, "msg": msg}
content.update(data) content.update(data)
return HttpResponse(content=simplejson.dumps(content), return HttpResponse(content=ujson.dumps(content),
mimetype='application/json', status=status) mimetype='application/json', status=status)
def json_success(data={}): def json_success(data={}):

View File

@@ -2,7 +2,7 @@ from __future__ import absolute_import
import re import re
import bisect import bisect
import simplejson import ujson
import collections import collections
from os import path from os import path
@@ -92,7 +92,7 @@ class SourceMap(object):
'''Map (line,column) pairs from generated to source file.''' '''Map (line,column) pairs from generated to source file.'''
def __init__(self, sourcemap_file): def __init__(self, sourcemap_file):
with open(sourcemap_file, 'r') as fil: with open(sourcemap_file, 'r') as fil:
sourcemap = simplejson.load(fil) sourcemap = ujson.load(fil)
# Pair each link with a sort / search key # Pair each link with a sort / search key
self._links = [ ((link.gen_line, link.gen_col), link) self._links = [ ((link.gen_line, link.gen_col), link)

View File

@@ -3,7 +3,7 @@ from __future__ import absolute_import
from optparse import make_option from optparse import make_option
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from zephyr.models import Realm, UserProfile, Recipient, Message, get_client from zephyr.models import Realm, UserProfile, Recipient, Message, get_client
import simplejson import ujson
from zephyr.lib.timestamp import datetime_to_timestamp, timestamp_to_datetime from zephyr.lib.timestamp import datetime_to_timestamp, timestamp_to_datetime
import datetime import datetime
import time import time

View File

@@ -4,16 +4,16 @@ from optparse import make_option
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from zephyr.models import UserProfile, get_user_profile_by_email from zephyr.models import UserProfile, get_user_profile_by_email
from zephyr.lib.actions import do_change_password from zephyr.lib.actions import do_change_password
import simplejson import ujson
def dump(): def dump():
passwords = [] passwords = []
for user_profile in UserProfile.objects.all(): for user_profile in UserProfile.objects.all():
passwords.append((user_profile.email, user_profile.password)) passwords.append((user_profile.email, user_profile.password))
file("dumped-passwords", "w").write(simplejson.dumps(passwords) + "\n") file("dumped-passwords", "w").write(ujson.dumps(passwords) + "\n")
def restore(change): def restore(change):
for (email, password) in simplejson.loads(file("dumped-passwords").read()): for (email, password) in ujson.loads(file("dumped-passwords").read()):
try: try:
user_profile = get_user_profile_by_email(email) user_profile = get_user_profile_by_email(email)
except UserProfile.DoesNotExist: except UserProfile.DoesNotExist:

View File

@@ -5,7 +5,7 @@ from django.core.management.base import BaseCommand
from zephyr.models import Realm, UserProfile, Message, UserMessage, \ from zephyr.models import Realm, UserProfile, Message, UserMessage, \
get_user_profile_by_email get_user_profile_by_email
from zephyr.lib.timestamp import datetime_to_timestamp, timestamp_to_datetime from zephyr.lib.timestamp import datetime_to_timestamp, timestamp_to_datetime
import simplejson import ujson
def dump(): def dump():
pointers = [] pointers = []
@@ -16,10 +16,10 @@ def dump():
pointers.append((u.email, datetime_to_timestamp(pub_date))) pointers.append((u.email, datetime_to_timestamp(pub_date)))
else: else:
pointers.append((u.email, -1)) pointers.append((u.email, -1))
file("dumped-pointers", "w").write(simplejson.dumps(pointers) + "\n") file("dumped-pointers", "w").write(ujson.dumps(pointers) + "\n")
def restore(change): def restore(change):
for (email, timestamp) in simplejson.loads(file("dumped-pointers").read()): for (email, timestamp) in ujson.loads(file("dumped-pointers").read()):
try: try:
u = get_user_profile_by_email(email) u = get_user_profile_by_email(email)
except UserProfile.DoesNotExist: except UserProfile.DoesNotExist:

View File

@@ -4,7 +4,7 @@ from optparse import make_option
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from zephyr.models import Realm, UserActivity, get_client, \ from zephyr.models import Realm, UserActivity, get_client, \
get_user_profile_by_email get_user_profile_by_email
import simplejson import ujson
from zephyr.lib.timestamp import datetime_to_timestamp, timestamp_to_datetime from zephyr.lib.timestamp import datetime_to_timestamp, timestamp_to_datetime
def dump(): def dump():
@@ -14,10 +14,10 @@ def dump():
pointers.append((activity.user_profile.email, activity.client.name, pointers.append((activity.user_profile.email, activity.client.name,
activity.query, activity.count, activity.query, activity.count,
datetime_to_timestamp(activity.last_visit))) datetime_to_timestamp(activity.last_visit)))
file("dumped-activity", "w").write(simplejson.dumps(pointers) + "\n") file("dumped-activity", "w").write(ujson.dumps(pointers) + "\n")
def restore(change): def restore(change):
for (email, client_name, query, count, timestamp) in simplejson.loads(file("dumped-activity").read()): for (email, client_name, query, count, timestamp) in ujson.loads(file("dumped-activity").read()):
user_profile = get_user_profile_by_email(email) user_profile = get_user_profile_by_email(email)
client = get_client(client_name) client = get_client(client_name)
last_visit = timestamp_to_datetime(timestamp) last_visit = timestamp_to_datetime(timestamp)

View File

@@ -5,7 +5,7 @@ import sys
import datetime import datetime
import tempfile import tempfile
import traceback import traceback
import simplejson import ujson
from os import path from os import path
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
@@ -17,7 +17,7 @@ def copy_retained_messages(infile, outfile):
"""Copy messages from infile to outfile which should be retained """Copy messages from infile to outfile which should be retained
according to policy.""" according to policy."""
for ln in infile: for ln in infile:
msg = simplejson.loads(ln) msg = ujson.loads(ln)
if not should_expunge_from_log(msg, now): if not should_expunge_from_log(msg, now):
outfile.write(ln) outfile.write(ln)

View File

@@ -18,7 +18,7 @@ from zephyr.lib.bulk_create import bulk_create_realms, \
from zephyr.lib.timestamp import timestamp_to_datetime from zephyr.lib.timestamp import timestamp_to_datetime
from zephyr.models import MAX_MESSAGE_LENGTH from zephyr.models import MAX_MESSAGE_LENGTH
import simplejson import ujson
import datetime import datetime
import random import random
import glob import glob
@@ -275,14 +275,14 @@ def restore_saved_messages():
# created goes with the Nth non-subscription row of the input # created goes with the Nth non-subscription row of the input
# So suppress the duplicates when using sqlite. # So suppress the duplicates when using sqlite.
if "sqlite" in settings.DATABASES["default"]["ENGINE"]: if "sqlite" in settings.DATABASES["default"]["ENGINE"]:
tmp_message = simplejson.loads(old_message_json) tmp_message = ujson.loads(old_message_json)
tmp_message['id'] = '1' tmp_message['id'] = '1'
duplicate_suppression_key = simplejson.dumps(tmp_message) duplicate_suppression_key = ujson.dumps(tmp_message)
if duplicate_suppression_key in duplicate_suppression_hash: if duplicate_suppression_key in duplicate_suppression_hash:
return return
duplicate_suppression_hash[duplicate_suppression_key] = True duplicate_suppression_hash[duplicate_suppression_key] = True
old_message = simplejson.loads(old_message_json) old_message = ujson.loads(old_message_json)
message_type = old_message["type"] message_type = old_message["type"]
# Lower case emails and domains; it will screw up # Lower case emails and domains; it will screw up

View File

@@ -2,7 +2,7 @@ from __future__ import absolute_import
from optparse import make_option from optparse import make_option
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
import simplejson import ujson
import pika import pika
from zephyr.lib.actions import process_user_activity_event, \ from zephyr.lib.actions import process_user_activity_event, \
process_user_presence_event, process_update_message_flags process_user_presence_event, process_update_message_flags

View File

@@ -1,7 +1,7 @@
from __future__ import absolute_import from __future__ import absolute_import
import time import time
import simplejson import ujson
from collections import defaultdict from collections import defaultdict

View File

@@ -1,6 +1,6 @@
from __future__ import absolute_import from __future__ import absolute_import
import simplejson import ujson
from postmonkey import PostMonkey from postmonkey import PostMonkey
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.conf import settings from django.conf import settings

View File

@@ -18,7 +18,7 @@ from zephyr.lib.timestamp import datetime_to_timestamp
from django.db.models.signals import post_save from django.db.models.signals import post_save
from bitfield import BitField from bitfield import BitField
import simplejson import ujson
MAX_SUBJECT_LENGTH = 60 MAX_SUBJECT_LENGTH = 60
MAX_MESSAGE_LENGTH = 10000 MAX_MESSAGE_LENGTH = 10000
@@ -117,7 +117,7 @@ class UserProfile(AbstractBaseUser):
# [("step 1", true), ("step 2", false)] # [("step 1", true), ("step 2", false)]
# where the second element of each tuple is if the step has been # where the second element of each tuple is if the step has been
# completed. # completed.
onboarding_steps = models.TextField(default=simplejson.dumps([])) onboarding_steps = models.TextField(default=ujson.dumps([]))
def tutorial_stream_name(self): def tutorial_stream_name(self):
# If you change this, you need to change the corresponding # If you change this, you need to change the corresponding
@@ -339,7 +339,7 @@ class Message(models.Model):
if self.last_edit_time != None: if self.last_edit_time != None:
obj['last_edit_timestamp'] = datetime_to_timestamp(self.last_edit_time) obj['last_edit_timestamp'] = datetime_to_timestamp(self.last_edit_time)
obj['edit_history'] = simplejson.loads(self.edit_history) obj['edit_history'] = ujson.loads(self.edit_history)
if apply_markdown and self.rendered_content_version is not None: if apply_markdown and self.rendered_content_version is not None:
obj['content'] = self.rendered_content obj['content'] = self.rendered_content
obj['content_type'] = 'text/html' obj['content_type'] = 'text/html'

View File

@@ -22,11 +22,11 @@ import optparse
import os import os
import random import random
import re import re
import simplejson
import subprocess import subprocess
import sys import sys
import time import time
import traceback import traceback
import ujson
import urllib2 import urllib2
from StringIO import StringIO from StringIO import StringIO
@@ -139,7 +139,7 @@ class AuthedTestCase(TestCase):
post_params = {"anchor": anchor, "num_before": num_before, post_params = {"anchor": anchor, "num_before": num_before,
"num_after": num_after} "num_after": num_after}
result = self.client.post("/json/get_old_messages", dict(post_params)) result = self.client.post("/json/get_old_messages", dict(post_params))
data = simplejson.loads(result.content) data = ujson.loads(result.content)
return data['messages'] return data['messages']
def users_subscribed_to_stream(self, stream_name, realm_domain): def users_subscribed_to_stream(self, stream_name, realm_domain):
@@ -159,7 +159,7 @@ class AuthedTestCase(TestCase):
"msg": ""}. "msg": ""}.
""" """
self.assertEqual(result.status_code, 200) self.assertEqual(result.status_code, 200)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertEqual(json.get("result"), "success") self.assertEqual(json.get("result"), "success")
# We have a msg key for consistency with errors, but it typically has an # We have a msg key for consistency with errors, but it typically has an
# empty value. # empty value.
@@ -167,7 +167,7 @@ class AuthedTestCase(TestCase):
def get_json_error(self, result): def get_json_error(self, result):
self.assertEqual(result.status_code, 400) self.assertEqual(result.status_code, 400)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertEqual(json.get("result"), "error") self.assertEqual(json.get("result"), "error")
return json['msg'] return json['msg']
@@ -607,8 +607,8 @@ class MessagePOSTTest(AuthedTestCase):
"sender": "sipbtest@mit.edu", "sender": "sipbtest@mit.edu",
"content": "Test message", "content": "Test message",
"client": "zephyr_mirror", "client": "zephyr_mirror",
"to": simplejson.dumps(["starnine@mit.edu", "to": ujson.dumps(["starnine@mit.edu",
"espuser@mit.edu"])}) "espuser@mit.edu"])})
self.assert_json_success(result) self.assert_json_success(result)
def test_mirrored_personal(self): def test_mirrored_personal(self):
@@ -639,7 +639,7 @@ class SubscriptionPropertiesTest(AuthedTestCase):
"stream_name": subs[0]['name']}) "stream_name": subs[0]['name']})
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertIn("stream_name", json) self.assertIn("stream_name", json)
self.assertIn("value", json) self.assertIn("value", json)
@@ -750,7 +750,7 @@ class SubscriptionAPITest(AuthedTestCase):
""" """
result = self.client.post("/json/subscriptions/list", {}) result = self.client.post("/json/subscriptions/list", {})
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertIn("subscriptions", json) self.assertIn("subscriptions", json)
for stream in json["subscriptions"]: for stream in json["subscriptions"]:
self.assertIsInstance(stream['name'], basestring) self.assertIsInstance(stream['name'], basestring)
@@ -781,11 +781,11 @@ class SubscriptionAPITest(AuthedTestCase):
"already_subscribed": {"iago@humbughq.com": ["Venice", "Verona"]}, "already_subscribed": {"iago@humbughq.com": ["Venice", "Verona"]},
"subscribed": {"iago@humbughq.com": ["Venice8"]}} "subscribed": {"iago@humbughq.com": ["Venice8"]}}
""" """
data = {"subscriptions": simplejson.dumps(subscriptions)} data = {"subscriptions": ujson.dumps(subscriptions)}
data.update(other_params) data.update(other_params)
result = self.client.post(url, data) result = self.client.post(url, data)
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
for subscription_status, val in json_dict.iteritems(): for subscription_status, val in json_dict.iteritems():
# keys are subscribed, already_subscribed. # keys are subscribed, already_subscribed.
# vals are a dict mapping e-mails to streams. # vals are a dict mapping e-mails to streams.
@@ -829,7 +829,7 @@ class SubscriptionAPITest(AuthedTestCase):
# character limit is 30 characters # character limit is 30 characters
long_stream_name = "a" * 31 long_stream_name = "a" * 31
result = self.client.post("/json/subscriptions/add", result = self.client.post("/json/subscriptions/add",
{"subscriptions": simplejson.dumps([long_stream_name])}) {"subscriptions": ujson.dumps([long_stream_name])})
self.assert_json_error(result, self.assert_json_error(result,
"Stream name (%s) too long." % (long_stream_name,)) "Stream name (%s) too long." % (long_stream_name,))
@@ -842,7 +842,7 @@ class SubscriptionAPITest(AuthedTestCase):
# currently, the only invalid name is the empty string # currently, the only invalid name is the empty string
invalid_stream_name = "" invalid_stream_name = ""
result = self.client.post("/json/subscriptions/add", result = self.client.post("/json/subscriptions/add",
{"subscriptions": simplejson.dumps([invalid_stream_name])}) {"subscriptions": ujson.dumps([invalid_stream_name])})
self.assert_json_error(result, self.assert_json_error(result,
"Invalid stream name (%s)." % (invalid_stream_name,)) "Invalid stream name (%s)." % (invalid_stream_name,))
@@ -862,7 +862,7 @@ class SubscriptionAPITest(AuthedTestCase):
streams_to_sub.extend(current_streams) streams_to_sub.extend(current_streams)
self.helper_check_subs_before_and_after_add( self.helper_check_subs_before_and_after_add(
"/json/subscriptions/add", streams_to_sub, "/json/subscriptions/add", streams_to_sub,
{"principals": simplejson.dumps([invitee])}, {"principals": ujson.dumps([invitee])},
{"subscribed": {invitee: streams[:1]}, {"subscribed": {invitee: streams[:1]},
"already_subscribed": {invitee: current_streams}}, "already_subscribed": {invitee: current_streams}},
invitee, streams_to_sub) invitee, streams_to_sub)
@@ -906,8 +906,8 @@ class SubscriptionAPITest(AuthedTestCase):
with self.assertRaises(UserProfile.DoesNotExist): with self.assertRaises(UserProfile.DoesNotExist):
self.get_user_profile(invalid_principal) self.get_user_profile(invalid_principal)
result = self.client.post("/json/subscriptions/add", result = self.client.post("/json/subscriptions/add",
{"subscriptions": simplejson.dumps(self.streams), {"subscriptions": ujson.dumps(self.streams),
"principals": simplejson.dumps([invalid_principal])}) "principals": ujson.dumps([invalid_principal])})
self.assert_json_error(result, "User not authorized to execute queries on behalf of '%s'" self.assert_json_error(result, "User not authorized to execute queries on behalf of '%s'"
% (invalid_principal,)) % (invalid_principal,))
@@ -921,8 +921,8 @@ class SubscriptionAPITest(AuthedTestCase):
# verify that principal exists (thus, the reason for the error is the cross-realming) # verify that principal exists (thus, the reason for the error is the cross-realming)
self.assertIsInstance(profile, UserProfile) self.assertIsInstance(profile, UserProfile)
result = self.client.post("/json/subscriptions/add", result = self.client.post("/json/subscriptions/add",
{"subscriptions": simplejson.dumps(self.streams), {"subscriptions": ujson.dumps(self.streams),
"principals": simplejson.dumps([principal])}) "principals": ujson.dumps([principal])})
self.assert_json_error(result, "User not authorized to execute queries on behalf of '%s'" self.assert_json_error(result, "User not authorized to execute queries on behalf of '%s'"
% (principal,)) % (principal,))
@@ -938,11 +938,11 @@ class SubscriptionAPITest(AuthedTestCase):
"removed": ["Denmark", "Scotland", "Verona"], "removed": ["Denmark", "Scotland", "Verona"],
"not_subscribed": ["Rome"], "result": "success"} "not_subscribed": ["Rome"], "result": "success"}
""" """
data = {"subscriptions": simplejson.dumps(subscriptions)} data = {"subscriptions": ujson.dumps(subscriptions)}
data.update(other_params) data.update(other_params)
result = self.client.post(url, data) result = self.client.post(url, data)
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
for key, val in json_dict.iteritems(): for key, val in json_dict.iteritems():
self.assertItemsEqual(val, json[key]) # we don't care about the order of the items self.assertItemsEqual(val, json[key]) # we don't care about the order of the items
new_streams = self.get_streams(email) new_streams = self.get_streams(email)
@@ -981,7 +981,7 @@ class SubscriptionAPITest(AuthedTestCase):
self.assertNotEqual(len(random_streams), 0) # necessary for full test coverage self.assertNotEqual(len(random_streams), 0) # necessary for full test coverage
streams_to_remove = random_streams[:1] # pick only one fake stream, to make checking the error message easy streams_to_remove = random_streams[:1] # pick only one fake stream, to make checking the error message easy
result = self.client.post("/json/subscriptions/remove", result = self.client.post("/json/subscriptions/remove",
{"subscriptions": simplejson.dumps(streams_to_remove)}) {"subscriptions": ujson.dumps(streams_to_remove)})
self.assert_json_error(result, "Stream(s) (%s) do not exist" % (random_streams[0],)) self.assert_json_error(result, "Stream(s) (%s) do not exist" % (random_streams[0],))
def helper_subscriptions_exists(self, stream, exists, subscribed): def helper_subscriptions_exists(self, stream, exists, subscribed):
@@ -993,7 +993,7 @@ class SubscriptionAPITest(AuthedTestCase):
""" """
result = self.client.post("/json/subscriptions/exists", result = self.client.post("/json/subscriptions/exists",
{"stream": stream}) {"stream": stream})
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertIn("exists", json) self.assertIn("exists", json)
self.assertEqual(json["exists"], exists) self.assertEqual(json["exists"], exists)
if exists: if exists:
@@ -1051,7 +1051,7 @@ class GetOldMessagesTest(AuthedTestCase):
post_params.update(modified_params) post_params.update(modified_params)
result = self.client.post("/json/get_old_messages", dict(post_params)) result = self.client.post("/json/get_old_messages", dict(post_params))
self.assert_json_success(result) self.assert_json_success(result)
return simplejson.loads(result.content) return ujson.loads(result.content)
def check_well_formed_messages_response(self, result): def check_well_formed_messages_response(self, result):
self.assertIn("messages", result) self.assertIn("messages", result)
@@ -1091,7 +1091,7 @@ class GetOldMessagesTest(AuthedTestCase):
emails = dr_emails(get_display_recipient(personals[0].recipient)) emails = dr_emails(get_display_recipient(personals[0].recipient))
self.login(me) self.login(me)
result = self.post_with_params({"narrow": simplejson.dumps( result = self.post_with_params({"narrow": ujson.dumps(
[['pm-with', emails]])}) [['pm-with', emails]])})
self.check_well_formed_messages_response(result) self.check_well_formed_messages_response(result)
@@ -1118,7 +1118,7 @@ class GetOldMessagesTest(AuthedTestCase):
stream_name = get_display_recipient(stream_messages[0].recipient) stream_name = get_display_recipient(stream_messages[0].recipient)
stream_id = stream_messages[0].recipient.id stream_id = stream_messages[0].recipient.id
result = self.post_with_params({"narrow": simplejson.dumps( result = self.post_with_params({"narrow": ujson.dumps(
[['stream', stream_name]])}) [['stream', stream_name]])})
self.check_well_formed_messages_response(result) self.check_well_formed_messages_response(result)
@@ -1139,7 +1139,7 @@ class GetOldMessagesTest(AuthedTestCase):
self.send_message("othello@humbughq.com", "hamlet@humbughq.com", Recipient.PERSONAL) self.send_message("othello@humbughq.com", "hamlet@humbughq.com", Recipient.PERSONAL)
self.send_message("iago@humbughq.com", "Scotland", Recipient.STREAM) self.send_message("iago@humbughq.com", "Scotland", Recipient.STREAM)
result = self.post_with_params({"narrow": simplejson.dumps( result = self.post_with_params({"narrow": ujson.dumps(
[['sender', "othello@humbughq.com"]])}) [['sender', "othello@humbughq.com"]])})
self.check_well_formed_messages_response(result) self.check_well_formed_messages_response(result)
@@ -1220,7 +1220,7 @@ class GetOldMessagesTest(AuthedTestCase):
self.login("hamlet@humbughq.com") self.login("hamlet@humbughq.com")
for operator in ['', 'foo', 'stream:verona', '__init__']: for operator in ['', 'foo', 'stream:verona', '__init__']:
params = dict(anchor=0, num_before=0, num_after=0, params = dict(anchor=0, num_before=0, num_after=0,
narrow=simplejson.dumps([[operator, '']])) narrow=ujson.dumps([[operator, '']]))
result = self.client.post("/json/get_old_messages", params) result = self.client.post("/json/get_old_messages", params)
self.assert_json_error_contains(result, self.assert_json_error_contains(result,
"Invalid narrow operator: unknown operator") "Invalid narrow operator: unknown operator")
@@ -1229,7 +1229,7 @@ class GetOldMessagesTest(AuthedTestCase):
other_params = [("anchor", 0), ("num_before", 0), ("num_after", 0)] other_params = [("anchor", 0), ("num_before", 0), ("num_after", 0)]
for operand in operands: for operand in operands:
post_params = dict(other_params + [ post_params = dict(other_params + [
("narrow", simplejson.dumps([[operator, operand]]))]) ("narrow", ujson.dumps([[operator, operand]]))])
result = self.client.post("/json/get_old_messages", post_params) result = self.client.post("/json/get_old_messages", post_params)
self.assert_json_error_contains(result, error_msg) self.assert_json_error_contains(result, error_msg)
@@ -1443,7 +1443,7 @@ class ChangeSettingsTest(AuthedTestCase):
self.login("hamlet@humbughq.com") self.login("hamlet@humbughq.com")
json_result = self.post_with_params({}) json_result = self.post_with_params({})
self.assert_json_success(json_result) self.assert_json_success(json_result)
result = simplejson.loads(json_result.content) result = ujson.loads(json_result.content)
self.check_well_formed_change_settings_response(result) self.check_well_formed_change_settings_response(result)
self.assertEqual(self.get_user_profile("hamlet@humbughq.com"). self.assertEqual(self.get_user_profile("hamlet@humbughq.com").
full_name, "Foo Bar") full_name, "Foo Bar")
@@ -1502,7 +1502,7 @@ class S3Test(AuthedTestCase):
result = self.client.post("/json/upload_file", {'file': fp}) result = self.client.post("/json/upload_file", {'file': fp})
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertIn("uri", json) self.assertIn("uri", json)
uri = json["uri"] uri = json["uri"]
self.test_uris.append(uri) self.test_uris.append(uri)
@@ -1642,7 +1642,7 @@ class GetProfileTest(AuthedTestCase):
max_id = stream[-1].id max_id = stream[-1].id
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertIn("client_id", json) self.assertIn("client_id", json)
self.assertIn("max_message_id", json) self.assertIn("max_message_id", json)
@@ -1685,7 +1685,7 @@ class GetPublicStreamsTest(AuthedTestCase):
result = self.client.post("/json/get_public_streams", {'email': email, 'api-key': api_key}) result = self.client.post("/json/get_public_streams", {'email': email, 'api-key': api_key})
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertIn("streams", json) self.assertIn("streams", json)
self.assertIsInstance(json["streams"], list) self.assertIsInstance(json["streams"], list)
@@ -1698,7 +1698,7 @@ class InviteOnlyStreamTest(AuthedTestCase):
post_data = {'email': email, post_data = {'email': email,
'api-key': api_key, 'api-key': api_key,
'subscriptions': streams, 'subscriptions': streams,
'invite_only': simplejson.dumps(invite_only)} 'invite_only': ujson.dumps(invite_only)}
post_data.update(extra_post_data) post_data.update(extra_post_data)
result = self.client.post("/api/v1/subscriptions/add", post_data) result = self.client.post("/api/v1/subscriptions/add", post_data)
@@ -1718,7 +1718,7 @@ class InviteOnlyStreamTest(AuthedTestCase):
self.assert_json_success(result2) self.assert_json_success(result2)
result = self.client.post("/json/subscriptions/list", {}) result = self.client.post("/json/subscriptions/list", {})
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertIn("subscriptions", json) self.assertIn("subscriptions", json)
for sub in json["subscriptions"]: for sub in json["subscriptions"]:
if sub['name'] == "Normandy": if sub['name'] == "Normandy":
@@ -1733,7 +1733,7 @@ class InviteOnlyStreamTest(AuthedTestCase):
result = self.common_subscribe_to_stream(email, '["Saxony"]', invite_only=True) result = self.common_subscribe_to_stream(email, '["Saxony"]', invite_only=True)
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertEqual(json["subscribed"], {email: ['Saxony']}) self.assertEqual(json["subscribed"], {email: ['Saxony']})
self.assertEqual(json["already_subscribed"], {}) self.assertEqual(json["already_subscribed"], {})
@@ -1748,8 +1748,8 @@ class InviteOnlyStreamTest(AuthedTestCase):
self.login(email) self.login(email)
result = self.common_subscribe_to_stream( result = self.common_subscribe_to_stream(
email, '["Saxony"]', email, '["Saxony"]',
extra_post_data={'principals': simplejson.dumps(["othello@humbughq.com"])}) extra_post_data={'principals': ujson.dumps(["othello@humbughq.com"])})
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertEqual(json["subscribed"], {"othello@humbughq.com": ['Saxony']}) self.assertEqual(json["subscribed"], {"othello@humbughq.com": ['Saxony']})
self.assertEqual(json["already_subscribed"], {}) self.assertEqual(json["already_subscribed"], {})
@@ -1758,7 +1758,7 @@ class InviteOnlyStreamTest(AuthedTestCase):
'api-key': self.get_api_key(email), 'api-key': self.get_api_key(email),
'stream': 'Saxony'}) 'stream': 'Saxony'})
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertTrue('othello@humbughq.com' in json['subscribers']) self.assertTrue('othello@humbughq.com' in json['subscribers'])
self.assertTrue('hamlet@humbughq.com' in json['subscribers']) self.assertTrue('hamlet@humbughq.com' in json['subscribers'])
@@ -1794,7 +1794,7 @@ class GetSubscribersTest(AuthedTestCase):
def make_successful_subscriber_request(self, stream_name): def make_successful_subscriber_request(self, stream_name):
result = self.make_subscriber_request(stream_name) result = self.make_subscriber_request(stream_name)
self.assert_json_success(result) self.assert_json_success(result)
self.check_well_formed_result(simplejson.loads(result.content), self.check_well_formed_result(ujson.loads(result.content),
stream_name, self.user_profile.realm.domain) stream_name, self.user_profile.realm.domain)
def test_subscriber(self): def test_subscriber(self):
@@ -1812,7 +1812,7 @@ class GetSubscribersTest(AuthedTestCase):
# Create a stream for which Hamlet is the only subscriber. # Create a stream for which Hamlet is the only subscriber.
stream_name = "Saxony" stream_name = "Saxony"
self.client.post("/json/subscriptions/add", self.client.post("/json/subscriptions/add",
{"subscriptions": simplejson.dumps([stream_name])}) {"subscriptions": ujson.dumps([stream_name])})
other_email = "othello@humbughq.com" other_email = "othello@humbughq.com"
# Fetch the subscriber list as a non-member. # Fetch the subscriber list as a non-member.
@@ -1825,8 +1825,8 @@ class GetSubscribersTest(AuthedTestCase):
""" """
stream_name = "Saxony" stream_name = "Saxony"
self.client.post("/json/subscriptions/add", self.client.post("/json/subscriptions/add",
{"subscriptions": simplejson.dumps([stream_name]), {"subscriptions": ujson.dumps([stream_name]),
"invite_only": simplejson.dumps(True)}) "invite_only": ujson.dumps(True)})
self.make_successful_subscriber_request(stream_name) self.make_successful_subscriber_request(stream_name)
def test_nonsubscriber_private_stream(self): def test_nonsubscriber_private_stream(self):
@@ -1836,8 +1836,8 @@ class GetSubscribersTest(AuthedTestCase):
# Create a private stream for which Hamlet is the only subscriber. # Create a private stream for which Hamlet is the only subscriber.
stream_name = "Saxony" stream_name = "Saxony"
self.client.post("/json/subscriptions/add", self.client.post("/json/subscriptions/add",
{"subscriptions": simplejson.dumps([stream_name]), {"subscriptions": ujson.dumps([stream_name]),
"invite_only": simplejson.dumps(True)}) "invite_only": ujson.dumps(True)})
other_email = "othello@humbughq.com" other_email = "othello@humbughq.com"
# Try to fetch the subscriber list as a non-member. # Try to fetch the subscriber list as a non-member.
@@ -2349,7 +2349,7 @@ class UserPresenceTests(AuthedTestCase):
result = self.client.post("/json/get_active_statuses", {'email': email, 'api-key': api_key}) result = self.client.post("/json/get_active_statuses", {'email': email, 'api-key': api_key})
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
for email, presence in json['presences'].items(): for email, presence in json['presences'].items():
self.assertEqual(presence, {}) self.assertEqual(presence, {})
@@ -2360,7 +2360,7 @@ class UserPresenceTests(AuthedTestCase):
def test_result(result): def test_result(result):
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertEqual(json['presences'][email][client]['status'], 'idle') self.assertEqual(json['presences'][email][client]['status'], 'idle')
self.assertIn('timestamp', json['presences'][email][client]) self.assertIn('timestamp', json['presences'][email][client])
self.assertIsInstance(json['presences'][email][client]['timestamp'], int) self.assertIsInstance(json['presences'][email][client]['timestamp'], int)
@@ -2378,7 +2378,7 @@ class UserPresenceTests(AuthedTestCase):
self.client.post("/json/update_active_status", {'email': email, 'api-key': api_key, 'status': 'idle'}) self.client.post("/json/update_active_status", {'email': email, 'api-key': api_key, 'status': 'idle'})
result = self.client.post("/json/get_active_statuses", {'email': email, 'api-key': api_key}) result = self.client.post("/json/get_active_statuses", {'email': email, 'api-key': api_key})
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertEqual(json['presences'][email][client]['status'], 'idle') self.assertEqual(json['presences'][email][client]['status'], 'idle')
self.assertEqual(json['presences']['hamlet@humbughq.com'][client]['status'], 'idle') self.assertEqual(json['presences']['hamlet@humbughq.com'][client]['status'], 'idle')
self.assertEqual(json['presences'].keys(), ['hamlet@humbughq.com', 'othello@humbughq.com']) self.assertEqual(json['presences'].keys(), ['hamlet@humbughq.com', 'othello@humbughq.com'])
@@ -2394,7 +2394,7 @@ class UserPresenceTests(AuthedTestCase):
result = self.client.post("/json/get_active_statuses", {'email': email, 'api-key': api_key}) result = self.client.post("/json/get_active_statuses", {'email': email, 'api-key': api_key})
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertEqual(json['presences'][email][client]['status'], 'idle') self.assertEqual(json['presences'][email][client]['status'], 'idle')
email = "othello@humbughq.com" email = "othello@humbughq.com"
@@ -2402,14 +2402,14 @@ class UserPresenceTests(AuthedTestCase):
self.client.post("/json/update_active_status", {'email': email, 'api-key': api_key, 'status': 'idle'}) self.client.post("/json/update_active_status", {'email': email, 'api-key': api_key, 'status': 'idle'})
result = self.client.post("/json/get_active_statuses", {'email': email, 'api-key': api_key}) result = self.client.post("/json/get_active_statuses", {'email': email, 'api-key': api_key})
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertEqual(json['presences'][email][client]['status'], 'idle') self.assertEqual(json['presences'][email][client]['status'], 'idle')
self.assertEqual(json['presences']['hamlet@humbughq.com'][client]['status'], 'idle') self.assertEqual(json['presences']['hamlet@humbughq.com'][client]['status'], 'idle')
self.client.post("/json/update_active_status", {'email': email, 'api-key': api_key, 'status': 'active'}) self.client.post("/json/update_active_status", {'email': email, 'api-key': api_key, 'status': 'active'})
result = self.client.post("/json/get_active_statuses", {'email': email, 'api-key': api_key}) result = self.client.post("/json/get_active_statuses", {'email': email, 'api-key': api_key})
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertEqual(json['presences'][email][client]['status'], 'active') self.assertEqual(json['presences'][email][client]['status'], 'active')
self.assertEqual(json['presences']['hamlet@humbughq.com'][client]['status'], 'idle') self.assertEqual(json['presences']['hamlet@humbughq.com'][client]['status'], 'idle')
@@ -2419,7 +2419,7 @@ class UserPresenceTests(AuthedTestCase):
api_key = self.common_init(email) api_key = self.common_init(email)
result = self.client.post("/json/update_active_status", {'email': email, 'api-key': api_key, 'status': 'idle'}) result = self.client.post("/json/update_active_status", {'email': email, 'api-key': api_key, 'status': 'idle'})
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertEqual(json['presences'], {}) self.assertEqual(json['presences'], {})
def test_same_realm(self): def test_same_realm(self):
@@ -2436,7 +2436,7 @@ class UserPresenceTests(AuthedTestCase):
result = self.client.post("/json/update_active_status", {'email': email, 'api-key': api_key, 'status': 'idle'}) result = self.client.post("/json/update_active_status", {'email': email, 'api-key': api_key, 'status': 'idle'})
self.assert_json_success(result) self.assert_json_success(result)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertEqual(json['presences'][email][client]['status'], 'idle') self.assertEqual(json['presences'][email][client]['status'], 'idle')
# We only want @humbughq.com emails # We only want @humbughq.com emails
for email in json['presences'].keys(): for email in json['presences'].keys():
@@ -2474,7 +2474,7 @@ class UnreadCountTests(AuthedTestCase):
def test_update_flags(self): def test_update_flags(self):
self.login("hamlet@humbughq.com") self.login("hamlet@humbughq.com")
result = self.client.post("/json/update_message_flags", {"messages": simplejson.dumps([1, 2]), result = self.client.post("/json/update_message_flags", {"messages": ujson.dumps([1, 2]),
"op": "add", "op": "add",
"flag": "read"}) "flag": "read"})
self.assert_json_success(result) self.assert_json_success(result)
@@ -2486,7 +2486,7 @@ class UnreadCountTests(AuthedTestCase):
elif msg['id'] == 2: elif msg['id'] == 2:
self.assertEqual(msg['flags'], ['read']) self.assertEqual(msg['flags'], ['read'])
result = self.client.post("/json/update_message_flags", {"messages": simplejson.dumps([2]), result = self.client.post("/json/update_message_flags", {"messages": ujson.dumps([2]),
"op": "remove", "op": "remove",
"flag": "read"}) "flag": "read"})
self.assert_json_success(result) self.assert_json_success(result)
@@ -2501,15 +2501,15 @@ class UnreadCountTests(AuthedTestCase):
def test_update_all_flags(self): def test_update_all_flags(self):
self.login("hamlet@humbughq.com") self.login("hamlet@humbughq.com")
result = self.client.post("/json/update_message_flags", {"messages": simplejson.dumps([1, 2]), result = self.client.post("/json/update_message_flags", {"messages": ujson.dumps([1, 2]),
"op": "add", "op": "add",
"flag": "read"}) "flag": "read"})
self.assert_json_success(result) self.assert_json_success(result)
result = self.client.post("/json/update_message_flags", {"messages": simplejson.dumps([]), result = self.client.post("/json/update_message_flags", {"messages": ujson.dumps([]),
"op": "remove", "op": "remove",
"flag": "read", "flag": "read",
"all": simplejson.dumps(True)}) "all": ujson.dumps(True)})
self.assert_json_success(result) self.assert_json_success(result)
for msg in self.get_old_messages(): for msg in self.get_old_messages():
@@ -2519,7 +2519,7 @@ class StarTests(AuthedTestCase):
def change_star(self, messages, add=True): def change_star(self, messages, add=True):
return self.client.post("/json/update_message_flags", return self.client.post("/json/update_message_flags",
{"messages": simplejson.dumps(messages), {"messages": ujson.dumps(messages),
"op": "add" if add else "remove", "op": "add" if add else "remove",
"flag": "starred"}) "flag": "starred"})
@@ -2928,7 +2928,7 @@ class RateLimitTests(AuthedTestCase):
result = self.send_api_message(email, api_key, "some stuff %s" % (i,)) result = self.send_api_message(email, api_key, "some stuff %s" % (i,))
self.assertEqual(result.status_code, 403) self.assertEqual(result.status_code, 403)
json = simplejson.loads(result.content) json = ujson.loads(result.content)
self.assertEqual(json.get("result"), "error") self.assertEqual(json.get("result"), "error")
self.assertIn("API usage exceeded rate limit, try again in", json.get("msg")) self.assertIn("API usage exceeded rate limit, try again in", json.get("msg"))

View File

@@ -16,7 +16,7 @@ import sys
import time import time
import logging import logging
import requests import requests
import simplejson import ujson
import subprocess import subprocess
import collections import collections
from django.db import connection from django.db import connection
@@ -352,7 +352,7 @@ def process_notification(data):
def send_notification_http(data): def send_notification_http(data):
if settings.TORNADO_SERVER: if settings.TORNADO_SERVER:
requests.post(settings.TORNADO_SERVER + '/notify_tornado', data=dict( requests.post(settings.TORNADO_SERVER + '/notify_tornado', data=dict(
data = simplejson.dumps(data), data = ujson.dumps(data),
secret = settings.SHARED_SECRET)) secret = settings.SHARED_SECRET))
def send_notification(data): def send_notification(data):

View File

@@ -19,7 +19,7 @@ from zephyr.lib.cache_helpers import cache_get_message
from zephyr.lib.event_queue import allocate_client_descriptor, get_client_descriptor from zephyr.lib.event_queue import allocate_client_descriptor, get_client_descriptor
import datetime import datetime
import simplejson import ujson
import socket import socket
import time import time
import sys import sys
@@ -27,7 +27,7 @@ import logging
@internal_notify_view @internal_notify_view
def notify(request): def notify(request):
process_notification(simplejson.loads(request.POST['data'])) process_notification(ujson.loads(request.POST['data']))
return json_success() return json_success()
@asynchronous @asynchronous

View File

@@ -59,6 +59,7 @@ from confirmation.models import Confirmation
import datetime import datetime
import ujson
import simplejson import simplejson
import re import re
import urllib import urllib
@@ -317,7 +318,7 @@ def accounts_accept_terms(request):
def api_endpoint_docs(request): def api_endpoint_docs(request):
raw_calls = open('templates/zephyr/api_content.json', 'r').read() raw_calls = open('templates/zephyr/api_content.json', 'r').read()
calls = simplejson.loads(raw_calls) calls = ujson.loads(raw_calls)
langs = set() langs = set()
for call in calls: for call in calls:
for example_type in ('request', 'response'): for example_type in ('request', 'response'):
@@ -555,7 +556,7 @@ def home(request):
event_queue_id = register_ret['queue_id'], event_queue_id = register_ret['queue_id'],
last_event_id = register_ret['last_event_id'], last_event_id = register_ret['last_event_id'],
max_message_id = register_ret['max_message_id'], max_message_id = register_ret['max_message_id'],
onboarding_steps = simplejson.loads(user_profile.onboarding_steps), onboarding_steps = ujson.loads(user_profile.onboarding_steps),
staging = settings.STAGING_DEPLOYED or settings.DEBUG staging = settings.STAGING_DEPLOYED or settings.DEBUG
)) ))
@@ -632,7 +633,7 @@ def json_get_old_messages(request, user_profile):
@has_request_variables @has_request_variables
def api_get_old_messages(request, user_profile, def api_get_old_messages(request, user_profile,
apply_markdown=REQ(default=False, apply_markdown=REQ(default=False,
converter=simplejson.loads)): converter=ujson.loads)):
return get_old_messages_backend(request, user_profile, return get_old_messages_backend(request, user_profile,
apply_markdown=apply_markdown) apply_markdown=apply_markdown)
@@ -1168,7 +1169,7 @@ def update_subscriptions_backend(request, user_profile,
if response.status_code != 200: if response.status_code != 200:
transaction.rollback() transaction.rollback()
return response return response
json_dict.update(simplejson.loads(response.content)) json_dict.update(ujson.loads(response.content))
return json_success(json_dict) return json_success(json_dict)
@authenticated_api_view @authenticated_api_view
@@ -1606,8 +1607,8 @@ def api_jira_webhook(request):
return json_error("Missing api_key parameter.") return json_error("Missing api_key parameter.")
try: try:
payload = simplejson.loads(request.body) payload = ujson.loads(request.body)
except simplejson.JSONDecodeError: except ValueError:
return json_error("Malformed JSON input") return json_error("Malformed JSON input")
try: try: