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
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)
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]))
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)
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)