예제 #1
0
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)
예제 #2
0
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)
예제 #3
0
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'] == ""
예제 #4
0
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'] == ""
예제 #5
0
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'
예제 #6
0
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'
예제 #7
0
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,
            },
        }
예제 #8
0
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': [],
    }
예제 #9
0
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': [],
        }
예제 #10
0
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)
예제 #11
0
 def full_dehydrate(self, bundle):
     bundle.data.update(serializers.post2dict(bundle.obj))
     bundle.data['mine'] = bundle.obj.author == bundle.request.user.profile
     return bundle
예제 #12
0
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)
예제 #13
0
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"
예제 #14
0
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)
예제 #15
0
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"
예제 #16
0
 def full_dehydrate(self, bundle):
     bundle.data.update(serializers.post2dict(bundle.obj))
     bundle.data['mine'] = bundle.obj.author == bundle.request.user.profile
     return bundle