Merge branch 'master' into develop

This commit is contained in:
Tyson Clugg 2015-04-27 22:45:18 +10:00
commit 882f8977b1
6 changed files with 54 additions and 12 deletions

View file

@ -1,6 +1,7 @@
"""Django/PostgreSQL implementation of the Meteor DDP service."""
from __future__ import unicode_literals
import os.path
import sys
from pkg_resources import get_distribution, DistributionNotFound
from gevent.local import local
from dddp import alea
@ -89,9 +90,16 @@ class RandomStreams(object):
return self._streams[key]
def serializer_factory():
"""Make a new DDP serializer."""
from django.core.serializers import get_serializer
return get_serializer('ddp')()
THREAD_LOCAL = ThreadLocal(
alea_random=alea.Alea,
random_streams=RandomStreams,
serializer=serializer_factory,
)
METEOR_ID_CHARS = u'23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz'

View file

@ -191,6 +191,8 @@ class Collection(APIMixin):
qs = self.get_queryset(qs)
user_rels = self.user_rel
if user_rels:
if user is None:
return qs.none() # no user but we need one: return no objects.
if isinstance(user_rels, basestring):
user_rels = [user_rels]
user_filter = None
@ -399,9 +401,9 @@ class DDP(APIMixin):
this.error('Invalid publication name: %r' % name)
return
obj, created = Subscription.objects.get_or_create(
connection=this.ws.connection,
connection_id=this.ws.connection.pk,
sub_id=id_,
user=this.request.user,
user_id=this.request.user.pk,
defaults={
'publication': pub.name,
'publication_class': '%s.%s' % (

View file

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
('dddp', '0004_connection_server_addr'),
]
operations = [
migrations.AlterField(
model_name='subscription',
name='user',
field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, null=True),
preserve_default=True,
),
]

View file

@ -136,7 +136,7 @@ class Subscription(models.Model, object):
_publication_cache = {}
connection = models.ForeignKey(Connection)
sub_id = models.CharField(max_length=17)
user = models.ForeignKey(settings.AUTH_USER_MODEL)
user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True)
publication = models.CharField(max_length=255)
publication_class = models.CharField(max_length=255)
params_ejson = models.TextField(default='{}')

View file

@ -1,17 +1,28 @@
"""Django DDP utils for DDP messaging."""
from copy import deepcopy
from dddp import THREAD_LOCAL as this
from django.core.serializers import get_serializer
def serializer_factory():
"""Make a new DDP serializer."""
return get_serializer('ddp')()
from django.db.models.expressions import ExpressionNode
def obj_change_as_msg(obj, msg):
"""Generate a DDP msg for obj with specified msg type."""
serializer = this.get('serializer', serializer_factory)
# check for F expressions
exps = [
name for name, val in vars(obj).items()
if isinstance(val, ExpressionNode)
]
if exps:
# clone and update obj with values but only for the expression fields
obj = deepcopy(obj)
# Django 1.8 makes obj._meta public --> pylint: disable=W0212
for name, val in obj._meta.model.objects.values(*exps).get(pk=obj.pk):
setattr(obj, name, val)
# run serialization now that all fields are "concrete" (not F expressions)
serializer = this.serializer
data = serializer.serialize([obj])[0]
# collection name is <app>.<model>
name = data['model']
# cast ID as string

View file

@ -123,7 +123,7 @@ class DDPWebSocketApplication(geventwebsocket.WebSocketApplication):
this.send_msg = self.send_msg
this.reply = self.reply
this.error = self.error
this.session_key = this.request.session.session_key
this.request.session.save()
this.remote_addr = self.remote_addr = \
'{0[REMOTE_ADDR]}:{0[REMOTE_PORT]}'.format(
@ -280,7 +280,7 @@ class DDPWebSocketApplication(geventwebsocket.WebSocketApplication):
this.version = version
this.support = support
self.connection = Connection.objects.create(
session_id=this.session_key,
session_id=this.request.session.session_key,
server_addr='%d:%s' % (
backend_pid,
self.ws.handler.socket.getsockname(),