Esempio n. 1
0
 def _updatePendingGroupRequestCount(ign):
     def _update_count(counts):
         pendingRequestCount = counts['groups'] if counts.get('groups', 0) != 0 else ''
         request.write("$('#pending-group-requests-count').html('%s');" % (pendingRequestCount))
     d01 = utils.render_LatestCounts(request, False, False)
     d01.addCallback(_update_count)
     return d01
Esempio n. 2
0
    def _renderNotifications(self, request):
        (appchange, script, args, myId) = yield self._getBasicArgs(request)
        landing = not self._ajax
        args["menuId"] = "notifications"

        if script and landing:
            t.render(request, "notifications.mako", **args)

        if script and appchange:
            t.renderScriptBlock(request, "notifications.mako", "layout",
                                landing, "#mainbar", "set", **args)

        start = utils.getRequestArg(request, "start") or ''
        fromFetchMore = ((not landing) and (not appchange) and start)
        data = yield self._getNotifications(request)

        latest = yield db.get_slice(myId, "latest", super_column="notifications")
        latest = utils.columnsToDict(latest)
        latestNotifyIds = [x for x in latest.values()]

        if not start:
            yield db.remove(myId, "latest", super_column="notifications")

        args.update(data)
        args['latestNotifyIds'] = latestNotifyIds
        if script:
            if fromFetchMore:
                t.renderScriptBlock(request, "notifications.mako", "content",
                                    landing, "#next-load-wrapper", "replace",
                                    True, handlers={}, **args)
            else:
                t.renderScriptBlock(request, "notifications.mako", "content",
                                    landing, "#notifications", "set", **args)
            yield utils.render_LatestCounts(request, landing)
        else:
            t.render(request, "notifications.mako", **args)
Esempio n. 3
0
    def _actions(self, request):
        """Perform an action on a conversation or a group of conversations.
        Update the UI based on the folder and the view that the user is in.

        Keyword arguments:
        convIds: A list of conversations upon which an action is to be taken.
        filterType: The folder view in which this action was taken.
        trash: A presence of this argument indicates that the action is to
            delete the selected conversations.
        archive: A presence of this argument indicates that the action is to
            archive the selected conversations.
        unread: A presence of this argument indicates that the action is to
            mark the selected conversations as unread.
        inbox: A presence of this argument indicates that the action is to
            move the selected conversations to inbox.
        view: one of [message, messages] indicates whether the user is
            performing action on a single conversation or multiple conversations.
        action: The actual action that the user wants to peform. One of
            ["inbox", "archive", "trash", "read", "unread"]. This is used
            if none of the above are mentioned.

        CF Changes:
        mConvFolders
        mUnreadConversations
        latest
        mAllConversations
        mDeletedConversations

        """
        (appchange, script, args, myId) = yield self._getBasicArgs(request)
        convIds = utils.getRequestArg(request, 'selected', multiValued=True) or []
        filterType = utils.getRequestArg(request, "filterType") or "all"
        trash = utils.getRequestArg(request, "trash") or None
        archive = utils.getRequestArg(request, "archive") or None
        unread = utils.getRequestArg(request, "unread") or None
        inbox = utils.getRequestArg(request, "inbox") or None
        view = utils.getRequestArg(request, "view") or "messages"

        if trash:
            action = "trash"
        elif archive:
            action = "archive"
        elif unread:
            action = "unread"
        elif inbox:
            action = "inbox"
        else:
            action = utils.getRequestArg(request, "action")

        if convIds:
            #Move the conversations based on action and update the CFs.
            if action in self._folders.keys():
                yield self._moveConversation(request, convIds, action)
            elif action == "read":
                #Remove it from unreadIndex and mark it as unread in all other
                # folders
                cols = yield db.multiget_slice(convIds, "mConversations")
                convs = utils.multiSuperColumnsToDict(cols)
                for convId in convs:
                    conv = convs[convId]
                    if not conv:
                        raise errors.InvalidMessage(convId)
                    if myId not in conv.get('participants', {}):
                        raise errors.MessageAccessDenied(convId)
                    timeUUID = conv['meta']['uuid']

                    yield db.remove(myId, "mUnreadConversations", timeUUID)
                    yield db.remove(convId, "mConvFolders", 'mUnreadConversations', myId)
                    yield db.remove(myId, "latest", timeUUID, "messages")

                    cols = yield db.get_slice(convId, "mConvFolders", [myId])
                    cols = utils.supercolumnsToDict(cols)
                    for folder in cols[myId]:
                        if folder in self._folders:
                            folder = self._folders[folder]
                        yield db.insert(myId, folder, "r:%s" % (convId), timeUUID)
                count = yield utils.render_LatestCounts(request)

        #XXX:Actions are not supported in non js mode so this check is unncessary.
        if not self._ajax:
            #Not all actions on message(s) happen over ajax, for them do a redirect
            request.redirect("/messages?type=%s" % filterType)
            request.finish()
        elif self._ajax and len(convIds) > 0:
            #Update the UI based on the actions and folder view.
            #For all actions other than read/unread, since the action won't be
            # available to the user in same view; i.e, archive won't be on
            # archive view, we can simply remove the conv.
            if action in ["inbox", "archive", "trash"]:
                if filterType != "unread":
                    request.write("$('%s').remove();" % ','.join(['#thread-%s' % convId for convId in convIds]))
                if view == "message":
                    reason = _("Message moved to %s" % (action.capitalize()))
                    if action == "archive":
                        reason = _("Message archived")

                    request.write("""$$.fetchUri('/messages?type=%s');$$.alerts.info("%s");""" % (filterType, _(reason)))
            elif action == "unread":
                query_template = """
                              $('#thread-%s').removeClass('row-read').addClass('row-unread');
                              $('#thread-%s .messaging-read-icon').removeClass('messaging-read-icon').addClass('messaging-unread-icon');
                              $('#thread-%s .messaging-unread-icon').attr("title", "Mark this conversation as read");
                              $('#thread-%s .messaging-unread-icon')[0].onclick = function(event) { $.post('/ajax/messages/thread', 'action=read&selected=%s&filterType=%s', null, 'script') };
                              """
                query = "".join([query_template % (convId, convId, convId, convId, convId, filterType) for convId in convIds])

                if view == "message":
                    request.write("""$$.fetchUri('/messages');$$.alerts.info("%s");""" % ("Message marked as unread"))
                else:
                    request.write(query)
            elif action == "read":
                # If we are in unread view, remove the conv else swap the styles
                if filterType != "unread":
                    query_template = """
                                  $('#thread-%s').removeClass('row-unread').addClass('row-read');
                                  $('#thread-%s .messaging-unread-icon').removeClass('messaging-unread-icon').addClass('messaging-read-icon');
                                  $('#thread-%s .messaging-read-icon').attr("title", "Mark this conversation as unread")
                                  $('#thread-%s .messaging-read-icon')[0].onclick = function(event) { $.post('/ajax/messages/thread', 'action=unread&selected=%s&filterType=%s', null, 'script') }
                                  """
                    query = "".join([query_template % (convId, convId, convId, convId, convId, filterType) for convId in convIds])
                    request.write(query)
                else:
                    request.write("$('%s').remove()" % ','.join(['#thread-%s' % convId for convId in convIds]))
