Esempio n. 1
0
    def get(self, request, group_id, format=None):
        """List all group discussions. Only group members can perform this op.
        """
        # 1 <= page, defaults to 1
        try:
            page = int(request.GET.get('page', '1'))
        except ValueError:
            page = 1
        if page < 0:
            page = 1

        # 1 <= per_page <= 100, defaults to 20
        try:
            per_page = int(request.GET.get('per_page', '20'))
        except ValueError:
            per_page = 20
        if per_page < 1 or per_page > 100:
            per_page = 20

        paginator = Paginator(
            GroupMessage.objects.filter(
                group_id=group_id).order_by('-timestamp'), per_page)

        try:
            group_msgs = paginator.page(page)
        except (EmptyPage, InvalidPage):
            group_msgs = paginator.page(paginator.num_pages)

        try:
            avatar_size = int(
                request.GET.get('avatar_size', AVATAR_DEFAULT_SIZE))
        except ValueError:
            avatar_size = AVATAR_DEFAULT_SIZE

        msgs = []
        for msg in group_msgs:
            info = get_user_common_info(msg.from_email, avatar_size)
            isoformat_timestr = datetime_to_isoformat_timestr(msg.timestamp)
            msgs.append({
                "id": msg.pk,
                "group_id": group_id,
                "user_name": info["name"],
                "user_email": info["email"],
                "user_contact_email": info["contact_email"],
                "avatar_url": info["avatar_url"],
                "content": msg.message,
                "created_at": isoformat_timestr
            })

        return HttpResponse(json.dumps({
            "msgs": msgs,
            "current_page": page,
            "page_num": paginator.num_pages,
        }),
                            status=200,
                            content_type=json_content_type)
Esempio n. 2
0
    def get(self, request, group_id, format=None):
        """List all group discussions. Only group members can perform this op.
        """
        # 1 <= page, defaults to 1
        try:
            page = int(request.GET.get('page', '1'))
        except ValueError:
            page = 1
        if page < 0:
            page = 1

        # 1 <= per_page <= 100, defaults to 20
        try:
            per_page = int(request.GET.get('per_page', '20'))
        except ValueError:
            per_page = 20
        if per_page < 1 or per_page > 100:
            per_page = 20

        paginator = Paginator(GroupMessage.objects.filter(
            group_id=group_id).order_by('-timestamp'), per_page)

        try:
            group_msgs = paginator.page(page)
        except (EmptyPage, InvalidPage):
            group_msgs = paginator.page(paginator.num_pages)

        try:
            avatar_size = int(request.GET.get('avatar_size',
                    AVATAR_DEFAULT_SIZE))
        except ValueError:
            avatar_size = AVATAR_DEFAULT_SIZE

        msgs = []
        for msg in group_msgs:
            info = get_user_common_info(msg.from_email, avatar_size)
            isoformat_timestr = datetime_to_isoformat_timestr(msg.timestamp)
            msgs.append({
                "id": msg.pk,
                "group_id": group_id,
                "user_name": info["name"],
                "user_email": info["email"],
                "user_contact_email": info["contact_email"],
                "avatar_url": request.build_absolute_uri(info["avatar_url"]),
                "content": msg.message,
                "created_at": isoformat_timestr
            })

        return HttpResponse(json.dumps({
            "msgs": msgs,
            "current_page": page,
            "page_num": paginator.num_pages,
            }), status=200, content_type=json_content_type)
Esempio n. 3
0
def user_msg_list(request, id_or_email):
    """List messages related to a certain person.
    """
    try:
        uid = int(id_or_email)
        try:
            user = User.objects.get(id=uid)
        except User.DoesNotExist:
            user = None
        if not user:
            return render_to_response("user_404.html",{},
                                      context_instance=RequestContext(request))
        to_email = user.email
    except ValueError:
        to_email = id_or_email

    username = request.user.username
    if username == to_email:
        return HttpResponseRedirect(reverse('edit_profile'))

    msgs = UserMessage.objects.get_messages_between_users(username, to_email)
    if msgs:
        # update ``ifread`` field of messages
        UserMessage.objects.update_unread_messages(to_email, username)

    '''paginate'''
    paginator = Paginator(msgs, 15)
    # Make sure page request is an int. If not, deliver first page.
    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1

    # If page request (9999) is out of range, deliver last page of results.
    try:
        person_msgs = paginator.page(page)
    except (EmptyPage, InvalidPage):
        person_msgs = paginator.page(paginator.num_pages)
    person_msgs.page_range = paginator.get_page_range(person_msgs.number)
    person_msgs.object_list = list(person_msgs.object_list)

    c = Contact.objects.get_contact_by_user(username, to_email)
    add_to_contacts = True if c is None else False

    return render_to_response("message/user_msg_list.html", {
            "person_msgs": person_msgs,
            "to_email": to_email,
            "add_to_contacts": add_to_contacts,
            }, context_instance=RequestContext(request))
