def bounce_email(email, subject, reason=None, body_text=None): """sends a bounce email at address ``email``, with the subject line ``subject``, accepts several reasons for the bounce: * ``'problem_posting'``, ``unknown_user`` and ``permission_denied`` * ``body_text`` in an optional parameter that allows to append extra text to the message """ if reason == "problem_posting": error_message = _( "<p>Sorry, there was an error posting your question " "please contact the %(site)s administrator</p>" ) % {"site": askbot_settings.APP_SHORT_NAME} error_message = string_concat(error_message, USAGE) elif reason == "unknown_user": error_message = _( "<p>Sorry, in order to post questions on %(site)s " 'by email, please <a href="%(url)s">register first</a></p>' ) % {"site": askbot_settings.APP_SHORT_NAME, "url": url_utils.get_login_url()} elif reason == "permission_denied": error_message = _( "<p>Sorry, your question could not be posted " "due to insufficient privileges of your user account</p>" ) else: raise ValueError('unknown reason to bounce an email: "%s"' % reason) if body_text != None: error_message = string_concat(error_message, body_text) # print 'sending email' # print email # print subject # print error_message mail.send_mail(recipient_list=(email,), subject_line="Re: " + subject, body_text=error_message)
def user_add_transaction(request, subject, context): """user subview for moderation """ moderator = request.user if not moderator.can_moderate_user(subject): raise Http404 user_transaction_added = False message_sent = False email_error_message = None user_transaction_form = forms.AddUserTransactionForm() send_message_form = forms.SendMessageForm() if request.method == 'POST': if 'send_message' in request.POST: send_message_form = forms.SendMessageForm(request.POST) if send_message_form.is_valid(): subject_line = send_message_form.cleaned_data['subject_line'] body_text = send_message_form.cleaned_data['body_text'] try: send_mail( subject_line = subject_line, body_text = body_text, recipient_list = [subject.email], headers={'Reply-to':moderator.email}, raise_on_failure = True ) message_sent = True except exceptions.EmailNotSent, e: email_error_message = unicode(e) send_message_form = forms.SendMessageForm() else: transaction_change_type = None user_transaction_form = forms.AddUserTransactionForm(request.POST) if user_transaction_form.is_valid(): user_income = user_transaction_form.cleaned_data['user_income'] user_outcome = user_transaction_form.cleaned_data['user_outcome'] transaction_type = user_transaction_form.cleaned_data['transaction_type'] comment = user_transaction_form.cleaned_data['comment'] moderator.add_user_transaction( user = subject, income =user_income, outcome =user_outcome, transaction_type=transaction_type, comment = comment, timestamp = datetime.datetime.now() ) #reset form to preclude accidentally repeating submission user_transaction_form = forms.AddUserTransactionForm() user_transaction_added = True
def handle(self, *args, **options): if len(args) != 1: raise CommandError('Recipients email address required') try: validate_email(args[0]) except ValidationError: raise CommandError('%s is not a valid email address' % (args[0])) send_mail( subject_line = 'Askbot Mail Test', body_text = 'Askbot Mail Test', recipient_list = [args[0]], )
def handle(self, *args, **options): if len(args) != 1: raise CommandError('Recipients email address required') try: validate_email(args[0]) except ValidationError: raise CommandError('%s is not a valid email address' % (args[0])) send_mail( subject_line='Askbot Mail Test', body_text='Askbot Mail Test', recipient_list=[args[0]], )
def handle(self, *args, **options): if len(args) != 1: print "Need a message file" return if not os.path.exists(args[0]): print "File '%s' does not exist" % args[0] return message=open(args[0], 'r').read() title = message.split('\n')[0] print "Title: ", title print "Message:\n", message users = models.User.objects.all().order_by('username') for user in users: if len(user.email) > 5: mail.send_mail( subject_line = title, body_text = message, recipient_list = [user.email] )
def PROCESS(message, address = None, host = None): try: for rule in settings.LAMSON_FORWARD: if re.match(rule['pattern'], message.base['to']): relay = Relay(host=rule['host'], port=rule['port'], debug=1) relay.deliver(message) return except AttributeError: pass error = None try: reply_address = ReplyAddress.objects.get_unused(address, message.From) separator = _("======= Reply above this line. ====-=-=") parts = message.body().split(separator) if len(parts) != 2 : error = _("Your message was malformed. Please make sure to qoute \ the original notification you received at the end of your reply.") else: reply_part = parts[0] reply_part = '\n'.join(reply_part.splitlines(True)[:-3]) reply_address.create_reply(reply_part.strip()) except ReplyAddress.DoesNotExist: error = _("You were replying to an email address\ unknown to the system or you were replying from a different address from the one where you\ received the notification.") if error is not None: from askbot.utils import mail from django.template import Context from askbot.skins.loaders import get_template template = get_template('reply_by_email_error.html') body_text = template.render(Context({'error':error})) mail.send_mail( subject_line = "Error posting your reply", body_text = body_text, recipient_list = [message.From], )
def bounce_email(email, subject, reason=None, body_text=None): """sends a bounce email at address ``email``, with the subject line ``subject``, accepts several reasons for the bounce: * ``'problem_posting'``, ``unknown_user`` and ``permission_denied`` * ``body_text`` in an optional parameter that allows to append extra text to the message """ if reason == 'problem_posting': error_message = _('<p>Sorry, there was an error posting your question ' 'please contact the %(site)s administrator</p>') % { 'site': askbot_settings.APP_SHORT_NAME } error_message = string_concat(error_message, USAGE) elif reason == 'unknown_user': error_message = _( '<p>Sorry, in order to post questions on %(site)s ' 'by email, please <a href="%(url)s">register first</a></p>') % { 'site': askbot_settings.APP_SHORT_NAME, 'url': askbot_settings.APP_URL + reverse('user_signin') } elif reason == 'permission_denied': error_message = _( '<p>Sorry, your question could not be posted ' 'due to insufficient privileges of your user account</p>') else: raise ValueError('unknown reason to bounce an email: "%s"' % reason) if body_text != None: error_message = string_concat(error_message, body_text) #print 'sending email' #print email #print subject #print error_message mail.send_mail(recipient_list=(email, ), subject_line='Re: ' + subject, body_text=error_message)
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(): user.add_missing_askbot_subscriptions() #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 threads = Thread.objects.filter(id__in=[qq.thread_id for qq in q_list.keys()]) tag_summary = Thread.objects.get_tag_summary_from_threads(threads) 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.thread.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>' # ) link = url_prefix + reverse( 'user_subscriptions', kwargs = { 'id': user.id, 'slug': slugify(user.username) } ) 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] )
address = address, allowed_from_email = message.From ) parts = get_parts(message) if reply_address.was_used: reply_address.edit_post(parts) else: reply_address.create_reply(parts) except ReplyAddress.DoesNotExist: error = _("You were replying to an email address\ unknown to the system or you were replying from a different address from the one where you\ received the notification.") except Exception, e: import sys sys.stderr.write(str(e)) import traceback sys.stderr.write(traceback.format_exc()) if error is not None: from askbot.utils import mail from django.template import Context from askbot.skins.loaders import get_template template = get_template('reply_by_email_error.html') body_text = template.render(Context({'error':error})) mail.send_mail( subject_line = "Error posting your reply", body_text = body_text, recipient_list = [message.From], )
def handle_noargs(self, **options): if askbot_settings.ENABLE_EMAIL_ALERTS == False: return 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.Post.objects.get_questions().exclude( thread__closed = True ).exclude( deleted = True ).added_between( start = schedule.start_cutoff_date, end = schedule.end_cutoff_date ).filter( thread__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 threads = Thread.objects.filter(id__in=[qq.thread_id for qq in final_question_list]) tag_summary = Thread.objects.get_tag_summary_from_threads(threads) 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.thread.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 user_moderate(request, subject, context): """user subview for moderation """ moderator = request.user if moderator.is_authenticated() and not moderator.can_moderate_user(subject): raise Http404 user_rep_changed = False user_status_changed = False message_sent = False email_error_message = None user_rep_form = forms.ChangeUserReputationForm() send_message_form = forms.SendMessageForm() if request.method == 'POST': if 'change_status' in request.POST: user_status_form = forms.ChangeUserStatusForm( request.POST, moderator = moderator, subject = subject ) if user_status_form.is_valid(): subject.set_status( user_status_form.cleaned_data['user_status'] ) user_status_changed = True elif 'send_message' in request.POST: send_message_form = forms.SendMessageForm(request.POST) if send_message_form.is_valid(): subject_line = send_message_form.cleaned_data['subject_line'] body_text = send_message_form.cleaned_data['body_text'] try: send_mail( subject_line = subject_line, body_text = body_text, recipient_list = [subject.email], headers={'Reply-to':moderator.email}, raise_on_failure = True ) message_sent = True except exceptions.EmailNotSent, e: email_error_message = unicode(e) send_message_form = forms.SendMessageForm() else: reputation_change_type = None if 'subtract_reputation' in request.POST: rep_change_type = 'subtract' elif 'add_reputation' in request.POST: rep_change_type = 'add' else: raise Http404 user_rep_form = forms.ChangeUserReputationForm(request.POST) if user_rep_form.is_valid(): rep_delta = user_rep_form.cleaned_data['user_reputation_delta'] comment = user_rep_form.cleaned_data['comment'] if rep_change_type == 'subtract': rep_delta = -1 * rep_delta moderator.moderate_user_reputation( user = subject, reputation_change = rep_delta, comment = comment, timestamp = datetime.datetime.now(), ) #reset form to preclude accidentally repeating submission user_rep_form = forms.ChangeUserReputationForm() user_rep_changed = True
def user_moderate(request, subject, context): """user subview for moderation """ moderator = request.user if not moderator.can_moderate_user(subject): raise Http404 user_rep_changed = False user_status_changed = False message_sent = False email_error_message = None user_rep_form = forms.ChangeUserReputationForm() send_message_form = forms.SendMessageForm() if request.method == "POST": if "change_status" in request.POST: user_status_form = forms.ChangeUserStatusForm(request.POST, moderator=moderator, subject=subject) if user_status_form.is_valid(): subject.set_status(user_status_form.cleaned_data["user_status"]) user_status_changed = True elif "send_message" in request.POST: send_message_form = forms.SendMessageForm(request.POST) if send_message_form.is_valid(): subject_line = send_message_form.cleaned_data["subject_line"] body_text = send_message_form.cleaned_data["body_text"] try: send_mail( subject_line=subject_line, body_text=body_text, recipient_list=[subject.email], headers={"Reply-to": moderator.email}, raise_on_failure=True, ) message_sent = True except exceptions.EmailNotSent, e: email_error_message = unicode(e) send_message_form = forms.SendMessageForm() else: reputation_change_type = None if "subtract_reputation" in request.POST: rep_change_type = "subtract" elif "add_reputation" in request.POST: rep_change_type = "add" else: raise Http404 user_rep_form = forms.ChangeUserReputationForm(request.POST) if user_rep_form.is_valid(): rep_delta = user_rep_form.cleaned_data["user_reputation_delta"] comment = user_rep_form.cleaned_data["comment"] if rep_change_type == "subtract": rep_delta = -1 * rep_delta moderator.moderate_user_reputation( user=subject, reputation_change=rep_delta, comment=comment, timestamp=datetime.datetime.now() ) # reset form to preclude accidentally repeating submission user_rep_form = forms.ChangeUserReputationForm() user_rep_changed = True
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,) )
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 send_email_alerts(self): #does not change the database, only sends the email #todo: move this to template for user in User.objects.all(): user.add_missing_askbot_subscriptions() #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 threads = Thread.objects.filter( id__in=[qq.thread_id for qq in q_list.keys()]) tag_summary = Thread.objects.get_tag_summary_from_threads( threads) 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( '<p>Dear %(name)s,</p><p>The following question has been updated ' '%(sitename)s</p>', '<p>Dear %(name)s,</p><p>The following %(num)d questions have been ' 'updated on %(sitename)s:</p>', num_q) % { 'num': num_q, 'name': user.username, 'sitename': askbot_settings.APP_SHORT_NAME } 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.thread.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>' # ) link = url_prefix + reverse('user_subscriptions', kwargs={ 'id': user.id, 'slug': slugify(user.username) }) text += _( '<p>Please remember that you can always <a ' 'href="%(email_settings_link)s">adjust</a> frequency of the email updates or ' 'turn them off entirely.<br/>If you believe that this message was sent in an ' 'error, please email about it the forum administrator at %(admin_email)s.</' 'p><p>Sincerely,</p><p>Your friendly %(sitename)s server.</p>' ) % { 'email_settings_link': link, 'admin_email': django_settings.ADMINS[0][1], 'sitename': askbot_settings.APP_SHORT_NAME } 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 manage_inbox(request): """delete, mark as new or seen user's response memo objects, excluding flags request data is memo_list - list of integer id's of the ActivityAuditStatus items and action_type - string - one of delete|mark_new|mark_seen """ response_data = dict() try: if request.is_ajax(): if request.method == 'POST': post_data = simplejson.loads(request.raw_post_data) if request.user.is_authenticated(): activity_types = const.RESPONSE_ACTIVITY_TYPES_FOR_DISPLAY activity_types += (const.TYPE_ACTIVITY_MENTION, const.TYPE_ACTIVITY_MARK_OFFENSIVE, const.TYPE_ACTIVITY_MODERATED_NEW_POST, const.TYPE_ACTIVITY_MODERATED_POST_EDIT) user = request.user memo_set = models.ActivityAuditStatus.objects.filter( id__in=post_data['memo_list'], activity__activity_type__in=activity_types, user=user) action_type = post_data['action_type'] if action_type == 'delete': memo_set.delete() elif action_type == 'mark_new': memo_set.update( status=models.ActivityAuditStatus.STATUS_NEW) elif action_type == 'mark_seen': memo_set.update( status=models.ActivityAuditStatus.STATUS_SEEN) elif action_type == 'remove_flag': for memo in memo_set: activity_type = memo.activity.activity_type if activity_type == const.TYPE_ACTIVITY_MARK_OFFENSIVE: request.user.flag_post( post=memo.activity.content_object, cancel_all=True) elif activity_type in \ ( const.TYPE_ACTIVITY_MODERATED_NEW_POST, const.TYPE_ACTIVITY_MODERATED_POST_EDIT ): post_revision = memo.activity.content_object request.user.approve_post_revision( post_revision) memo.delete() #elif action_type == 'close': # for memo in memo_set: # if memo.activity.content_object.post_type == "question": # request.user.close_question(question = memo.activity.content_object, reason = 7) # memo.delete() elif action_type == 'delete_post': for memo in memo_set: content_object = memo.activity.content_object if isinstance(content_object, models.PostRevision): post = content_object.post else: post = content_object request.user.delete_post(post) reject_reason = models.PostFlagReason.objects.get( id=post_data['reject_reason_id']) body_text = string_concat( _('Your post (copied in the end),'), '<br/>', _('was rejected for the following reason:'), '<br/><br/>', reject_reason.details.html, '<br/><br/>', _('Here is your original post'), '<br/><br/>', post.text) mail.send_mail( subject_line=_('your post was not accepted'), body_text=unicode(body_text), recipient_list=[ post.author.email, ]) memo.delete() user.update_response_counts() response_data['success'] = True data = simplejson.dumps(response_data) return HttpResponse(data, mimetype="application/json") else: raise exceptions.PermissionDenied( _('Sorry, but anonymous users cannot access the inbox') ) else: raise exceptions.PermissionDenied('must use POST request') else: #todo: show error page but no-one is likely to get here return HttpResponseRedirect(reverse('index')) except Exception, e: message = unicode(e) if message == '': message = _('Oops, apologies - there was some error') response_data['message'] = message response_data['success'] = False data = simplejson.dumps(response_data) return HttpResponse(data, mimetype="application/json")
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 user_moderate(request, subject): """user subview for moderation """ moderator = request.user if not moderator.can_moderate_user(subject): raise Http404 user_rep_changed = False user_status_changed = False message_sent = False email_error_message = None user_rep_form = forms.ChangeUserReputationForm() send_message_form = forms.SendMessageForm() if request.method == 'POST': if 'change_status' in request.POST: user_status_form = forms.ChangeUserStatusForm(request.POST, moderator=moderator, subject=subject) if user_status_form.is_valid(): subject.set_status( user_status_form.cleaned_data['user_status']) user_status_changed = True elif 'send_message' in request.POST: send_message_form = forms.SendMessageForm(request.POST) if send_message_form.is_valid(): subject_line = send_message_form.cleaned_data['subject_line'] body_text = send_message_form.cleaned_data['body_text'] try: send_mail(subject_line=subject_line, body_text=body_text, recipient_list=[subject.email], headers={'Reply-to': moderator.email}, raise_on_failure=True) message_sent = True except exceptions.EmailNotSent, e: email_error_message = unicode(e) send_message_form = forms.SendMessageForm() else: reputation_change_type = None if 'subtract_reputation' in request.POST: rep_change_type = 'subtract' elif 'add_reputation' in request.POST: rep_change_type = 'add' else: raise Http404 user_rep_form = forms.ChangeUserReputationForm(request.POST) if user_rep_form.is_valid(): rep_delta = user_rep_form.cleaned_data['user_reputation_delta'] comment = user_rep_form.cleaned_data['comment'] if rep_change_type == 'subtract': rep_delta = -1 * rep_delta moderator.moderate_user_reputation( user=subject, reputation_change=rep_delta, comment=comment, timestamp=datetime.datetime.now(), ) #reset form to preclude accidentally repeating submission user_rep_form = forms.ChangeUserReputationForm() user_rep_changed = True
reply_part.strip(), attachments = attachments ) else: reply_address.create_reply( reply_part.strip(), attachments = attachments ) except ReplyAddress.DoesNotExist: error = _("You were replying to an email address\ unknown to the system or you were replying from a different address from the one where you\ received the notification.") except Exception, e: import sys sys.stderr.write(str(e)) import traceback sys.stderr.write(traceback.format_exc()) if error is not None: from askbot.utils import mail from django.template import Context from askbot.skins.loaders import get_template template = get_template('reply_by_email_error.html') body_text = template.render(Context({'error':error})) mail.send_mail( subject_line = "Error posting your reply", body_text = body_text, recipient_list = [message.From], )
def manage_inbox(request): """delete, mark as new or seen user's response memo objects, excluding flags request data is memo_list - list of integer id's of the ActivityAuditStatus items and action_type - string - one of delete|mark_new|mark_seen """ response_data = dict() try: if request.is_ajax(): if request.method == 'POST': post_data = simplejson.loads(request.raw_post_data) if request.user.is_authenticated(): activity_types = const.RESPONSE_ACTIVITY_TYPES_FOR_DISPLAY activity_types += ( const.TYPE_ACTIVITY_MENTION, const.TYPE_ACTIVITY_MARK_OFFENSIVE, const.TYPE_ACTIVITY_MODERATED_NEW_POST, const.TYPE_ACTIVITY_MODERATED_POST_EDIT ) user = request.user memo_set = models.ActivityAuditStatus.objects.filter( id__in = post_data['memo_list'], activity__activity_type__in = activity_types, user = user ) action_type = post_data['action_type'] if action_type == 'delete': memo_set.delete() elif action_type == 'mark_new': memo_set.update(status = models.ActivityAuditStatus.STATUS_NEW) elif action_type == 'mark_seen': memo_set.update(status = models.ActivityAuditStatus.STATUS_SEEN) elif action_type == 'remove_flag': for memo in memo_set: activity_type = memo.activity.activity_type if activity_type == const.TYPE_ACTIVITY_MARK_OFFENSIVE: request.user.flag_post( post = memo.activity.content_object, cancel_all = True ) elif activity_type in \ ( const.TYPE_ACTIVITY_MODERATED_NEW_POST, const.TYPE_ACTIVITY_MODERATED_POST_EDIT ): post_revision = memo.activity.content_object request.user.approve_post_revision(post_revision) memo.delete() #elif action_type == 'close': # for memo in memo_set: # if memo.activity.content_object.post_type == "question": # request.user.close_question(question = memo.activity.content_object, reason = 7) # memo.delete() elif action_type == 'delete_post': for memo in memo_set: content_object = memo.activity.content_object if isinstance(content_object, models.PostRevision): post = content_object.post else: post = content_object request.user.delete_post(post) reject_reason = models.PostFlagReason.objects.get( id = post_data['reject_reason_id'] ) body_text = string_concat( _('Your post (copied in the end),'), '<br/>', _('was rejected for the following reason:'), '<br/><br/>', reject_reason.details.html, '<br/><br/>', _('Here is your original post'), '<br/><br/>', post.text ) mail.send_mail( subject_line = _('your post was not accepted'), body_text = unicode(body_text), recipient_list = [post.author,] ) memo.delete() user.update_response_counts() response_data['success'] = True data = simplejson.dumps(response_data) return HttpResponse(data, mimetype="application/json") else: raise exceptions.PermissionDenied( _('Sorry, but anonymous users cannot access the inbox') ) else: raise exceptions.PermissionDenied('must use POST request') else: #todo: show error page but no-one is likely to get here return HttpResponseRedirect(reverse('index')) except Exception, e: message = unicode(e) if message == '': message = _('Oops, apologies - there was some error') response_data['message'] = message response_data['success'] = False data = simplejson.dumps(response_data) return HttpResponse(data, mimetype="application/json")
def handle_noargs(self, **options): if askbot_settings.ENABLE_ACCEPT_ANSWER_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_ACCEPT_ANSWER_REMINDER, askbot_settings.ACCEPT_ANSWER_REMINDER_FREQUENCY, askbot_settings.MAX_ACCEPT_ANSWER_REMINDERS ) questions = models.Question.objects.exclude( deleted = True ).added_between( start = schedule.start_cutoff_date, end = schedule.end_cutoff_date ).filter( answer_count__gt = 0 ).filter( answer_accepted = False ).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.filter(author = user) final_question_list = user_questions.get_questions_needing_reminder( activity_type = const.TYPE_ACTIVITY_ACCEPT_ANSWER_REMINDER_SENT, user = user, recurrence_delay = schedule.recurrence_delay ) #todo: rewrite using query set filter #may be a lot more efficient question_count = len(final_question_list) if question_count == 0: continue #tag_summary = get_tag_summary_from_questions(final_question_list) subject_line = _( 'Accept the best answer for %(question_count)d of your questions' ) % {'question_count': question_count} #todo - make a template for these if question_count == 1: reminder_phrase = _('Please accept the best answer for this question:') else: reminder_phrase = _('Please accept the best answer for these questions:') body_text = '<p>' + reminder_phrase + '</p>' 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,) )