def test_topics_in_subject_line(self): q1 = models.Question(id=1, tagnames='one two three four five') q2 = models.Question(id=2, tagnames='two three four five') q3 = models.Question(id=3, tagnames='three four five') q4 = models.Question(id=4, tagnames='four five') q5 = models.Question(id=5, tagnames='five') q6 = models.Question(id=6, tagnames='six') q7 = models.Question(id=7, tagnames='six') q8 = models.Question(id=8, tagnames='six') q9 = models.Question(id=9, tagnames='six') q10 = models.Question(id=10, tagnames='six') q11 = models.Question(id=11, tagnames='six') q_dict = { q1:'', q2:'', q3:'', q4:'', q5:'', q6:'', q7:'', q8:'', q9:'', q10:'', q11:'', } subject = get_tag_summary_from_questions(q_dict.keys()) self.assertTrue('one' not in subject) self.assertTrue('two' in subject) self.assertTrue('three' in subject) self.assertTrue('four' in subject) self.assertTrue('five' in subject) self.assertTrue('six' in subject) i2 = subject.index('two') i3 = subject.index('three') i4 = subject.index('four') i5 = subject.index('five') i6 = subject.index('six') order = [i6, i5, i4, i3, i2] self.assertEquals( order, sorted(order) )
def test_topics_in_subject_line(self): q1 = models.Question(id=1, tagnames="one two three four five") q2 = models.Question(id=2, tagnames="two three four five") q3 = models.Question(id=3, tagnames="three four five") q4 = models.Question(id=4, tagnames="four five") q5 = models.Question(id=5, tagnames="five") q6 = models.Question(id=6, tagnames="six") q7 = models.Question(id=7, tagnames="six") q8 = models.Question(id=8, tagnames="six") q9 = models.Question(id=9, tagnames="six") q10 = models.Question(id=10, tagnames="six") q11 = models.Question(id=11, tagnames="six") q_dict = {q1: "", q2: "", q3: "", q4: "", q5: "", q6: "", q7: "", q8: "", q9: "", q10: "", q11: ""} subject = get_tag_summary_from_questions(q_dict.keys()) self.assertTrue("one" not in subject) self.assertTrue("two" in subject) self.assertTrue("three" in subject) self.assertTrue("four" in subject) self.assertTrue("five" in subject) self.assertTrue("six" in subject) i2 = subject.index("two") i3 = subject.index("three") i4 = subject.index("four") i5 = subject.index("five") i6 = subject.index("six") order = [i6, i5, i4, i3, i2] self.assertEquals(order, sorted(order))
def send_email_alerts(self): #does not change the database, only sends the email #todo: move this to template for user in User.objects.all(): #todo: q_list is a dictionary, not a list q_list = self.get_updated_questions_for_user(user) if len(q_list.keys()) == 0: continue num_q = 0 for question, meta_data in q_list.items(): if meta_data['skip']: del q_list[question] else: num_q += 1 if num_q > 0: url_prefix = askbot_settings.APP_URL tag_summary = get_tag_summary_from_questions(q_list.keys()) question_count = len(q_list.keys()) subject_line = ungettext( '%(question_count)d updated question about %(topics)s', '%(question_count)d updated questions about %(topics)s', question_count ) % { 'question_count': question_count, 'topics': tag_summary } #todo: send this to special log #print 'have %d updated questions for %s' % (num_q, user.username) text = ungettext('%(name)s, this is an update message header for %(num)d question', '%(name)s, this is an update message header for %(num)d questions',num_q) \ % {'num':num_q, 'name':user.username} text += '<ul>' items_added = 0 items_unreported = 0 for q, meta_data in q_list.items(): act_list = [] if meta_data['skip']: continue if items_added >= askbot_settings.MAX_ALERTS_PER_EMAIL: items_unreported = num_q - items_added #may be inaccurate actually, but it's ok else: items_added += 1 if meta_data['new_q']: act_list.append(_('new question')) format_action_count('%(num)d rev', meta_data['q_rev'],act_list) format_action_count('%(num)d ans', meta_data['new_ans'],act_list) format_action_count('%(num)d ans rev',meta_data['ans_rev'],act_list) act_token = ', '.join(act_list) text += '<li><a href="%s?sort=latest">%s</a> <font color="#777777">(%s)</font></li>' \ % (url_prefix + q.get_absolute_url(), q.title, act_token) text += '</ul>' text += '<p></p>' #if len(q_list.keys()) >= askbot_settings.MAX_ALERTS_PER_EMAIL: # text += _('There may be more questions updated since ' # 'you have logged in last time as this list is ' # 'abridged for your convinience. Please visit ' # 'the askbot and see what\'s new!<br>' # ) text += _( 'Please visit the askbot and see what\'s new! ' 'Could you spread the word about it - ' 'can somebody you know help answering those questions or ' 'benefit from posting one?' ) feeds = EmailFeedSetting.objects.filter( subscriber=user, ) feed_freq = [feed.frequency for feed in feeds] text += '<p></p>' if 'd' in feed_freq: text += _('Your most frequent subscription setting is \'daily\' ' 'on selected questions. If you are receiving more than one ' 'email per day' 'please tell about this issue to the askbot administrator.' ) elif 'w' in feed_freq: text += _('Your most frequent subscription setting is \'weekly\' ' 'if you are receiving this email more than once a week ' 'please report this issue to the askbot administrator.' ) text += ' ' text += _( 'There is a chance that you may be receiving links seen ' 'before - due to a technicality that will eventually go away. ' ) link = url_prefix + user.get_profile_url() + '?sort=email_subscriptions' text += _( 'go to %(email_settings_link)s to change ' 'frequency of email updates or ' '%(admin_email)s administrator' ) % { 'email_settings_link': link, 'admin_email': django_settings.ADMINS[0][1] } if DEBUG_THIS_COMMAND == True: recipient_email = django_settings.ADMINS[0][1] else: recipient_email = user.email mail.send_mail( subject_line = subject_line, body_text = text, recipient_list = [recipient_email] )
def handle_noargs(self, **options): if askbot_settings.ENABLE_UNANSWERED_REMINDERS == False: return #get questions without answers, excluding closed and deleted #order it by descending added_at date wait_period = datetime.timedelta( askbot_settings.DAYS_BEFORE_SENDING_UNANSWERED_REMINDER ) cutoff_date = datetime.datetime.now() + wait_period questions = models.Question.objects.exclude( closed = True ).exclude( deleted = True ).filter( added_at__lt = cutoff_date ).filter( answer_count = 0 ).order_by('-added_at') #for all users, excluding blocked #for each user, select a tag filtered subset #format the email reminder and send it for user in models.User.objects.exclude(status = 'b'): user_questions = questions.exclude(author = user) user_questions = user.get_tag_filtered_questions(user_questions) final_question_list = list() #todo: rewrite using query set filter #may be a lot more efficient for question in user_questions: activity_type = const.TYPE_ACTIVITY_UNANSWERED_REMINDER_SENT try: activity = models.Activity.objects.get( user = user, question = question, activity_type = activity_type ) now = datetime.datetime.now() recurrence_delay = datetime.timedelta( askbot_settings.UNANSWERED_REMINDER_FREQUENCY ) if now < activity.active_at + recurrence_delay: continue except models.Activity.DoesNotExist: activity = models.Activity( user = user, question = question, activity_type = activity_type, content_object = question, ) activity.active_at = datetime.datetime.now() activity.save() final_question_list.append(question) question_count = len(final_question_list) if question_count == 0: continue tag_summary = get_tag_summary_from_questions(user_questions) subject_line = ungettext( '%(question_count)d unanswered question about %(topics)s', '%(question_count)d unanswered questions about %(topics)s', question_count ) % { 'question_count': question_count, 'topics': tag_summary } body_text = '<ul>' for question in final_question_list: body_text += '<li><a href="%s%s?sort=latest">%s</a></li>' \ % ( askbot_settings.APP_URL, question.get_absolute_url(), question.title ) body_text += '</ul>' mail.send_mail( subject_line = subject_line, body_text = body_text, recipient_list = (user.email,) )
def handle_noargs(self, **options): if askbot_settings.ENABLE_UNANSWERED_REMINDERS == False: return #get questions without answers, excluding closed and deleted #order it by descending added_at date schedule = ReminderSchedule( askbot_settings.DAYS_BEFORE_SENDING_UNANSWERED_REMINDER, askbot_settings.UNANSWERED_REMINDER_FREQUENCY, max_reminders = askbot_settings.MAX_UNANSWERED_REMINDERS ) questions = models.Question.objects.exclude( closed = True ).exclude( deleted = True ).added_between( start = schedule.start_cutoff_date, end = schedule.end_cutoff_date ).filter( answer_count = 0 ).order_by('-added_at') #for all users, excluding blocked #for each user, select a tag filtered subset #format the email reminder and send it for user in models.User.objects.exclude(status = 'b'): user_questions = questions.exclude(author = user) user_questions = user.get_tag_filtered_questions(user_questions) final_question_list = user_questions.get_questions_needing_reminder( user = user, activity_type = const.TYPE_ACTIVITY_UNANSWERED_REMINDER_SENT, recurrence_delay = schedule.recurrence_delay ) question_count = len(final_question_list) if question_count == 0: continue tag_summary = get_tag_summary_from_questions(final_question_list) subject_line = ungettext( '%(question_count)d unanswered question about %(topics)s', '%(question_count)d unanswered questions about %(topics)s', question_count ) % { 'question_count': question_count, 'topics': tag_summary } body_text = '<ul>' for question in final_question_list: body_text += '<li><a href="%s%s?sort=latest">%s</a></li>' \ % ( askbot_settings.APP_URL, question.get_absolute_url(), question.title ) body_text += '</ul>' if DEBUG_THIS_COMMAND: print "User: %s<br>\nSubject:%s<br>\nText: %s<br>\n" % \ (user.email, subject_line, body_text) else: mail.send_mail( subject_line = subject_line, body_text = body_text, recipient_list = (user.email,) )
def handle_noargs(self, **options): if askbot_settings.ENABLE_UNANSWERED_REMINDERS == False: return #get questions without answers, excluding closed and deleted #order it by descending added_at date wait_period = datetime.timedelta( askbot_settings.DAYS_BEFORE_SENDING_UNANSWERED_REMINDER) cutoff_date = datetime.datetime.now() + wait_period questions = models.Question.objects.exclude(closed=True).exclude( deleted=True).filter(added_at__lt=cutoff_date).filter( answer_count=0).order_by('-added_at') #for all users, excluding blocked #for each user, select a tag filtered subset #format the email reminder and send it for user in models.User.objects.exclude(status='b'): user_questions = questions.exclude(author=user) user_questions = user.get_tag_filtered_questions(user_questions) final_question_list = list() #todo: rewrite using query set filter #may be a lot more efficient for question in user_questions: activity_type = const.TYPE_ACTIVITY_UNANSWERED_REMINDER_SENT try: activity = models.Activity.objects.get( user=user, question=question, activity_type=activity_type) now = datetime.datetime.now() recurrence_delay = datetime.timedelta( askbot_settings.UNANSWERED_REMINDER_FREQUENCY) if now < activity.active_at + recurrence_delay: continue except models.Activity.DoesNotExist: activity = models.Activity( user=user, question=question, activity_type=activity_type, content_object=question, ) activity.active_at = datetime.datetime.now() activity.save() final_question_list.append(question) question_count = len(final_question_list) if question_count == 0: continue tag_summary = get_tag_summary_from_questions(user_questions) subject_line = ungettext( '%(question_count)d unanswered question about %(topics)s', '%(question_count)d unanswered questions about %(topics)s', question_count) % { 'question_count': question_count, 'topics': tag_summary } body_text = '<ul>' for question in final_question_list: body_text += '<li><a href="%s%s?sort=latest">%s</a></li>' \ % ( askbot_settings.APP_URL, question.get_absolute_url(), question.title ) body_text += '</ul>' mail.send_mail(subject_line=subject_line, body_text=body_text, recipient_list=(user.email, ))
def handle(self, *args, **options): DEBUG_THIS_COMMAND = False FORCE_EMAIL = False IGNORE_DATES = False TEXT_FORMAT = False if askbot_settings.ENABLE_UNANSWERED_REMINDERS == False: return if options['ignore_dates']: IGNORE_DATES = True FORCE_EMAIL = True if options['debug']: DEBUG_THIS_COMMAND = True if options['force_email']: FORCE_EMAIL = True if options['text']: TEXT_FORMAT = True #get questions without answers, excluding closed and deleted #order it by descending added_at date wait_period = datetime.timedelta( askbot_settings.DAYS_BEFORE_SENDING_UNANSWERED_REMINDER ) start_cutoff_date = datetime.datetime.now() - wait_period recurrence_delay = datetime.timedelta( askbot_settings.UNANSWERED_REMINDER_FREQUENCY ) max_emails = askbot_settings.MAX_UNANSWERED_REMINDERS end_cutoff_date = start_cutoff_date - (max_emails - 1)*recurrence_delay if IGNORE_DATES: print "Email Reminders: Questions Asked BEFORE %s" % (start_cutoff_date) questions = models.Question.objects.exclude( closed = True ).exclude( deleted = True ).filter( added_at__lt = start_cutoff_date ).filter( answer_count = 0 ).order_by('-added_at') else: print "Email Reminders: Wait Period: %s - Email Every: %s - Max Emails: %d" % ( wait_period, recurrence_delay, max_emails) print "From %s to %s" % (end_cutoff_date, start_cutoff_date) questions = models.Question.objects.exclude( closed = True ).exclude( deleted = True ).filter( added_at__lt = start_cutoff_date ).exclude( added_at__lt = end_cutoff_date ).filter( answer_count = 0 ).order_by('-added_at') #for all users, excluding blocked #for each user, select a tag filtered subset #format the email reminder and send it now = datetime.datetime.now() print "Unanswered Question Set:" print_question_list(questions) for user in models.User.objects.exclude(status = 'b'): # Sanity check to catch invalid email if len(user.email) < 5: continue #user_questions = questions.exclude(author = user) user_questions = user.get_tag_filtered_questions( questions = questions, context = 'email' ) user_questions = list(user_questions) if user_questions: last = user_questions[-1] for i in range(len(user_questions)-2,-1,-1): if last == user_questions[i]: del user_questions[i] else: last=user_questions[i] final_question_list = list() #todo: rewrite using query set filter #may be a lot more efficient for question in user_questions: activity_type = const.TYPE_ACTIVITY_UNANSWERED_REMINDER_SENT try: activity = models.Activity.objects.get( user = user, question = question, activity_type = activity_type ) now = datetime.datetime.now() if now < activity.active_at + recurrence_delay: #print "Time Reject: %s < %s" % (now, activity.active_at + recurrence_delay) # Only send email if minimum delay between emails has been met if not DEBUG_THIS_COMMAND and not FORCE_EMAIL: continue except models.Activity.DoesNotExist: activity = models.Activity( user = user, question = question, activity_type = activity_type, content_object = question, ) if not DEBUG_THIS_COMMAND: activity.active_at = datetime.datetime.now() activity.save() final_question_list.append(question) question_count = len(final_question_list) if question_count == 0: continue tag_summary = get_tag_summary_from_questions(final_question_list) body_text = '<p>This email is sent as a reminder that the following questions do not have ' \ 'an answer. If you can provide an answer, please click on the link and share ' \ 'your knowlege.</p><hr><p><b>Summary List</b></p>' if TEXT_FORMAT: body_text = 'This email is sent as a reminder that the following questions do not have\n' \ 'an answer. If you can provide an answer, please share ' \ 'your knowlege.\nSummary List\n' tag_list = {} # Build list of Tags for question in final_question_list: tag_names = question.get_tag_names() tag_string = "" days = now - question.added_at for tag in tag_names: tag_string += tag + ", " if tag in tag_list: tag_list[tag].append((question, days)) else: tag_list[tag] = [(question, now - question.added_at)] if TEXT_FORMAT: body_text += ' - (%02d days old) %s [%s]\n' \ % ( days.days, question.title, tag_string[:-2] ) else: body_text += '<li>(%02d days old) <a href="%s%s">%s</a> [%s]</li>' \ % ( days.days, askbot_settings.APP_URL, question.get_absolute_url(), question.title, tag_string[:-2] ) tag_keys = tag_list.keys() tag_keys.sort() subject_line = ungettext( '%(question_count)d unanswered question about %(topics)s', '%(question_count)d unanswered questions about %(topics)s', question_count ) % { 'question_count': question_count, 'topics': tag_summary } if TEXT_FORMAT: body_text += "\nList ordered by Tags\n\n" else: body_text += "<hr><p><b>List ordered by Tags</b></p><br>" for tag in tag_keys: if TEXT_FORMAT: body_text += tag + '\n' else: body_text += '<p><b>' + tag + '</b></p><ul>' for question in tag_list[tag]: if TEXT_FORMAT: body_text += ' - (%02d days old) %s\n' \ % ( question[1].days, question[0].title ) else: body_text += '<li>(%02d days old) <a href="%s%s">%s</a></li>' \ % ( question[1].days, askbot_settings.APP_URL, question[0].get_absolute_url(), question[0].title ) if not TEXT_FORMAT: body_text += '</ul>' body_text += '\n' if DEBUG_THIS_COMMAND: print "User: %s<br>\nSubject:%s<br>\nText: %s<br>\n" % \ (user.email, subject_line, body_text) else: print "User: %s - %s" % (user.email, subject_line) mail.send_mail( subject_line = subject_line, body_text = body_text, recipient_list = (user.email,) )