Esempio n. 4
0
def get_person_msgs(to_email, page, username):

    # Show 15 group messages per page.
    paginator = Paginator(UserMessage.objects.get_messages_between_users(username, to_email).order_by('-timestamp'), 15)

    # If page request (9999) is out of range, return None
    try:
        person_msgs = paginator.page(page)
    except (EmptyPage, InvalidPage):
        return None

    # Force evaluate queryset to fix some database error for mysql.
    person_msgs.object_list = list(person_msgs.object_list)
    attachments = UserMsgAttachment.objects.list_attachments_by_user_msgs(person_msgs.object_list)

    for msg in person_msgs.object_list:
        msg.attachments = []
        for att in attachments:
            if att.user_msg != msg:
                continue

            pfds = att.priv_file_dir_share
            if pfds is None: # in case that this attachment is unshared.
                continue

            att.repo_id = pfds.repo_id
            att.path = pfds.path
            att.name = os.path.basename(pfds.path.rstrip('/'))
            att.token = pfds.token
            msg.attachments.append(att)

    return person_msgs
Esempio n. 5
0
def get_group_msgs(groupid, page, username):

    # Show 15 group messages per page.
    paginator = Paginator(GroupMessage.objects.filter(group_id=groupid).order_by("-timestamp"), 15)

    # If page request (9999) is out of range, return None
    try:
        group_msgs = paginator.page(page)
    except (EmptyPage, InvalidPage):
        return None

    # Force evaluate queryset to fix some database error for mysql.
    group_msgs.object_list = list(group_msgs.object_list)

    attachments = MessageAttachment.objects.filter(group_message__in=group_msgs.object_list)

    msg_replies = MessageReply.objects.filter(reply_to__in=group_msgs.object_list)
    reply_to_list = [r.reply_to_id for r in msg_replies]

    for msg in group_msgs.object_list:
        msg.reply_cnt = reply_to_list.count(msg.id)
        msg.replies = []
        for r in msg_replies:
            if msg.id == r.reply_to_id:
                msg.replies.append(r)
        msg.replies = msg.replies[-3:]

        for att in attachments:
            if att.group_message_id != msg.id:
                continue

            # Attachment name is file name or directory name.
            # If is top directory, use repo name instead.
            path = att.path
            if path == "/":
                repo = seafile_api.get_repo(att.repo_id)
                if not repo:
                    # TODO: what should we do here, tell user the repo
                    # is no longer exists?
                    continue
                att.name = repo.name
            else:
                path = path.rstrip("/")  # cut out last '/' if possible
                att.name = os.path.basename(path)

            # Load to discuss page if attachment is a image and from recommend.
            if att.attach_type == "file" and att.src == "recommend":
                att.filetype, att.fileext = get_file_type_and_ext(att.name)
                if att.filetype == IMAGE:
                    att.obj_id = seafile_api.get_file_id_by_path(att.repo_id, path)
                    if not att.obj_id:
                        att.err = "File does not exist"
                    else:
                        att.token = seafile_api.get_fileserver_access_token(att.repo_id, att.obj_id, "view", username)
                        att.img_url = gen_file_get_url(att.token, att.name)

            msg.attachment = att

    return group_msgs
Esempio n. 6
0
    def get(self, request, group_id, format=None):
        """List all group discussions. Only group members can perform this op.
        """
        # 1 <= page, defaults to 1
        try:
            page = int(request.GET.get('page', '1'))
        except ValueError:
            page = 1
        if page < 0:
            page = 1

        # 1 <= per_page <= 100, defaults to 20
        try:
            per_page = int(request.GET.get('per_page', '20'))
        except ValueError:
            per_page = 20
        if per_page < 1 or per_page > 100:
            per_page = 20

        paginator = Paginator(GroupMessage.objects.filter(
            group_id=group_id).order_by('-timestamp'), per_page)

        try:
            group_msgs = paginator.page(page)
        except (EmptyPage, InvalidPage):
            group_msgs = paginator.page(paginator.num_pages)

        msgs = []
        for e in group_msgs:
            msgs.append({
                "group_id": group_id,
                "discussion_id": e.pk,
                "user": e.from_email,
                "content": e.message,
                "created_at": e.timestamp.strftime("%Y-%m-%dT%H:%M:%S") + DateFormat(e.timestamp).format('O'),
            })

        return HttpResponse(json.dumps(msgs), status=200,
                            content_type=json_content_type)