Esempio n. 4
0
    def _listConversations(self, request):
        """Renders a time sorted list of coversations in a particular view.

        Keyword Arguments:
        filerType: The folder view which is to rendered. One of ['unread', 'all',
            'archive', 'trash'].
        start: The base64 encoded timeUUID of the starting conversation id of
            the page that needs to be rendered.

        """
        (appchange, script, args, myId) = yield self._getBasicArgs(request)
        landing = not self._ajax
        filterType = utils.getRequestArg(request, 'type')
        folder = self._folders[filterType] if filterType in self._folders else\
                                                         self._folders['inbox']
        start = utils.getRequestArg(request, "start") or ''
        start = utils.decodeKey(start)

        if script and landing:
            t.render(request, "message.mako", **args)

        if appchange and script:
            t.renderScriptBlock(request, "message.mako", "layout",
                                landing, "#mainbar", "set", **args)

        unread = []
        convs = []
        users = set()
        count = 10
        fetchCount = count + 1
        nextPageStart = ''
        prevPageStart = ''

        cols = yield db.get_slice(myId, folder, reverse=True, start=start, count=fetchCount)
        for col in cols:
            x, convId = col.column.value.split(':')
            convs.append(convId)
            if x == 'u':
                unread.append(convId)
        if len(cols) == fetchCount:
            nextPageStart = utils.encodeKey(col.column.name)
            convs = convs[:count]

        ###XXX: try to avoid extra fetch
        cols = yield db.get_slice(myId, folder, count=fetchCount, start=start)
        if cols and len(cols) > 1 and start:
            prevPageStart = utils.encodeKey(cols[-1].column.name)

        cols = yield db.multiget_slice(convs, 'mConversations')
        conversations = utils.multiSuperColumnsToDict(cols)
        m = {}
        for convId in conversations:
            if not conversations[convId]:
                continue
            participants = conversations[convId]['participants'].keys()
            users.update(participants)
            conversations[convId]['people'] = participants
            conversations[convId]['read'] = str(int(convId not in unread))
            messageCount = yield db.get_count(convId, "mConvMessages")
            conversations[convId]['count'] = messageCount
            m[convId] = conversations[convId]

        users = base.EntitySet(users)
        yield users.fetchData()

        args.update({"view": "messages"})
        args.update({"messages": m})
        args.update({"people": users})
        args.update({"mids": convs})
        args.update({"menuId": "messages"})

        args.update({"filterType": filterType or "all"})
        args['nextPageStart'] = nextPageStart
        args['prevPageStart'] = prevPageStart

        if script:
            onload = """
                     $$.menu.selectItem('%s');
                     $('#mainbar .contents').removeClass("has-right");
                     """ % args["menuId"]
            t.renderScriptBlock(request, "message.mako", "render_conversations", landing,
                                ".center-contents", "set", True,
                                handlers={"onload": onload}, **args)
            yield utils.render_LatestCounts(request, landing)
        else:
            t.render(request, "message.mako", **args)
