def posted_event(post, **extra_data): data = serializers.post2dict(post, **extra_data) teacher_ids = post.elders_in_context.filter( school_staff=True).values_list('pk', flat=True) for teacher_id in teacher_ids: channel = 'user_%s' % teacher_id my_data = { 'objects': [dict(data, mine=data['author_id'] == teacher_id)]} trigger(channel, 'message_posted', my_data)
def posted_event(post, **extra_data): data = serializers.post2dict(post, **extra_data) teacher_ids = post.elders_in_context.filter(school_staff=True).values_list( 'pk', flat=True) for teacher_id in teacher_ids: channel = 'user_%s' % teacher_id my_data = { 'objects': [dict(data, mine=data['author_id'] == teacher_id)] } trigger(channel, 'message_posted', my_data)
def test_post2dict_no_author(db): """Special handling for author-less (automated) posts.""" student = factories.ProfileFactory.create() post = factories.PostFactory.create(author=None, student=student) d = serializers.post2dict(post) assert d['author_id'] == 0 assert d['author'] == "Portfoliyo" assert d['role'] == ""
def test_post2dict_no_relationship(db): """If relationship is gone, uses author's role instead.""" rel = factories.RelationshipFactory.create( from_profile__name='The Teacher', from_profile__role='role', description='desc', ) post = factories.PostFactory.create( author=rel.elder, student=rel.student, ) rel.delete() assert serializers.post2dict(post)['role'] == 'role'
def _get_posts(profile, student=None, group=None): """ Return post data for handlebars posts.html template render. Get all posts for given student/group; list them as read/unread by given ``profile``. """ all_unread = set() if student: all_unread = model.unread.all_unread(student, profile) queryset = student.posts_in_village.select_related( 'author__user', 'student', 'relationship').prefetch_related( 'attachments') elif group: if group.is_all: queryset = profile.authored_bulkposts.filter( group=None).select_related('author__user') else: queryset = group.bulk_posts.select_related('author__user') else: queryset = None post_data = [] count = 0 if queryset is not None: count = queryset.count() post_data = [ serializers.post2dict( post, unread=str(post.id) in all_unread, mine=post.author == profile, ) for post in reversed( queryset.order_by( '-timestamp')[:BACKLOG_POSTS]) ] return { 'objects': post_data, 'meta': { 'total_count': count, 'limit': BACKLOG_POSTS, 'more': count > BACKLOG_POSTS, }, }
def test_post2dict(db): """post2dict returns dictionary of post data.""" rel = factories.RelationshipFactory.create( from_profile__name='The Teacher', description='desc') post = factories.PostFactory.create( author=rel.elder, student=rel.student, relationship=rel, timestamp=datetime.datetime(2012, 9, 17, 5, 30, tzinfo=timezone.utc), html_text='Foo', ) assert serializers.post2dict(post, extra="extra") == { 'post_id': post.id, 'type': { 'name': 'message', 'is_message': True, 'is_note': False, 'is_meeting': False, 'is_call': False, }, 'author_id': rel.elder.id, 'student_id': rel.student.id, 'author': 'The Teacher', 'role': u'desc', 'school_staff': False, 'timestamp': '2012-09-17T05:30:00+00:00', 'timestamp_display': u'Sep 17 2012, 5:30am', 'text': 'Foo', 'extra': 'extra', 'sms': False, 'to_sms': False, 'from_sms': False, 'sms_recipients': [], 'present': [], 'attachments': [], }
def serialize_post(post, **extra): """Transform ``Post`` instance into its serialized representation.""" extra['plain_text'] = post.original_text extra['original_timestamp'] = post.timestamp return serializers.post2dict(post, **extra)
def full_dehydrate(self, bundle): bundle.data.update(serializers.post2dict(bundle.obj)) bundle.data['mine'] = bundle.obj.author == bundle.request.user.profile return bundle
def create_post(request, student_id=None, group_id=None): """ Create a post. If ``student_id`` is provided in the URL, the post will be a single-village post. If ``group_id`` is provided, it will be a group bulk post. If neither is provided, it will be an all-students bulk post. POST parameters accepted: ``text`` The text of the post to create. Must be few enough characters that, when the user's auto-signature is appended, the resulting full SMS message is <160 characters. ``type`` The type of post to create: "message", "note", "call", or "meeting". This parameter is ignored for bulk posts; all bulk posts are of type "message". ``elder`` A list of elder IDs connected with this post. For a "message" type post, these users will receive the post via SMS. For a "meeting" or "call" type post, these are the users who were present on the call or at the meeting. ``extra_name`` A list of additional names connected with this post. (For instance, for a "meeting" or "call" type post, these are names of additional people present at the meeting or on the call, who are not actually elders in the village.) ``author_sequence_id`` An increasing numeric ID for posts authored by this user in this browser session. This value is opaque to the server and not stored anywhere, but is round-tripped through Pusher back to the client, to simplify matching up post data and avoid creating duplicates on the client. For non-bulk posts, an ``attachment`` file-upload parameter is also optionally accepted. Returns JSON object with boolean key ``success``. If ``success`` is ``False``, a human-readable message will be provided in the ``error`` key. If ``success`` is ``True``, the ``objects`` key will be a list containing one JSON-serialized post object. (Even though this view will only ever return one post, it still returns a list for better compatibility with other client-side JSON-handling code.) """ if 'text' not in request.POST: return http.HttpResponseBadRequest( json.dumps( { 'error': "Must provide a 'text' querystring parameter.", 'success': False, } ), content_type='application/json', ) extra_kwargs = {} group = None rel = None post_model = model.BulkPost profile_ids = 'all' if student_id is not None: rel = get_relationship_or_404(student_id, request.user.profile) post_model = model.Post target = rel.student profile_ids = request.POST.getlist('elder') extra_kwargs['extra_names'] = request.POST.getlist('extra_name') extra_kwargs['post_type'] = request.POST.get('type') if 'attachment' in request.FILES: extra_kwargs['attachments'] = request.FILES.getlist('attachment') redirect_url = reverse('village', kwargs={'student_id': student_id}) qs_group = get_querystring_group(request, rel.student) if qs_group: redirect_url += "?group=%s" % qs_group.id elif group_id is not None: group = get_object_or_404( model.Group.objects.filter(owner=request.user.profile), pk=group_id) target = group redirect_url = reverse('group', kwargs={'group_id': group_id}) else: target = None redirect_url = reverse('all_students') text = request.POST['text'] sequence_id = request.POST.get('author_sequence_id') limit = model.post_char_limit(rel or request.user.profile) if len(text) > limit: return http.HttpResponseBadRequest( json.dumps( { 'error': 'Posts are limited to %s characters.' % limit, 'success': False, } ), content_type='application/json', ) with xact.xact(): post = post_model.create( request.user.profile, target, text, profile_ids=profile_ids, sequence_id=sequence_id, **extra_kwargs) if request.is_ajax(): data = { 'success': True, 'objects': [ serializers.post2dict( post, author_sequence_id=sequence_id, unread=False, mine=True) ], } return http.HttpResponse( json.dumps(data), content_type='application/json') else: return http.HttpResponseRedirect(redirect_url)
def test_post2dict_timestamp_display(db, mock_now): """Natural date for a nearby date.""" post = factories.PostFactory.create( timestamp=datetime.datetime(2013, 2, 11, 8, 32, tzinfo=timezone.utc)) assert serializers.post2dict(post)['timestamp_display'] == u"8:32am"