Esempio n. 7
0
def get_group_msgs_json(groupid, page, username):
    # Show 15 group messages per page.
    paginator = Paginator(GroupMessage.objects.filter(group_id=groupid).order_by("-timestamp"), 15)

    # If page request (9999) is out of range, return None
    try:
        group_msgs = paginator.page(page)
    except (EmptyPage, InvalidPage):
        return None, -1

    if group_msgs.has_next():
        next_page = group_msgs.next_page_number()
    else:
        next_page = -1

    group_msgs.object_list = list(group_msgs.object_list)
    msgs = [group_msg_to_json(msg, True) for msg in group_msgs.object_list]
    return msgs, next_page
Esempio n. 8
0
def get_group_msgs_json(groupid, page, username):
    # Show 15 group messages per page.
    paginator = Paginator(GroupMessage.objects.filter(
            group_id=groupid).order_by('-timestamp'), 15)

    # If page request (9999) is out of range, return None
    try:
        group_msgs = paginator.page(page)
    except (EmptyPage, InvalidPage):
        return None, -1

    if group_msgs.has_next():
        next_page = group_msgs.next_page_number()
    else:
        next_page = -1

    group_msgs.object_list = list(group_msgs.object_list)
    msgs = [ group_msg_to_json(msg, True) for msg in group_msgs.object_list ]
    return msgs, next_page
Esempio n. 9
0
def get_group_msgs(groupid, page, username):

    # Show 15 group messages per page.
    paginator = Paginator(GroupMessage.objects.filter(
            group_id=groupid).order_by('-timestamp'), 15)

    # If page request (9999) is out of range, return None
    try:
        group_msgs = paginator.page(page)
    except (EmptyPage, InvalidPage):
        return None

    # Force evaluate queryset to fix some database error for mysql.
    group_msgs.object_list = list(group_msgs.object_list)

    attachments = MessageAttachment.objects.filter(group_message__in=group_msgs.object_list)

    msg_replies = MessageReply.objects.filter(reply_to__in=group_msgs.object_list)
    reply_to_list = [ r.reply_to_id for r in msg_replies ]

    for msg in group_msgs.object_list:
        msg.reply_cnt = reply_to_list.count(msg.id)
        msg.replies = []
        for r in msg_replies:
            if msg.id == r.reply_to_id:
                msg.replies.append(r)
        msg.replies = msg.replies[-3:]

        for att in attachments:
            if att.group_message_id != msg.id:
                continue

            # Attachment name is file name or directory name.
            # If is top directory, use repo name instead.
            path = att.path
            if path == '/':
                repo = seafile_api.get_repo(att.repo_id)
                if not repo:
                    # TODO: what should we do here, tell user the repo
                    # is no longer exists?
                    continue
                att.name = repo.name
            else:
                path = path.rstrip('/') # cut out last '/' if possible
                att.name = os.path.basename(path)

            # Load to discuss page if attachment is a image and from recommend.
            if att.attach_type == 'file' and att.src == 'recommend':
                att.filetype, att.fileext = get_file_type_and_ext(att.name)
                if att.filetype == IMAGE:
                    att.obj_id = seafile_api.get_file_id_by_path(att.repo_id, path)
                    if not att.obj_id:
                        att.err = 'File does not exist'
                    else:
                        att.token = seafile_api.get_fileserver_access_token(
                            att.repo_id, att.obj_id, 'view', username)
                        att.img_url = gen_file_get_url(att.token, att.name)

            msg.attachment = att

    return group_msgs
