def render(self, parts, value, toOwner=False, getTitle=True, getBody=True, data=None): convId, convType, convOwnerId, notifyType = parts if convType == "question": templates = self._toOthers_A if not toOwner else self._toOwner_A else: templates = self._toOthers_C if not toOwner else self._toOwner_C title, body, html = '', '', '' senderName = data['me'].basic['name'] convOwnerName = data['entities'][convOwnerId].basic['name'] if getTitle: title = templates[0] % locals() if getBody: senderAvatarUrl = utils.userAvatar(data['myId'], data['me'], "medium") convUrl = "%s/item?id=%s" % (rootUrl, convId) comment = data.get('comment', '') body = templates[1] % locals() if 'richComment' in data: comment = data['richComment'] vals = locals().copy() del vals['self'] html = t.getBlock("emails.mako", templates[2], **vals) return (title, body, html)
def _comment(self, request, data=None): authInfo = request.getSession(IAuthInfo) myId = authInfo.username orgId = authInfo.organization convId, conv = data['parent'] fids = data['fId'] comment, snippet = data['comment'] review = data['_review'] itemId, convId, items, keywords = yield Item._comment(convId, conv, comment, snippet, myId, orgId, False, review, fids) if keywords: block = t.getBlock('item.mako', 'requireReviewDlg', keywords=keywords, convId=convId) request.write('$$.convs.reviewRequired(%s, "%s");' % (json.dumps(block), convId)) return # Finally, update the UI entities = base.EntitySet([myId]) yield entities.fetchData() args = {"entities": entities, "items": items, "me": entities[myId]} numShowing = utils.getRequestArg(request, "nc") or "0" numShowing = int(numShowing) + 1 responseCount = items[convId]['meta']['responseCount'] isItemView = (utils.getRequestArg(request, "_pg") == "/item") t.renderScriptBlock(request, 'item.mako', 'conv_comments_head', False, '#comments-header-%s' % (convId), 'set', args=[convId, responseCount, numShowing, isItemView], **args) onload = """(function(){$('.comment-input', '#comment-form-%s').val(''); $('[name=\"nc\"]', '#comment-form-%s').val('%s');})();$('#comment-attach-%s-uploaded').empty()""" % (convId, convId, numShowing, convId) t.renderScriptBlock(request, 'item.mako', 'conv_comment', False, '#comments-%s' % convId, 'append', True, handlers={"onload": onload}, args=[convId, itemId], **args)
def _sendSignupInvitation(emailId): if len(emailId.split('@')) != 2: raise InvalidEmailId() mailId, domain = emailId.split('@') if domain in blacklist: raise DomainBlacklisted() rootUrl = config.get('General', 'URL') brandName = config.get('Branding', 'Name') signature = "Flocked-in Team.\n\n\n\n" myOrgId = yield getOrgId(domain) if myOrgId: entities = yield db.get_slice(myOrgId, "entities", ["basic"]) myOrg = utils.supercolumnsToDict(entities) orgName = myOrg['basic']['name'] else: orgName = domain existing = yield db.get_slice(emailId, "userAuth", ["user"]) existing = utils.columnsToDict(existing) if existing and existing.get('user', ''): subject = "[%s] Account exists" % (brandName) body = "You already have an account on %(brandName)s.\n"\ "Please visit %(rootUrl)s/signin to sign-in.\n\n" textBody = (body + signature) % locals() htmlBody = t.getBlock("emails.mako", "accountExists", **locals()) else: subject = "Welcome to %s" % (brandName) body = "Please click the following link to join %(orgName)s network on %(brandName)s\n"\ "%(activationUrl)s\n\n" activationTmpl = "%(rootUrl)s/signup?email=%(emailId)s&token=%(token)s" token = utils.getRandomKey() insert_d = db.insert(domain, "invitations", emailId, token, emailId) activationUrl = activationTmpl % locals() textBody = (body + signature) % locals() htmlBody = t.getBlock("emails.mako", "signup", **locals()) yield insert_d yield utils.sendmail(emailId, subject, textBody, htmlBody)
def _new(self, request, data=None): (appchange, script, args, myId) = yield self._getBasicArgs(request) me = args['me'] landing = not self._ajax authInfo = request.getSession(IAuthInfo) convType = data['type'] convId, conv, keywords = yield Item.new(request, authInfo, convType) if keywords: block = t.getBlock('item.mako', 'requireReviewDlg', keywords=keywords) request.write('$$.convs.reviewRequired(%s);' % json.dumps(block)) return target = conv['meta'].get('target', None) toFetchEntities = set() if target: toFetchEntities.update(target.split(',')) convType = utils.getRequestArg(request, "type") plugin = plugins[convType] entityIds = yield plugin.fetchData(args, convId) toFetchEntities.update(entityIds) entities = base.EntitySet(toFetchEntities) yield entities.fetchData() entities.update(args['me']) relation = Relation(myId, []) yield relation.initGroupsList() data = {"items": {convId: conv}, "relations": relation, "entities": entities, "script": True} args.update(data) onload = "(function(obj){$$.convs.load(obj);$('#sharebar-attach-uploaded').empty();})(this);" t.renderScriptBlock(request, "item.mako", "item_layout", False, "#user-feed", "prepend", args=[convId, 'conv-item-created'], handlers={"onload": onload}, **args) defaultType = plugins.keys()[0] plugins[defaultType].renderShareBlock(request, True) if plugin and hasattr(plugin, 'renderFeedSideBlock'): entityId = myId referer = request.getHeader('referer') matchObj = feedPathObj.search(referer) if matchObj: matchedStr = matchObj.group('entityId') if matchedStr != "": entityId = matchedStr else: if target: entityId = target.split(',')[0] args["groupId"] = target.split(',')[0] request.write("$('#feed-side-block-container').empty();") yield plugin.renderFeedSideBlock(request, landing, entityId, args)
def _render(self, parts, value, getTitle, getBody, data, args): args.update({'brandName': brandName, 'rootUrl': rootUrl}) if getTitle: title = self._template[0] % args if getBody: args['senderAvatarUrl'] = utils.userAvatar(value, data['entities'][value], "medium") args['senderId'] = value args['senderName'] = data['entities'][value].basic['name'] body = self._template[1] % args html = t.getBlock("emails.mako", self._template[2], **args) return (title, body, html)
def _sendmailResetPassword(email, token): rootUrl = config.get('General', 'URL') brandName = config.get('Branding', 'Name') body = "A request was received to reset the password "\ "for %(email)s on %(brandName)s.\nTo change the password please click the following "\ "link, or paste it in your browser.\n\n%(resetPasswdUrl)s\n\n"\ "This link is valid for 24hours only.\n"\ "If you did not request this email there is no need for further action\n" resetPasswdUrl = "%(rootUrl)s/password/resetPassword?email=%(email)s&token=%(token)s" % (locals()) args = {"brandName": brandName, "rootUrl": rootUrl, "resetPasswdUrl": resetPasswdUrl, "email": email} subject = "[%(brandName)s] Reset Password requested for %(email)s" % (locals()) htmlBody = t.getBlock("emails.mako", "forgotPasswd", **args) textBody = body % (locals()) yield utils.sendmail(email, subject, textBody, htmlBody)
def _reportUser(self, request, myId, targetId): entities = base.EntitySet([myId, targetId]) yield entities.fetchData() reportedBy = entities[myId].basic["name"] email = entities[targetId].basic["emailId"] rootUrl = config.get('General', 'URL') brandName = config.get('Branding', 'Name') authinfo = request.getSession(IAuthInfo) amIAdmin = authinfo.isAdmin cols = yield db.get_slice(email, "userAuth", ["reactivateToken", "isFlagged", "isAdmin"]) cols = utils.columnsToDict(cols) if cols.has_key("isAdmin") and not amIAdmin: raise errors.PermissionDenied("Only administrators can flag other \ administrators for verification") if cols.has_key("isFlagged"): token = cols.get("reactivateToken") else: token = utils.getRandomKey() yield db.insert(email, "userAuth", token, 'reactivateToken') yield db.insert(email, "userAuth", "", 'isFlagged') body = "%(reportedBy)s has flagged your account for verification."\ "You can verify your account by clicking on the link below.\n"\ "\n\n%(reactivateUrl)s\n\n" reactivateUrl = "%(rootUrl)s/password/verify?email=%(email)s&token=%(token)s"%(locals()) args = {"brandName": brandName, "rootUrl": rootUrl, "reportedBy":reportedBy, "reactivateUrl": reactivateUrl} subject = "[%(brandName)s] Your profile has been flagged for review" %(locals()) htmlBody = t.getBlock("emails.mako", "reportUser", **args) textBody = body %(locals()) yield utils.sendmail(email, subject, textBody, htmlBody) request.write('$$.alerts.info("%s");' % _('User has been flagged for verification'))
def rootHTML(self, convId, isQuoted, args): if "convId" in args: return t.getBlock("poll.mako", "poll_root", **args) else: return t.getBlock("poll.mako", "poll_root", args=[convId, isQuoted], **args)
def rootHTML(self, convId, isQuoted, args): if "convId" in args: return t.getBlock("item.mako", "render_activity", **args) else: return t.getBlock("item.mako", "render_activity", args=[convId, isQuoted], **args)
def render(self, parts, value, toOwner=False, getTitle=True, getBody=True, data=None): convId, convType, convOwnerId, notifyType = parts convTitle, convLocation, convTime = "", "", "" if "convMeta" in data: convMeta = data["convMeta"] me = data['me'] entities = data['entities'] convTitle = convMeta["event_title"] convLocation = convMeta.get("event_location", "") start = convMeta["event_startTime"] end = convMeta["event_endTime"] owner = convMeta["owner"] ownerName = entities[owner].basic["name"] my_tz = timezone(me.basic['timezone']) owner_tz = timezone(entities[owner].basic['timezone']) utc = pytz.utc startdatetime = datetime.datetime.utcfromtimestamp(float(start)).replace(tzinfo=utc) enddatetime = datetime.datetime.utcfromtimestamp(float(end)).replace(tzinfo=utc) utc_dt = utc.normalize(startdatetime) start_dt = my_tz.normalize(startdatetime.astimezone(my_tz)) end_dt = my_tz.normalize(enddatetime.astimezone(my_tz)) if start_dt.date() == end_dt.date(): sameDay = True else: sameDay = False allDay = True if convMeta.get("event_allDay", "0") == "1" else False if not allDay: event_start_fmt = "%a %b %d, %I:%M %p" else: event_start_fmt = "%a %b %d" event_start = start_dt.strftime(event_start_fmt) if allDay: event_end_fmt = "%a %b %d" elif sameDay: event_end_fmt = "%I:%M %p" else: event_end_fmt = "%a %b %d, %I:%M %p" event_end = end_dt.strftime(event_end_fmt) if not allDay: convTime += event_start if sameDay: convTime += " to %s" % (event_end) else: convTime += " -- %s" % (event_end) else: convTime += event_start if sameDay: convTime += _("All Day") else: convTime += " -- %s" % (event_end) if notifyType == "EI": templates = self._toOthers_EI else: templates = self._toOwner_EA title, body, html = '', '', '' senderName = data['me'].basic['name'] convOwnerName = data['entities'][convOwnerId].basic['name'] if getTitle: title = templates[0] % locals() if getBody: senderAvatarUrl = utils.userAvatar(data['myId'], data['me'], "medium") convUrl = "%s/item?id=%s" % (rootUrl, convId) body = templates[1] % locals() vals = locals().copy() del vals['self'] html = t.getBlock("event.mako", templates[2], **vals) return (title, body, html)
def getNewUserCount(startDate, endDate, count=100, column_count=100, mail_to=''): frm_to = startDate + ' ' + endDate startDate = datetime.datetime.strptime(startDate, dateFormat) endDate = datetime.datetime.strptime(endDate, dateFormat) if endDate <= startDate: log.msg("end-date should be later than start-date") raise Exception("end-date should be later than start-date") startTime = time.mktime(startDate.timetuple()) endTime = time.mktime(endDate.timetuple()) toFetchCount = count +1 toFetchColumnCount = column_count +1 new_domains = [] start = '' stats = {} data = {} while 1: domains = yield db.get_range_slice('domainOrgMap', count=toFetchCount, start=start) for row in domains[:count]: domain = row.key for col in row.columns[:count]: if domain not in data.setdefault(col.column.name, {}).setdefault("domain", []): data[col.column.name]["domain"].append((domain, col.column.timestamp/1e6)) column_timestamp = col.column.timestamp/1000000.0 if column_timestamp < endTime and column_timestamp >= startTime: if domain not in new_domains: new_domains.append(domain) if len(domains) < toFetchCount: break else: start = domains[-1].key stats = {frm_to: {"newDomains":new_domains, "newDomainCount": len(new_domains) }} start = '' new_users = {} usersOrgMap = {} totalNewUsers = 0 totalUsers ={} while 1: users = yield db.get_range_slice('orgUsers', start=start, count=toFetchCount, column_count=toFetchColumnCount) for row in users[:count]: orgId = row.key totalUsers[orgId] = 0 for col in row.columns[:column_count]: userId = col.column.name usersOrgMap[userId] = orgId if userId not in data.setdefault(orgId, {}).setdefault("users", {}): data[orgId]['users'][userId] = {"newItems":0, "items":0} column_timestamp = col.column.timestamp/1000000.0 if column_timestamp < endTime and column_timestamp >= startTime: if col.column.name not in new_users.setdefault(orgId, []): new_users[orgId].append(userId) if column_timestamp < endTime: totalUsers[orgId] +=1 if len(row.columns) == toFetchColumnCount: column_start = row.columns[-1].column.name while 1: _users = yield db.get_range_slice('orgUsers', count=1, start=orgId, column_start=column_start, column_count=toFetchColumnCount) for col in _users[0].columns[:column_count]: userId = col.column.name usersOrgMap[userId] = orgId if userId not in data.setdefault(orgId, {}).setdefault("users", {}): data[orgId]['users'][userId] = {'newItems':0, 'items':0} column_timestamp = col.column.timestamp/1000000.0 if column_timestamp < endTime and column_timestamp >= startTime: if col.column.name not in new_users[orgId]: new_users[orgId].append(userId) if column_timestamp < endTime: totalUsers[orgId] +=1 if len(_users[0].columns) == toFetchColumnCount: column_start = _users[0].columns[-1].column.name else: break totalNewUsers += len(new_users.get(orgId, [])) if len(users) < toFetchCount: break else: start = users[-1].key stats[frm_to]["signups"] = totalNewUsers start = '' while 1: rows = yield db.get_range_slice('userItems', start=start, count=toFetchCount, column_count = toFetchColumnCount) for row in rows[:count]: userId = row.key for col in row.columns[:column_count]: if userId not in usersOrgMap: data['no-org'] = {"users":{userId:{"items": 0, "newItems": 0}}} orgId = 'no-org' else: orgId = usersOrgMap[userId] if userId not in data[orgId]['users'] : data[orgId]['users'] = {'items': 0 , 'newItems': 0} column_timestamp = col.column.timestamp/1000000.0 if column_timestamp < endTime and column_timestamp >= startTime: data[orgId]['users'][userId]['newItems'] += 1 if column_timestamp < endTime: data[orgId]['users'][userId]['items'] += 1 if len(row.columns) == toFetchColumnCount: cstart = row.columns[-1].column.name while 1: userItems = yield db.get_range_slice('userItems', count=1, start=userId, column_start= cstart, column_count= toFetchColumnCount) for col in userItems[0].columns[:column_count]: column_timestamp = col.column.timestamp/1000000.0 if column_timestamp < endTime and column_timestamp >= startTime: data[orgId]['users'][userId]['newItems'] += 1 #if userId in data[orgId]['users'] : if column_timestamp < endTime: data[orgId]['users'][userId]['items'] += 1 if len(userItems[0].columns) == toFetchColumnCount: cstart = userItems[0].columns[-1].column.name else: break if len(rows) < toFetchCount: break else: start = rows[-1].key stats["domain"] = OrderedDict() sortedOrgIds = sorted(data, key=lambda x: data[x]["domain"][0][1]) for orgId in sortedOrgIds: domainName = ",".join([x[0] for x in data[orgId]['domain']]) stats["domain"][domainName] = {} stats["domain"][domainName]["newUsers"] = len(new_users.get(orgId, [])) stats["domain"][domainName]["totalUsers"] = totalUsers.get(orgId, 0) stats["domain"][domainName]["newItems"] = sum([data[orgId]['users'][x]['newItems'] for x in data[orgId].get('users', {})]) stats["domain"][domainName]["items"] = sum([data[orgId]['users'][x]['items'] for x in data[orgId].get('users', {})]) if not mail_to: print pprint.pprint(stats) subject = "Stats: %s to %s" % (startDate.strftime(dateFormat), endDate.strftime(dateFormat)) textPart = repr(stats) rootUrl = config.get('General', 'URL') brandName = config.get('Branding', 'Name') htmlPart = getBlock("emails.mako", "html_stats", **{"stats":stats, "frm_to": frm_to, 'rootUrl': rootUrl, 'brandName': brandName}) for mailId in mail_to: yield utils.sendmail(mailId, subject, textPart, htmlPart)
def _sendInvitations(myOrgUsers, otherOrgUsers, me, myId, myOrg): rootUrl = config.get('General', 'URL') brandName = config.get('Branding', 'Name') senderName = me.basic["name"] senderOrgName = myOrg.basic["name"] senderAvatarUrl = utils.userAvatar(myId, me, "medium") sentUsers = [] blockedUsers = [] existingUsers = [] myOrgSubject = "%s invited you to %s" % (senderName, brandName) myOrgBody = "Hi,\n\n"\ "%(senderName)s has invited you to %(senderOrgName)s network on %(brandName)s.\n"\ "To activate your account please visit: %(activationUrl)s.\n\n" otherOrgSubject = "%s invited you to %s" % (senderName, brandName) otherOrgBody = "Hi,\n\n"\ "%(senderName)s has invited you to try %(brandName)s.\n"\ "To activate your account please visit: %(activationUrl)s.\n\n" signature = "Flocked.in Team.\n\n\n\n"\ "--\n"\ "To block invitations from %(senderName)s visit %(blockSenderUrl)s\n"\ "To block all invitations from %(brandName)s visit %(blockAllUrl)s" blockSenderTmpl = "%(rootUrl)s/signup/blockSender?email=%(emailId)s&token=%(token)s" blockAllTmpl = "%(rootUrl)s/signup/blockAll?email=%(emailId)s&token=%(token)s" activationTmpl = "%(rootUrl)s/signup?email=%(emailId)s&token=%(token)s" # Combine all users. myOrgUsers.extend(otherOrgUsers) # Ensure that the users do not already exist and that the users are # not in the doNotSpam list (for this sender or globally) d1 = db.multiget(myOrgUsers, "userAuth", "user") d2 = db.multiget_slice(myOrgUsers, "doNotSpam", [myId, '*']) existing = yield d1 existing = utils.multiColumnsToDict(existing) doNotSpam = yield d2 doNotSpam = utils.multiColumnsToDict(doNotSpam) deferreds = [] for emailId in myOrgUsers: if emailId in existing and existing[emailId]: existingUsers.append(emailId) continue token = utils.getRandomKey() # Add invitation to the database localpart, domainpart = emailId.split('@') deferreds.append(db.insert(domainpart, "invitations", myId, token, emailId)) deferreds.append(db.insert(myId, "invitationsSent", '', emailId)) # Mail the invitation if everything is ok. if emailId in doNotSpam and doNotSpam[emailId]: blockedUsers.append(emailId) continue activationUrl = activationTmpl % locals() blockAllUrl = blockAllTmpl % locals() blockSenderUrl = blockSenderTmpl % locals() sameOrg = False if emailId in otherOrgUsers else True if not sameOrg: subject = otherOrgSubject textBody = (otherOrgBody + signature) % locals() else: subject = myOrgSubject textBody = (myOrgBody + signature) % locals() # XXX: getBlock blocks the application for disk reads when reading template htmlBody = t.getBlock("emails.mako", "invite", **locals()) deferreds.append(utils.sendmail(emailId, subject, textBody, htmlBody)) sentUsers.append(emailId) yield defer.DeferredList(deferreds) defer.returnValue((sentUsers, blockedUsers, existingUsers))