def _getMessageCard(self, message, search=None): message = odict(message) image = getUserImage(message.user_id) user_icon = div(img(src=image, width='70px', class_='img-thumbnail'), class_='userIcon') username = div(message.author, class_='messageAuthor') reason = div(message.reason, class_='messageReason') date = div(message.created, class_='messageDate') name_link = a(username, href='//%s/profile.py?u=%s' % (self.conf.baseurl, encrypt_int(message.user_id))) username_and_date = div(name_link + reason + date, class_='usernameAndDate') text = urlize(message.text, trim_url_limit=50, nofollow=True, target='_blank') text = self._highlightKeyTerms(text, search) messageLikes = MessageLikes(message) messageComments = MessageComments(message) footer = \ messageLikes.html_widget(self.page.session.user) + \ messageComments.html_widget() # hack need to instantiate m for each mesage: url_previews = '' for preview in Message(message.id).url_previews: preview2 = copy(preview) preview2['thumbnail_width'] = min(preview2['thumbnail_width'], 500) if not preview2['thumbnail_url']: preview2['thumbnail_url'] = '' url_previews += self.url_preview_html.format(**preview2) o = '' o += user_icon + username_and_date o += div(text, class_='messageText') o += url_previews o += div(footer, class_='messageFooter') o += messageLikes.html_likersSection() o += messageComments.html_commentsSection(self.page.session.user, search=search) return div(o, class_='messageCard', id='message_card_%s' % message.id)
def sendSummary(self, user=None): '''Given a User Object, or None for all, Send Summary Email to user(s). ''' sent = failed = 0 # one or all users? users = [user] if user else Users().getUsers('1=1') time_since = datetime.now() - timedelta(NUM_DAYS_BACK) new_posts = self._summary_getNewPosts() total_comments = self._getTotalComments(created_after=time_since) total_likes = self._getTotalLikes(created_after=time_since) for user in users: print 'user:'******'created': format_datetime(p['last_updated']), 'text': ' '.join(p['text'].split(' ')[0:80]), # 80 words 'name': p['author'], 'profile_image': getUserImage(p['user_id']), 'message_url': 'http://%s/main.py#message_card_%s' \ % (self.conf.baseurl, p['message_id']) }) html = open('%s/lib/emails/summary.html' %self.conf.basedir).read() html = Template(html) html = html.render(likes=total_likes, comments=total_comments, posts=posts, new_posts=new_posts) try: self.email.send_email(to=user.email, subject='While you were away', body="", html=html) sent += 1 except Exception, e: self.logger.error('Summary Email Failed: %s: %s' % (user.email, e)) failed += 1
def _getUserData(self): '''Return User Data Fields as HTML''' header = h3('Profile') pic_src = getUserImage(self.user.id) image_ = div(img(width='150px', src=pic_src)) if self.user.id == self.session.user.id: file = input(type='file', name='filename', accept='image/*', onchange='upload_form.submit();') action_text = '' if pic_src == 'images/generic_icon.png': action_text = p('Click to upload your <br/>profile photo', id='profile-pic-action-text') browse = div(image_ + action_text + file, id='profile-pic', class_='btn btn-file') image = form(browse, enctype='multipart/form-data', action='', method='post', name='upload_form') else: image = image_ # build data data = [['Name:', self.user.fullname]] if self.user.id == self.session.user.id: data.append(['Email:', self.user.email]) data.append([nobr('Member Since:'), format_date(self.user.created)]) # build html table table = HtmlTable(class_='profileTable') for row in data: row_header = span(row[0], class_='profileRowHeader') value = row[1] table.addRow([row_header, value]) table.setColVAlign(1, 'top') return header + image + table.getTable()
def html_commentsSection(self, user, search=None): comment_cards = [] # get existing comments for comment in self.comments: image = getUserImage(comment['user_id']) user_icon = div(img(src=image, width='30px', class_='img-thumbnail'), class_='userIcon') who = comment['user_fullname'] text = comment['text'] text = urlize(text, target='_blank') if search: for term in search.split(' '): term2 = r'(%s)(?!=)' % term text =re.sub(term2, r'<span class="search-term">\1</span>', text, flags=re.IGNORECASE) time_ago = cal_time_ago(comment['created']) who_link = a(who, href='//%s/profile.py?u=%s' % (self.conf.baseurl, encrypt_int(comment['user_id']))) comment_card = div(span(user_icon) + ' ' + span(who_link, class_='commenter') + ' ' + span(text, class_='comment-text') + ' ' + span(time_ago, class_='comment-time-ago'), class_='comment-card') comment_cards.append(comment_card) # add new comment field: new_comment_card = open('new-comment.html', 'r').read()\ .format(message_id=self.message.id) comment_cards.append(new_comment_card) comment_cards_html = '\n'.join(comment_cards) return div(comment_cards_html, class_='comments', id='comments_%s' % self.message.id)
def sendMessageActivity(self, user=None): '''Given a User Object, or None for all, Send Message Activity Email to user(s) Send notification about Comments on Users message or on comments to messages user has liked or commented on Since the last time run TO DO: Implement dynamtic send interval based on number of likes and comments ''' data = self._getMessageComments(user.id if user else None) for user_id in data.keys(): purge = [] user = User(user_id) print 'Email to:', data[user_id]['email'] posts = [] for message in data[user_id]['messages']: # message data mUser = User(message['message_user_id']) # comments data comments = [] for i, cid in enumerate(message['comment_ids']): cUser = User(Comment(cid).user_id) profile_url = 'http://%s/profile.py?u=%s' % \ (self.conf.baseurl, encrypt_int(cUser.id)) comments.append({'name': cUser.fullname, 'profile_image': getUserImage(cUser.id), 'profile_url': profile_url, 'text': message['comment_texts'][i]}) purge.append([user_id, cid]) # activity message message_url = 'http://%s/main.py#message_card_%s' \ % (self.conf.baseurl, message['id']) post_link = a(b('Post', style='font-size:14px'), href=message_url) orig_post = message['message_text'][0:119] if len(message['message_text']) > 120: orig_post += ' ...' if user_id == mUser.id: who = 'your' else: who = mUser.fullname + "'s" activity_msg = '%s new comment%s on %s %s<p/>%s' % \ (len(comments), 's' if len(comments) > 1 else '', who, post_link, orig_post) posts.append({ 'activity_msg': activity_msg, 'comments': comments, 'message_url': 'http://%s/main.py#message_card_%s' \ % (self.conf.baseurl, message['id']) }) html = open('%s/lib/emails/message_activity.html' % \ self.conf.basedir).read() html = Template(html) html = html.render(posts=posts) self.email.send_email(#to='*****@*****.**', to=user.email, subject='Recent activity', body='', html=html) # purge notify queue for user_id, comment_id in purge: # copy queue recors to queue_log sql = 'insert into notify_queue_log ' \ '(user_id, comment_id, created) ' \ 'select user_id, comment_id, created ' \ 'from notify_queue ' \ 'where user_id = %s and comment_id = %s' self.db.execute(sql, params=(user_id, comment_id)) # delete queue records sql = 'delete from notify_queue ' \ 'where user_id = %s and comment_id = %s' self.db.execute(sql, params=(user_id, comment_id))
class Notifications(object): @lazyproperty def logger(self): return logger.getLogger('Notifications') def __init__(self): self.conf = conf.getInstance() self.db = db.getInstance() self.users = Users() self.messages = Messages() self.email = Emails() def sendMessageActivity(self, user=None): '''Given a User Object, or None for all, Send Message Activity Email to user(s) Send notification about Comments on Users message or on comments to messages user has liked or commented on Since the last time run TO DO: Implement dynamtic send interval based on number of likes and comments ''' data = self._getMessageComments(user.id if user else None) for user_id in data.keys(): purge = [] user = User(user_id) print 'Email to:', data[user_id]['email'] posts = [] for message in data[user_id]['messages']: # message data mUser = User(message['message_user_id']) # comments data comments = [] for i, cid in enumerate(message['comment_ids']): cUser = User(Comment(cid).user_id) profile_url = 'http://%s/profile.py?u=%s' % \ (self.conf.baseurl, encrypt_int(cUser.id)) comments.append({'name': cUser.fullname, 'profile_image': getUserImage(cUser.id), 'profile_url': profile_url, 'text': message['comment_texts'][i]}) purge.append([user_id, cid]) # activity message message_url = 'http://%s/main.py#message_card_%s' \ % (self.conf.baseurl, message['id']) post_link = a(b('Post', style='font-size:14px'), href=message_url) orig_post = message['message_text'][0:119] if len(message['message_text']) > 120: orig_post += ' ...' if user_id == mUser.id: who = 'your' else: who = mUser.fullname + "'s" activity_msg = '%s new comment%s on %s %s<p/>%s' % \ (len(comments), 's' if len(comments) > 1 else '', who, post_link, orig_post) posts.append({ 'activity_msg': activity_msg, 'comments': comments, 'message_url': 'http://%s/main.py#message_card_%s' \ % (self.conf.baseurl, message['id']) }) html = open('%s/lib/emails/message_activity.html' % \ self.conf.basedir).read() html = Template(html) html = html.render(posts=posts) self.email.send_email(#to='*****@*****.**', to=user.email, subject='Recent activity', body='', html=html) # purge notify queue for user_id, comment_id in purge: # copy queue recors to queue_log sql = 'insert into notify_queue_log ' \ '(user_id, comment_id, created) ' \ 'select user_id, comment_id, created ' \ 'from notify_queue ' \ 'where user_id = %s and comment_id = %s' self.db.execute(sql, params=(user_id, comment_id)) # delete queue records sql = 'delete from notify_queue ' \ 'where user_id = %s and comment_id = %s' self.db.execute(sql, params=(user_id, comment_id)) def _getMessageComments(self, user_id): '''Return the following message activity Data structure: {1: # user_id {'email': '*****@*****.**', {'messages': [{id: 806, # message_id 'message_user_id': 1, 'message_text': "I'm very excited about how Stemsible", 'created': <datetime> 'comment_ids: [109, 134] 'comment_texts': ['test comment message', 'another test comment message'] ]} } } ''' data = {} # get sql user_filter = 'u.id = %s' % user_id if user_id else '1=1' sql_file = '%s/lib/sql/new_comments.sql' % self.conf.basedir sql = open(sql_file, 'r').read() % user_filter # loop thru records, tally on user_id change for row in self.db.query(sql): user_id = row['user_id'] user_email = row['user_email'] message_user_id = row['message_user_id'] message_id = row['message_id'] message_text = row['message_text'] comment_ids = row['comment_ids'].split(',') comment_texts = row['comment_texts'].split('^!^!^') if user_id not in data: data[user_id] = {'email': user_email, 'messages': []} data[user_id]['messages'].append( {'id': message_id, 'message_user_id': message_user_id, 'message_text': message_text, 'comment_ids': comment_ids, 'comment_texts': comment_texts }) return data def sendMessageNotification(self, message_id, user=None): '''Given a message_id, and a User Object, or None for all users not including original author, commenters or likers, send a Message Notification Email to user(s) with subject line: "<user.first_name> could use your help answering a question" ''' try: message = Message(message_id) except Exception, e: raise NotificationsError('Message %s not found: %s' % (message_id, e)) if user: users = [user] else: # exclude message author, commenters and likers: exclude = [message.user_id] exclude.extend([c.user_id for c in message.comments]) exclude.extend([l.user_id for l in message.likes]) filter = ("id not in (%s)" % ', '.join([str(x) for x in set(exclude)])) users = self.users.getUsers(filter) print message # mutiple possible subjects: SUBJECT1 = '%s could use your help answering a question' % \ message.user.first_name SUBJECT2 = '%s posted a link that may interest you' % \ message.user.first_name subject = SUBJECT2 profile_url = 'http://%s/profile.py?u=%s' % \ (self.conf.baseurl, encrypt_int(message.user.id)) mdata = {'notification_message': subject + '.', 'name': message.user.fullname, 'created': format_datetime(message.created), 'text': message.text, 'message_url': 'http://%s/main.py#message_card_%s' \ % (self.conf.baseurl, message.id), 'profile_image': getUserImage(message.user.id), 'profile_url': profile_url, } html = open('%s/lib/emails/message_notification.html' % \ self.conf.basedir).read() html = Template(html) html = html.render(mdata=mdata) for user in users: print 'email: %s' % (user.email) self.email.send_email(#to='*****@*****.**', to=user.email, subject=subject, body='', html=html)