Esempio n. 10
0
def user_msg_list(request, id_or_email):
    """List messages related to a certain person.
    """
    try:
        uid = int(id_or_email)
        try:
            user = User.objects.get(id=uid)
        except User.DoesNotExist:
            user = None
        if not user:
            return render_to_response("user_404.html",{},
                                      context_instance=RequestContext(request))
        to_email = user.email
    except ValueError:
        to_email = id_or_email

    username = request.user.username
    if username == to_email:
        return HttpResponseRedirect(reverse('edit_profile'))

    msgs = UserMessage.objects.get_messages_between_users(username, to_email)
    if msgs:
        # update ``ifread`` field of messages
        UserMessage.objects.update_unread_messages(to_email, username)

        attachments = UserMsgAttachment.objects.list_attachments_by_user_msgs(msgs)
        for msg in msgs:
            msg.attachments = []
            for att in attachments:
                if att.user_msg != msg:
                    continue

                pfds = att.priv_file_dir_share
                if pfds is None: # in case that this attachment is unshared.
                    continue

                att.repo_id = pfds.repo_id
                att.path = pfds.path
                att.name = os.path.basename(pfds.path.rstrip('/'))
                att.token = pfds.token
                msg.attachments.append(att) 

    '''paginate'''
    paginator = Paginator(msgs, 15)
    # Make sure page request is an int. If not, deliver first page.
    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1

    # If page request (9999) is out of range, deliver last page of results.
    try:
        person_msgs = paginator.page(page)
    except (EmptyPage, InvalidPage):
        person_msgs = paginator.page(paginator.num_pages)
    person_msgs.page_range = paginator.get_page_range(person_msgs.number)
    person_msgs.object_list = list(person_msgs.object_list)

    return render_to_response("message/user_msg_list.html", {
            "person_msgs": person_msgs,
            "to_email": to_email,
            }, context_instance=RequestContext(request))
Esempio n. 11
0
def group_discuss(request, group):
    if group.is_pub:
        raise Http404

    username = request.user.username
    form = MessageForm()

    # remove user notifications
    UserNotification.objects.seen_group_msg_notices(username, group.id)

    # Get all group members.
    members = get_group_members(group.id)

    """group messages"""
    # Show 15 group messages per page.
    paginator = Paginator(GroupMessage.objects.filter(group_id=group.id).order_by("-timestamp"), 15)

    # Make sure page request is an int. If not, deliver first page.
    try:
        page = int(request.GET.get("page", "1"))
    except ValueError:
        page = 1

    # If page request (9999) is out of range, deliver last page of results.
    try:
        group_msgs = paginator.page(page)
    except (EmptyPage, InvalidPage):
        group_msgs = paginator.page(paginator.num_pages)

    group_msgs.page_range = paginator.get_page_range(group_msgs.number)

    # Force evaluate queryset to fix some database error for mysql.
    group_msgs.object_list = list(group_msgs.object_list)

    msg_attachments = MessageAttachment.objects.filter(group_message__in=group_msgs.object_list)

    msg_replies = MessageReply.objects.filter(reply_to__in=group_msgs.object_list)
    reply_to_list = [r.reply_to_id for r in msg_replies]

    for msg in group_msgs.object_list:
        msg.reply_cnt = reply_to_list.count(msg.id)
        msg.replies = []
        for r in msg_replies:
            if msg.id == r.reply_to_id:
                msg.replies.append(r)
        msg.replies = msg.replies[-3:]

        msg.attachments = []
        for att in msg_attachments:
            if att.group_message_id != msg.id:
                continue

            # Attachment name is file name or directory name.
            # If is top directory, use repo name instead.
            path = att.path
            if path == "/":
                repo = get_repo(att.repo_id)
                if not repo:
                    # TODO: what should we do here, tell user the repo
                    # is no longer exists?
                    continue
                att.name = repo.name
            else:
                path = path.rstrip("/")  # cut out last '/' if possible
                att.name = os.path.basename(path)

            # Load to discuss page if attachment is a image and from recommend.
            if att.attach_type == "file" and att.src == "recommend":
                att.filetype, att.fileext = get_file_type_and_ext(att.name)
                if att.filetype == IMAGE:
                    att.obj_id = get_file_id_by_path(att.repo_id, path)
                    if not att.obj_id:
                        att.err = _(u"File does not exist")
                    else:
                        att.token = seafile_api.get_fileserver_access_token(att.repo_id, att.obj_id, "view", username)
                        att.img_url = gen_file_get_url(att.token, att.name)

            msg.attachments.append(att)

    # get available modules(wiki, etc)
    mods_available = get_available_mods_by_group(group.id)
    mods_enabled = get_enabled_mods_by_group(group.id)

    return render_to_response(
        "group/group_discuss.html",
        {
            "group": group,
            "is_staff": group.is_staff,
            "group_msgs": group_msgs,
            "form": form,
            "mods_enabled": mods_enabled,
            "mods_available": mods_available,
        },
        context_instance=RequestContext(request),
    )