Esempio n. 5
0
    def _renderConversation(self, request):
        """Render a conversation.

        Keyword arguments:
        convId: The id of the conversation that needs to be rendered.

        """
        (appchange, script, args, myId) = yield self._getBasicArgs(request)
        landing = not self._ajax
        convId = utils.getRequestArg(request, 'id', sanitize=False)
        if not convId:
            raise errors.MissingParams([])

        if script and landing:
            t.render(request, "message.mako", **args)

        if appchange and script:
            t.renderScriptBlock(request, "message.mako", "layout",
                                landing, "#mainbar", "set", **args)

        cols = yield db.get_slice(convId, "mConversations")
        conv = utils.supercolumnsToDict(cols)
        participants = set(conv.get('participants', {}).keys())
        if not conv:
            raise errors.InvalidMessage(convId)
        if myId not in participants:
            raise errors.MessageAccessDenied(convId)

        timeUUID = conv['meta']['uuid']
        d1 = db.remove(myId, "mUnreadConversations", timeUUID)
        d2 = db.remove(convId, "mConvFolders", 'mUnreadConversations', myId)
        d3 = db.remove(myId, "latest", timeUUID, "messages")
        deferreds = [d1, d2, d3]
        yield defer.DeferredList(deferreds)
        deferreds = []
        cols = yield db.get_slice(convId, "mConvFolders", [myId])
        cols = utils.supercolumnsToDict(cols)
        for folder in cols[myId]:
            if folder in self._folders:
                folder = self._folders[folder]
            d = db.insert(myId, folder, "r:%s" % (convId), timeUUID)
            deferreds.append(d)

        inFolders = cols[myId].keys()
        #FIX: make sure that there will be an entry of convId in mConvFolders
        cols = yield db.get_slice(convId, "mConvMessages")
        mids = [col.column.value for col in cols]
        messages = yield db.multiget_slice(mids, "messages", ["meta"])
        messages = utils.multiSuperColumnsToDict(messages)

        s = yield defer.DeferredList(deferreds)
        participants.update([messages[mid]['meta']['owner'] for mid in messages])
        people = base.EntitySet(participants)
        yield people.fetchData()

        args.update({"people": people})
        args.update({"conv": conv})
        args.update({"messageIds": mids})
        args.update({'messages': messages})
        args.update({"id": convId})
        args.update({"flags": {}})
        args.update({"view": "message"})
        args.update({"menuId": "messages"})
        args.update({"inFolders": inFolders})

        if script:
            onload = """
                     $$.menu.selectItem("messages");
                     $('#mainbar .contents').addClass("has-right");
                     $('.conversation-reply').autogrow();
                     $('#message-reply-form').html5form({messages: 'en'});
                     """
            t.renderScriptBlock(request, "message.mako", "render_conversation",
                                landing, ".center-contents", "set", True,
                                handlers={"onload": onload}, **args)

            onload = """
                     $$.files.init('msgreply-attach');
                     $('#conversation_add_member').autocomplete({
                           source: '/auto/users',
                           minLength: 2,
                           select: function( event, ui ) {
                               $('#conversation_recipients').attr('value', ui.item.uid)
                           }
                      });
                    """
            t.renderScriptBlock(request, "message.mako", "right",
                                landing, ".right-contents", "set", True,
                                handlers={"onload": onload}, **args)
            yield utils.render_LatestCounts(request, landing)
        else:
            t.render(request, "message.mako", **args)