Esempio n. 12
0
def group_discuss(request, group):
    if group.is_pub:
        raise Http404

    username = request.user.username
    form = MessageForm()

    # remove user notifications
    UserNotification.objects.seen_group_msg_notices(username, group.id)

    # Get all group members.
    members = get_group_members(group.id)

    """group messages"""
    # Show 15 group messages per page.
    paginator = Paginator(GroupMessage.objects.filter(
            group_id=group.id).order_by('-timestamp'), 15)

    # Make sure page request is an int. If not, deliver first page.
    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1

    # If page request (9999) is out of range, deliver last page of results.
    try:
        group_msgs = paginator.page(page)
    except (EmptyPage, InvalidPage):
        group_msgs = paginator.page(paginator.num_pages)

    group_msgs.page_range = paginator.get_page_range(group_msgs.number)

    # Force evaluate queryset to fix some database error for mysql.
    group_msgs.object_list = list(group_msgs.object_list)

    msg_attachments = MessageAttachment.objects.filter(group_message__in=group_msgs.object_list)

    msg_replies = MessageReply.objects.filter(reply_to__in=group_msgs.object_list)
    reply_to_list = [ r.reply_to_id for r in msg_replies ]

    for msg in group_msgs.object_list:
        msg.reply_cnt = reply_to_list.count(msg.id)
        msg.replies = []
        for r in msg_replies:
            if msg.id == r.reply_to_id:
                msg.replies.append(r)
        msg.replies = msg.replies[-3:]

        msg.attachments = []
        for att in msg_attachments:
            if att.group_message_id != msg.id:
                continue

            # Attachment name is file name or directory name.
            # If is top directory, use repo name instead.
            path = att.path
            if path == '/':
                repo = get_repo(att.repo_id)
                if not repo:
                    # TODO: what should we do here, tell user the repo
                    # is no longer exists?
                    continue
                att.name = repo.name
            else:
                path = path.rstrip('/') # cut out last '/' if possible
                att.name = os.path.basename(path)

            # Load to discuss page if attachment is a image and from recommend.
            if att.attach_type == 'file' and att.src == 'recommend':
                att.filetype, att.fileext = get_file_type_and_ext(att.name)
                if att.filetype == IMAGE:
                    att.obj_id = get_file_id_by_path(att.repo_id, path)
                    if not att.obj_id:
                        att.err = _(u'File does not exist')
                    else:
                        att.token = seafile_api.get_fileserver_access_token(
                            att.repo_id, att.obj_id, 'view', username)
                        att.img_url = gen_file_get_url(att.token, att.name)

            msg.attachments.append(att)

    # get available modules(wiki, etc)
    mods_available = get_available_mods_by_group(group.id)
    mods_enabled = get_enabled_mods_by_group(group.id)

    return render_to_response("group/group_discuss.html", {
            "group" : group,
            "is_staff": group.is_staff,
            "group_msgs": group_msgs,
            "form": form,
            "mods_enabled": mods_enabled,
            "mods_available": mods_available,
            }, context_instance=RequestContext(request))
Esempio n. 13
0
def user_msg_list(request, id_or_email):
    """List messages related to a certain person.
    """
    try:
        uid = int(id_or_email)
        try:
            user = User.objects.get(id=uid)
        except User.DoesNotExist:
            user = None
        if not user:
            return render_to_response("user_404.html", {},
                                      context_instance=RequestContext(request))
        to_email = user.email
    except ValueError:
        to_email = id_or_email

    username = request.user.username
    if username == to_email:
        return HttpResponseRedirect(reverse('edit_profile'))

    msgs = UserMessage.objects.get_messages_between_users(username, to_email)
    if msgs:
        # update ``ifread`` field of messages
        UserMessage.objects.update_unread_messages(to_email, username)

        attachments = UserMsgAttachment.objects.list_attachments_by_user_msgs(
            msgs)
        for msg in msgs:
            msg.attachments = []
            for att in attachments:
                if att.user_msg != msg:
                    continue

                pfds = att.priv_file_dir_share
                if pfds is None:  # in case that this attachment is unshared.
                    continue

                att.repo_id = pfds.repo_id
                att.path = pfds.path
                att.name = os.path.basename(pfds.path.rstrip('/'))
                att.token = pfds.token
                msg.attachments.append(att)
    '''paginate'''
    paginator = Paginator(msgs, 15)
    # Make sure page request is an int. If not, deliver first page.
    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1

    # If page request (9999) is out of range, deliver last page of results.
    try:
        person_msgs = paginator.page(page)
    except (EmptyPage, InvalidPage):
        person_msgs = paginator.page(paginator.num_pages)
    person_msgs.page_range = paginator.get_page_range(person_msgs.number)
    person_msgs.object_list = list(person_msgs.object_list)

    return render_to_response("message/user_msg_list.html", {
        "person_msgs": person_msgs,
        "to_email": to_email,
    },
                              context_instance=RequestContext(request))
Esempio n. 14
0
def group_discuss(request, group_id):
    if request.method == 'POST':
        form = MessageForm(request.POST)

        if form.is_valid():
            msg = form.cleaned_data['message']
            message = GroupMessage()
            message.group_id = group_id
            message.from_email = request.user.username
            message.message = msg
            message.save()

            # send signal
            grpmsg_added.send(sender=GroupMessage, group_id=group_id,
                              from_email=request.user.username)
            # Always return an HttpResponseRedirect after successfully dealing
            # with POST data.
            return HttpResponseRedirect(reverse('group_discuss', args=[group_id]))
    else:
        form = MessageForm()
        
        op = request.GET.get('op', '')
        if op == 'delete':
            return group_remove(request, group_id)
        elif op == 'dismiss':
            return group_dismiss(request, group_id)
        elif op == 'quit':
            return group_quit(request, group_id)

    group_id_int = int(group_id) # Checkeb by URL Conf

    # remove user notifications
    UserNotification.objects.filter(to_user=request.user.username,
                                    msg_type='group_msg',
                                    detail=str(group_id)).delete()
    
    group = get_group(group_id_int)
    if not group:
        return HttpResponseRedirect(reverse('group_list', args=[]))
    
    # Check whether user belongs to the group.
    joined = is_group_user(group_id_int, request.user.username)
    if not joined and not request.user.is_staff:
        # Return group public info page.
        return render_to_response('group/group_pubinfo.html', {
                'members': members,
                'group': group,
                }, context_instance=RequestContext(request))

    # Get all group members.
    members = get_group_members(group_id_int)
    is_staff = True if check_group_staff(group.id, request.user) else False
        
    """group messages"""
    # Show 15 group messages per page.
    paginator = Paginator(GroupMessage.objects.filter(
            group_id=group_id).order_by('-timestamp'), 15)

    # Make sure page request is an int. If not, deliver first page.
    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1

    # If page request (9999) is out of range, deliver last page of results.
    try:
        group_msgs = paginator.page(page)
    except (EmptyPage, InvalidPage):
        group_msgs = paginator.page(paginator.num_pages)

    group_msgs.page_range = paginator.get_page_range(group_msgs.number)

    # Force evaluate queryset to fix some database error for mysql.        
    group_msgs.object_list = list(group_msgs.object_list) 

    attachments = MessageAttachment.objects.filter(group_message__in=group_msgs.object_list)

    msg_replies = MessageReply.objects.filter(reply_to__in=group_msgs.object_list)
    reply_to_list = [ r.reply_to_id for r in msg_replies ]
    
    for msg in group_msgs.object_list:
        msg.reply_cnt = reply_to_list.count(msg.id)
        msg.replies = []
        for r in msg_replies:
            if msg.id == r.reply_to_id:
                msg.replies.append(r)
        msg.replies = msg.replies[-3:]
            
        for att in attachments:
            if msg.id == att.group_message_id:
                # Attachment name is file name or directory name.
                # If is top directory, use repo name instead.
                path = att.path
                if path == '/':
                    repo = get_repo(att.repo_id)
                    if not repo:
                        # TODO: what should we do here, tell user the repo
                        # is no longer exists?
                        continue
                    att.name = repo.name
                else:
                    # cut out last '/'
                    if path[-1] == '/':
                        path = path[:-1]
                    att.name = os.path.basename(path)
                msg.attachment = att

    return render_to_response("group/group_discuss.html", {
            "members": members,
            "group_id": group_id,
            "group" : group,
            "is_staff": is_staff,
            "group_msgs": group_msgs,
            "form": form,
            'group_members_default_display': GROUP_MEMBERS_DEFAULT_DISPLAY,
            }, context_instance=RequestContext(request));