def event_signup(self, request, tl, one, two, module, extra, prog): if request.method == 'POST': form = TeacherEventSignupForm(self, request.POST) if form.is_valid(): data = form.cleaned_data # Remove old bits UserAvailability.objects.filter(user=request.user, event__event_type__in=self.event_types().values()).delete() # Register for interview if data['interview']: ua, created = UserAvailability.objects.get_or_create( user=request.user, event=data['interview'], role=self.availability_role()) # Send the directors an e-mail if self.program.director_email and created: event_name = data['interview'].description send_mail('['+self.program.niceName()+'] Teacher Interview for ' + request.user.first_name + ' ' + request.user.last_name + ': ' + event_name, \ """Teacher Interview Registration Notification\n--------------------------------- \n\nTeacher: %s %s\n\nTime: %s\n\n""" % \ (request.user.first_name, request.user.last_name, event_name) , \ ('%s <%s>' % (request.user.first_name + ' ' + request.user.last_name, request.user.email,)), \ [self.program.getDirectorCCEmail()], True) # Register for training if data['training']: ua, created = UserAvailability.objects.get_or_create( user=request.user, event=data['training'], role=self.availability_role()) return self.goToCore(tl) else: data = {} entries = self.entriesByTeacher(request.user) if entries['interview'].count() > 0: data['interview'] = entries['interview'][0].event.id if entries['training'].count() > 0: data['training'] = entries['training'][0].event.id form = TeacherEventSignupForm(self, initial=data) return render_to_response( self.baseDir()+'event_signup.html', request, {'prog':prog, 'form': form} )
def event_signup(self, request, tl, one, two, module, extra, prog): if request.method == 'POST': form = TeacherEventSignupForm(self, request.POST) if form.is_valid(): data = form.cleaned_data # Remove old bits UserAvailability.objects.filter(user=request.user, event__event_type__in=self.event_types().values()).delete() # Register for interview if data['interview']: ua, created = UserAvailability.objects.get_or_create( user=request.user, event=data['interview'], role=self.availability_role()) # Send the directors an e-mail if self.program.director_email and created: event_name = data['interview'].description send_mail('['+self.program.niceName()+'] Teacher Interview for ' + request.user.first_name + ' ' + request.user.last_name + ': ' + event_name, \ """Teacher Interview Registration Notification\n--------------------------------- \n\nTeacher: %s %s\n\nTime: %s\n\n""" % \ (request.user.first_name, request.user.last_name, event_name) , \ ('%s <%s>' % (request.user.first_name + ' ' + request.user.last_name, request.user.email,)), \ [self.program.getDirectorCCEmail()], True) # Register for training if data['training']: ua, created = UserAvailability.objects.get_or_create( user=request.user, event=data['training'], role=self.availability_role()) return self.goToCore(tl) else: data = {} entries = self.entriesByTeacher(request.user) if entries['interview'].count() > 0: data['interview'] = entries['interview'][0].event.id if entries['training'].count() > 0: data['training'] = entries['training'][0].event.id form = TeacherEventSignupForm(self, initial=data) return render_to_response( self.baseDir()+'event_signup.html', request, {'prog':prog, 'form': form} )
def send_confirmation_email(self, user, program, repeat=False, override=False): options = program.getModuleExtension('StudentClassRegModuleInfo') ## Get or create a userbit indicating whether or not email's been sent. try: record, created = Record.objects.get_or_create(user=user, event="conf_email", program=program) except Exception: created = False if (created or repeat) and (options.send_confirmation or override): try: receipt_template = Template( DBReceipt.objects.get(program=program, action='confirmemail').receipt) except: receipt_template = select_template([ 'program/confemails/%s_confemail.txt' % (program.id), 'program/confirm_email.txt' ]) send_mail("Thank you for registering for %s!" %(program.niceName()), \ receipt_template.render(Context({'user': user, 'program': program}, autoescape=False)), \ ("%s <%s>" %(program.niceName() + " Directors", program.director_email)), \ [user.email], True)
def send_student_email(self, student_ind, changed=True, for_real=False, f=None): student = self.students[student_ind] recipient_list = [student.email, self.from_email] if changed: text_fn = self.get_changed_student_email_text else: text_fn = self.get_unchanged_student_email_text sent_to = "\n\nSent to " + student.username + ", " + student.name( ) + " <" + student.email + ">\n\n------------------------\n\n" if self.options['stats_display']: logger.info(text_fn(student_ind, for_real=False) + sent_to) sys.stdout.flush() if f: f.write((text_fn(student_ind, for_real=False) + sent_to).replace( u'\u2019', "'").replace(u'\u201c', '"').replace(u'\u201d', '"').encode('ascii', 'ignore')) if for_real: send_mail(self.subject, text_fn(student_ind, for_real=True), self.from_email, recipient_list, bcc=self.bcc, extra_headers=self.extra_headers) time.sleep(self.timeout)
def send_activation_email(user, userkey): t = loader.get_template('registration/activation_email.txt') c = { 'user': user, 'activation_key': userkey, 'site': Site.objects.get_current() } send_mail("Account Activation", t.render(c), settings.SERVER_EMAIL, [user.email], fail_silently=False)
def send_availability_email(self, teacher, note=None): timeslots = teacher.getAvailableTimes(self.program, ignore_classes=True) email_title = 'Availability for %s: %s' % (self.program.niceName(), teacher.name()) email_from = '%s Registration System <server@%s>' % (self.program.anchor.parent.name, settings.EMAIL_HOST_SENDER) email_context = {'teacher': teacher, 'timeslots': timeslots, 'program': self.program, 'curtime': datetime.now(), 'note': note} email_contents = render_to_string('program/modules/availabilitymodule/update_email.txt', email_context) email_to = ['%s <%s>' % (teacher.name(), teacher.email)] send_mail(email_title, email_contents, email_from, email_to, False)
def send_activation_email(user, userkey): from django.template import Context as RawContext t = loader.get_template('registration/activation_email.txt') c = RawContext({ 'user': user, 'activation_key': userkey, 'site': Site.objects.get_current() }) send_mail("Account Activation", t.render(c), settings.SERVER_EMAIL, [user.email], fail_silently=False)
def send_error_email(self, request, context): """ Send an e-mail to admins explaining the credit card error. (Broken out from charge_payment view for readability.) """ context['request'] = request context['program'] = self.program context['postdata'] = request.POST.copy() domain_name = Site.objects.get_current().domain msg_content = render_to_string(self.baseDir() + 'error_email.txt', context) msg_subject = '[ ESP CC ] Credit card error on %s: %d %s' % (domain_name, request.user.id, request.user.name()) # This message could contain sensitive information. Send to the # confidential messages address, and don't bcc the archive list. send_mail(msg_subject, msg_content, settings.SERVER_EMAIL, [self.program.getDirectorConfidentialEmail()], bcc=None)
def send_availability_email(self, teacher, note=None): timeslots = teacher.getAvailableTimes(self.program, ignore_classes=True) email_title = 'Availability for %s: %s' % (self.program.niceName(), teacher.name()) email_from = '%s Registration System <server@%s>' % (self.program.program_type, settings.EMAIL_HOST_SENDER) email_context = {'teacher': teacher, 'timeslots': timeslots, 'program': self.program, 'curtime': datetime.now(), 'note': note, 'DEFAULT_HOST': settings.DEFAULT_HOST} email_contents = render_to_string('program/modules/availabilitymodule/update_email.txt', email_context) email_to = ['%s <%s>' % (teacher.name(), teacher.email)] send_mail(email_title, email_contents, email_from, email_to, False)
def send_confirmation_email(self, user, program, repeat=False, override=False): options = program.studentclassregmoduleinfo ## Get or create a userbit indicating whether or not email's been sent. try: record, created = Record.objects.get_or_create(user=user, event="conf_email", program=program) except Exception: created = False if (created or repeat) and (options.send_confirmation or override): try: receipt_template = Template(DBReceipt.objects.get(program=program, action='confirmemail').receipt) except: receipt_template = select_template(['program/confemails/%s_confemail.txt' %(program.id),'program/confirm_email.txt']) send_mail("Thank you for registering for %s!" %(program.niceName()), \ receipt_template.render(Context({'user': user, 'program': program}, autoescape=False)), \ ("%s <%s>" %(program.niceName() + " Directors", program.director_email)), \ [user.email], True)
def send_student_email(self, student_ind, changed = True, for_real = False, f = None): student = self.students[student_ind] recipient_list = [student.email, self.from_email] if changed: text_fn = self.get_changed_student_email_text else: text_fn = self.get_unchanged_student_email_text sent_to = "\n\nSent to " + student.username + ", " + student.name() + " <" + student.email + ">\n\n------------------------\n\n" if self.options['stats_display']: logger.info(text_fn(student_ind,for_real=False) + sent_to) sys.stdout.flush() if f: f.write((text_fn(student_ind,for_real=False) + sent_to).replace(u'\u2019', "'").replace(u'\u201c','"').replace(u'\u201d','"').encode('ascii','ignore')) if for_real: send_mail(self.subject, text_fn(student_ind,for_real=True), self.from_email, recipient_list, bcc=self.bcc, extra_headers=self.extra_headers) time.sleep(self.timeout)
def send_class_mail_to_directors(self, cls): mail_ctxt = self.generate_director_mail_context(cls) recipients = [teacher.email for teacher in cls.get_teachers()] if recipients: send_mail('['+self.program.niceName()+"] Comments for " + cls.emailcode() + ': ' + cls.title, \ render_to_string('program/modules/teacherclassregmodule/classreg_email', mail_ctxt) , \ ('%s Class Registration <%s>' % (self.program.program_type, self.program.director_email)), \ recipients, False) if self.program.director_email: mail_ctxt['admin'] = True send_mail('['+self.program.niceName()+"] Comments for " + cls.emailcode() + ': ' + cls.title, \ render_to_string('program/modules/teacherclassregmodule/classreg_email', mail_ctxt) , \ ('%s Class Registration <%s>' % (self.program.program_type, self.program.director_email)), \ [self.program.getDirectorCCEmail()], False)
def send_confirmation_email(self, student, note=None): email_title = 'Student Lottery Confirmation for %s: %s' % ( self.program.niceName(), student.name()) email_from = '%s Registration System <server@%s>' % ( self.program.program_type, settings.EMAIL_HOST_SENDER) email_context = { 'student': student, 'program': self.program, 'curtime': datetime.datetime.now(), 'note': note, 'DEFAULT_HOST': settings.DEFAULT_HOST } email_contents = render_to_string( 'program/modules/studentregphasezero/confirmation_email.txt', email_context) email_to = ['%s <%s>' % (student.name(), student.email)] send_mail(email_title, email_contents, email_from, email_to, False)
def send_error_email(self, request, context): """ Send an e-mail to admins explaining the credit card error. (Broken out from charge_payment view for readability.) """ context['request'] = request context['program'] = self.program context['postdata'] = request.POST.copy() domain_name = Site.objects.get_current().domain msg_content = render_to_string(self.baseDir() + 'error_email.txt', context) msg_subject = '[ ESP CC ] Credit card error on %s: %d %s' % ( domain_name, request.user.id, request.user.name()) # This message could contain sensitive information. Send to the # confidential messages address, and don't bcc the archive list. send_mail(msg_subject, msg_content, settings.SERVER_EMAIL, [self.program.getDirectorConfidentialEmail()], bcc=None)
def send_miniblog_messages(): entries = Entry.objects.filter(email = True, sent = False) for entry in entries: entry.sent = True entry.save() verb = GetNode('V/Subscribe') if hasattr(settings, 'EMAILTIMEOUT') and settings.EMAILTIMEOUT is not None: wait = settings.EMAILTIMEOUT else: wait = 1.5 for entry in entries: if entry.fromemail is None or len(entry.fromemail.strip()) == 0: if entry.fromuser is None or type(entry.fromuser) == AnonymousUser: fromemail = '*****@*****.**' else: fromemail = '%s <%s>' % (ESPUser(entry.fromuser).name(), entry.fromuser.email) else: fromemail = entry.fromemail emails = {} bits = UserBit.bits_get_users(qsc = entry.anchor, verb = verb) for bit in bits: if bit.user is None or type(bit.user) == AnonymousUser: # print "Error with %s (%s)" % (str(entry), str(bit.user)) pass else: emails[bit.user.email] = ESPUser(bit.user).name() for email,name in emails.items(): send_mail(entry.title, entry.content, fromemail, ['%s <%s>' % (name, email)], True) print "Sent mail to %s" % (name) time.sleep(wait)
def event_signup(self, request, tl, one, two, module, extra, prog): if request.method == 'POST': form = TeacherEventSignupForm(self, request.POST) if form.is_valid(): data = form.cleaned_data # Remove old bits [ ub.expire() for ub in UserBit.objects.filter( Q(qsc__parent=self.qscs['interview']) | Q(qsc__parent=self.qscs['training']), UserBit.not_expired(), user=request.user, verb=self.reg_verb ) ] # Register for interview if data['interview']: ub, created = UserBit.objects.get_or_create( user=request.user, qsc=data['interview'], verb=self.reg_verb, defaults={'recursive':False} ) # Send the directors an e-mail if self.program.director_email and (created or ub.enddate < datetime.now() ): event_names = ' '.join([x.description for x in data['interview'].event_set.all()]) send_mail('['+self.program.niceName()+'] Teacher Interview for ' + request.user.first_name + ' ' + request.user.last_name + ': ' + event_names, \ """Teacher Interview Registration Notification\n--------------------------------- \n\nTeacher: %s %s\n\nTime: %s\n\n""" % \ (request.user.first_name, request.user.last_name, event_names) , \ ('%s <%s>' % (request.user.first_name + ' ' + request.user.last_name, request.user.email,)), \ [self.program.director_email], True) if not created: ub.enddate = datetime(9999,1,1) # Approximately infinity; see default value of UserBit.enddate ub.save() # Register for training if data['training']: ub, created = UserBit.objects.get_or_create( user=request.user, qsc=data['training'], verb=self.reg_verb, defaults={'recursive':False} ) if not created: ub.enddate = datetime(9999,1,1) # Approximately infinity ub.save() return self.goToCore(tl) else: data = {} bits = self.bitsByTeacher(request.user) if bits['interview'].count() > 0: data['interview'] = bits['interview'][0].qsc.id if bits['training'].count() > 0: data['training'] = bits['training'][0].qsc.id form = TeacherEventSignupForm(self, initial=data) return render_to_response( self.baseDir()+'event_signup.html', request, (prog, tl), {'prog':prog, 'form': form} )
def cancelrequest(self, request, tl, one, two, module, extra, prog): if request.method == "POST" and 'reason' in request.POST: cls = ClassSubject.objects.get(id=request.POST['cls']) reason = request.POST['reason'] request_teacher = request.user email_title = '[%s] Class Cancellation Request for %s: %s' % ( self.program.niceName(), cls.emailcode(), cls.title) email_from = '%s Registration System <server@%s>' % ( self.program.program_type, settings.EMAIL_HOST_SENDER) email_context = { 'request_teacher': request_teacher, 'program': self.program, 'cls': cls, 'reason': reason, 'DEFAULT_HOST': settings.DEFAULT_HOST, 'one': cls.parent_program.program_type, 'two': cls.parent_program.program_instance } #Send email to all teachers confirming cancellation request email_contents = render_to_string( 'program/modules/teacherclassregmodule/cancelrequest.txt', email_context) for teacher in cls.get_teachers(): email_to = ['%s <%s>' % (teacher.name(), teacher.email)] send_mail(email_title, email_contents, email_from, email_to, False) #Send email to admin with link to manageclass page email_context['admin'] = True email_contents = render_to_string( 'program/modules/teacherclassregmodule/cancelrequest.txt', email_context) email_to = ['Directors <%s>' % (cls.parent_program.director_email)] send_mail(email_title, email_contents, email_from, email_to, False) return self.goToCore(tl)
def send_class_mail_to_directors(self, cls, create = True): mail_ctxt = self.generate_director_mail_context(cls) subject = "Comments for " + cls.emailcode() + ': ' + cls.title if not create: subject = "Re: " + subject # add program email tag subject = '['+self.program.niceName()+'] ' + subject recipients = [teacher.email for teacher in cls.get_teachers()] if recipients: send_mail(subject, \ render_to_string('program/modules/teacherclassregmodule/classreg_email', mail_ctxt) , \ ('%s Class Registration <%s>' % (self.program.program_type, self.program.director_email)), \ recipients, False) if self.program.director_email: mail_ctxt['admin'] = True send_mail(subject, \ render_to_string('program/modules/teacherclassregmodule/classreg_email', mail_ctxt) , \ ('%s Class Registration <%s>' % (self.program.program_type, self.program.director_email)), \ [self.program.getDirectorCCEmail()], False)
def finaid_app(self, request, tl, one, two, module, extra, prog): """ A way for a student to apply for financial aid. """ from datetime import datetime from esp.dbmail.models import send_mail app, created = FinancialAidRequest.objects.get_or_create( user=request.user, program=self.program) class Form(forms.ModelForm): class Meta: model = FinancialAidRequest tag_data = Tag.getTag('finaid_form_fields') if tag_data: fields = tuple(tag_data.split(',')) if request.method == 'POST': form = Form(request.POST, initial=app.__dict__) if form.is_valid(): app.__dict__.update(form.cleaned_data) if not request.POST.has_key('submitform') or request.POST[ 'submitform'].lower() == 'complete': app.done = True elif request.POST['submitform'].lower( ) == 'mark as incomplete' or request.POST['submitform'].lower( ) == 'save progress': app.done = False else: raise ESPError( ), "Our server lost track of whether or not you were finished filling out this form. Please go back and click 'Complete' or 'Mark as Incomplete'." app.save() # Automatically accept apps for people with subsidized lunches if app.reduced_lunch: app.approved = datetime.now() # This probably really wants a template. Oh well. app.save() if app.approved: date_str = str(app.approved) subj_str = '%s %s received Financial Aid for %s' % ( request.user.first_name, request.user.last_name, prog.niceName()) msg_str = "\n%s %s received Financial Aid for %s on %s, for stating that they receive a free or reduced-price lunch." else: date_str = str(datetime.now()) subj_str = '%s %s applied for Financial Aid for %s' % ( request.user.first_name, request.user.last_name, prog.niceName()) msg_str = "\n%s %s applied for Financial Aid for %s on %s, but did not state that they receive a free or reduced-price lunch." send_mail( subj_str, (msg_str + """ Here is their form data: ======================================== Program: %s User: %s %s <%s> Approved: %s Has Reduced Lunch: %s Household Income: $%s Form Was Filled Out by Non-Student: %s Extra Explanation: %s ======================================== This request can be (re)viewed at: <http://%s/admin/program/financialaidrequest/%s/> """) % ( request.user.first_name, request.user.last_name, prog.niceName(), date_str, str(app.program), request.user.first_name, request.user.last_name, str(app.user), date_str, str(app.reduced_lunch), str(app.household_income), str(app.student_prepare), app.extra_explaination, settings.DEFAULT_HOST, # server hostname str(app.id)), settings.SERVER_EMAIL, [prog.director_email]) return self.goToCore(tl) else: form = Form(initial=app.__dict__) return render_to_response(self.baseDir() + 'application.html', request, (self.program, tl), { 'form': form, 'app': app })
def finaid(self,request, tl, one, two, module, extra, prog): """ A way for a student to apply for financial aid. """ from datetime import datetime from esp.dbmail.models import send_mail app, created = FinancialAidRequest.objects.get_or_create(user = request.user, program = self.program) class Form(forms.ModelForm): class Meta: model = FinancialAidRequest tag_data = Tag.getTag('finaid_form_fields') if tag_data: fields = tuple(tag_data.split(',')) else: fields = '__all__' if request.method == 'POST': form = Form(request.POST, initial = app.__dict__) if form.is_valid(): app.__dict__.update(form.cleaned_data) if not 'submitform' in request.POST or request.POST['submitform'].lower() == 'complete': app.done = True elif request.POST['submitform'].lower() == 'mark as incomplete' or request.POST['submitform'].lower() == 'save progress': app.done = False else: raise ESPError("Our server lost track of whether or not you were finished filling out this form. Please go back and click 'Complete' or 'Mark as Incomplete'.") app.save() # Automatically accept apps for people with subsidized lunches # Send an e-mail announcing the application either way date_str = str(datetime.now()) iac = IndividualAccountingController(self.program, request.user) if app.reduced_lunch: iac.grant_full_financial_aid() subj_str = '%s %s received Financial Aid for %s' % (request.user.first_name, request.user.last_name, prog.niceName()) msg_str = "\n%s %s received Financial Aid for %s on %s, for stating that they receive a free or reduced-price lunch." else: subj_str = '%s %s applied for Financial Aid for %s' % (request.user.first_name, request.user.last_name, prog.niceName()) msg_str = "\n%s %s applied for Financial Aid for %s on %s, but did not state that they receive a free or reduced-price lunch." send_mail(subj_str, (msg_str + """ Here is their form data: ======================================== Program: %s User: %s %s <%s> Approved: %s Has Reduced Lunch: %s Household Income: $%s Form Was Filled Out by Non-Student: %s Extra Explanation: %s ======================================== This request can be (re)viewed at: <http://%s/admin/program/financialaidrequest/%s/> """) % (request.user.first_name, request.user.last_name, prog.niceName(), date_str, str(app.program), request.user.first_name, request.user.last_name, str(app.user), date_str, str(app.reduced_lunch), str(app.household_income), str(app.student_prepare), app.extra_explaination, settings.DEFAULT_HOST, # server hostname str(app.id)), settings.SERVER_EMAIL, [ prog.getDirectorConfidentialEmail() ] ) return self.goToCore(tl) else: form = Form(initial = app.__dict__) return render_to_response(self.baseDir()+'application.html', request, {'form': form, 'app': app})
def send_email_requests(): """ Go through all email requests that aren't sent and send them. """ if hasattr(settings, 'EMAILRETRIES') and settings.EMAILRETRIES is not None: retries = settings.EMAILRETRIES else: retries = 2 # default 3 tries total # Find unsent e-mail requests mailtxts = TextOfEmail.objects.filter(Q(sent_by__lte=datetime.now()) | Q(sent_by__isnull=True), sent__isnull=True, locked=False, tries__lte=retries) mailtxts_list = list(mailtxts) # Mark these messages as locked for this send_email_requests call # If the process is killed unexpectedly, then any locked messages will need to be unlocked # TODO: consider a lock on the function, for example by locking a file mailtxts.update(locked=True) if hasattr(settings, 'EMAILTIMEOUT') and settings.EMAILTIMEOUT is not None: wait = settings.EMAILTIMEOUT else: wait = 1.5 num_sent = 0 errors = [] # if any messages failed to deliver for mailtxt in mailtxts_list: try: mailtxt.send() except Exception as e: # Increment tries so that we don't continuously attempt to send this message mailtxt.tries = mailtxt.tries + 1 mailtxt.save() # Queue report about this delivery failure errors.append({'email': mailtxt, 'exception': str(e)}) print "Encountered error while sending to " + str( mailtxt.send_to) + ": " + str(e) else: num_sent += 1 time.sleep(wait) # Unlock the messages as we are done processing them mailtxts.update(locked=False) if num_sent > 0: print 'Sent %d messages' % num_sent # Report any errors if errors: recipients = [mailtxt.send_from] if 'bounces' in settings.DEFAULT_EMAIL_ADDRESSES: recipients.append(settings.DEFAULT_EMAIL_ADDRESSES['bounces']) mail_context = {'errors': errors} send_mail('Mail delivery failure', render_to_string('email/delivery_failed', mail_context), settings.SERVER_EMAIL, recipients)
'class_cap': c.class_size_max, 'section_texts': '\n'.join(section_texts), } subject = email_subject_template % { 'email_code': c.emailcode(), 'title': c.title, } to_address = '*****@*****.**' % c.emailcode() while True: # this is a while loop because send_mail sometimes errors # particularly "too many concurrent SMTP connections" # loop until sending is successful, # or it errors and the user decides not to retry try: send_mail(subject, email_text, from_address, [to_address, from_address], extra_headers=extra_headers) except Exception as e: # print the exception print "An error occurred while sending:", subject import traceback traceback.print_exc() # prompt the user to retry while True: # loop until the user gives a yes or no answer print "Retry (y/n)?", choice = raw_input().lower() if choice in ['y', 'yes']: retry = True break elif choice in ['n', 'no']: retry = False
'section_texts': '\n'.join(section_texts), } subject = email_subject_template % { 'email_code': c.emailcode(), 'title': c.title, } to_address = '*****@*****.**' % c.emailcode() while True: # this is a while loop because send_mail sometimes errors # particularly "too many concurrent SMTP connections" # loop until sending is successful, # or it errors and the user decides not to retry try: send_mail(subject, email_text, from_address, [to_address, from_address], extra_headers=extra_headers) except Exception as e: # print the exception print "An error occurred while sending:", subject import traceback traceback.print_exc() # prompt the user to retry while True: # loop until the user gives a yes or no answer print "Retry (y/n)?", choice = raw_input().lower() if choice in ['y', 'yes']: retry = True break elif choice in ['n', 'no']:
def main(): global NOW, priorityLimit, SR_PROG, SR_REQ, SR_WAIT, SR_EN, PROG, REQ, WAIT, EN, p, students, sections, timeslots, timeslot, all_students global en, req, loc, en_new, cap, score, req_num, wait, changed, unchanged, student save_enrollments = False send_emails = False if "-h" in sys.argv or "--help" in sys.argv: print "Help." return if "--save-enrollments" in sys.argv or "-se" in sys.argv: save_enrollments = True if "--send-emails" in sys.argv: send_emails = True p = None for arg in sys.argv: if arg.startswith("--pk="): p = Program.objects.get(pk=int(arg[5:])) break if not p: return else: print p iscorrect = raw_input("Is this the correct program (y/[n])? ") if not (iscorrect.lower() == 'y' or iscorrect.lower() == 'yes'): return if save_enrollments: iscorrect = raw_input( "Are you sure you want to save the results in the database (y/[n])? " ) if not (iscorrect.lower() == 'y' or iscorrect.lower() == 'yes'): return studentregmodule = p.getModuleExtension('StudentClassRegModuleInfo') if studentregmodule and studentregmodule.priority_limit > 0: priorityLimit = studentregmodule.priority_limit SR_PROG = Q(studentregistration__section__parent_class__parent_program=p, studentregistration__start_date__lte=NOW, studentregistration__end_date__gte=NOW) SR_REQ = Q(studentregistration__relationship__name="Request") & SR_PROG SR_WAIT = [ Q(studentregistration__relationship=("Waitlist/%s" % str(i + 1))) & SR_PROG for i in range(priorityLimit) ] SR_WAIT.append( Q(studentregistration__relationship__contains="Waitlist") & SR_PROG) SR_EN = Q(studentregistration__relationship__name="Enrolled") & SR_PROG PROG = Q(section__parent_class__parent_program=p, start_date__lte=NOW, end_date__gte=NOW) REQ = Q(relationship__name="Request") & PROG WAIT = [Q(relationship__name__contains="Waitlist") & PROG] WAIT += [ Q(relationship__name=("Waitlist/%s" % str(i + 1))) & PROG for i in range(priorityLimit) ] EN = Q(relationship__name="Enrolled") & PROG timeslots = p.getTimeSlots() for timeslot in timeslots: print "Setup for", timeslot, "....", sys.stdout.flush() en = {} req = {} loc = {} en_new = {} cap = {} score = {} req_num = {} wait = {} sections = list(p.sections().filter(status=10, meeting_times=timeslot)) class ClassSectionNull: def __init__(self): self.limbo = [] def __repr__(self): return "<NullSection>" NullSection = ClassSectionNull() en[NullSection] = [[]] cap[NullSection] = 0 score[NullSection] = 0 for i in range(len(sections)): en[sections[i]] = [[] for j in range(priorityLimit + 2)] req[sections[i]] = [[] for j in range(priorityLimit + 2)] en_new[sections[i]] = [] cap[sections[i]] = sections[i].capacity - sections[i].num_students( ) req_num[sections[i]] = 0 score[sections[i]] = -cap[sections[i]] students = ESPUser.objects.filter( SR_REQ, studentregistration__section__meeting_times=timeslot) all_students |= set(students) for i in range(students.count()): req[students[i]] = StudentRegistration.objects.get( REQ, user=students[i], section__meeting_times=timeslot).section loc[students[i]] = StudentRegistration.objects.get( REQ, user=students[i], section__meeting_times=timeslot).section req[req[students[i]]][0].append(students[i]) req_num[req[students[i]]] += 1 score[req[students[i]]] += 1 try: en[students[i]] = StudentRegistration.objects.get( EN, user=students[i], section__meeting_times=timeslot).section except Exception: en[students[i]] = NullSection en[en[students[i]]][0].append(students[i]) cap[en[students[i]]] += 1 score[en[students[i]]] -= 1 try: wait[students[i]] = int( StudentRegistration.objects.get( WAIT[0], user=students[i], section__meeting_times=timeslot, section=req[students[i]]).relationship.name.partition( "/")[2]) except Exception: wait[students[i]] = priorityLimit + 1 req[req[students[i]]][wait[students[i]]].append(students[i]) en[req[students[i]]][wait[students[i]]].append(students[i]) cap[NullSection] = 0 score[NullSection] = 0 print " done!" print "Randomly assigning students to classes by priority ....", sys.stdout.flush() for i in range(len(sections)): for j in range(1, priorityLimit + 2): if len(en[sections[i]][j]) > cap[sections[i]]: random.shuffle(en[sections[i]][j]) for k in range(cap[sections[i]], len(en[sections[i]][j])): NullSection.limbo.append(en[sections[i]][j][k]) loc[en[sections[i]][j][k]] = NullSection en[sections[i]][j] = en[sections[i]][j][:( cap[sections[i]])] for k in range(j + 1, priorityLimit + 2): for l in range(len(en[sections[i]][k])): NullSection.limbo.append(en[sections[i]][k][l]) loc[en[sections[i]][k][l]] = NullSection en[sections[i]][k] = [] cap[sections[i]] -= len(en[sections[i]][j]) en_new[sections[i]] += en[sections[i]][j] if not cap[sections[i]]: break print " done!" print "Pushing students back to original classes...", sys.stdout.flush() a = 0 limbo_orig = NullSection.limbo[:] limbo_all = [set()] while len(NullSection.limbo): a += 1 limbo_all.append(set()) limbo_old = NullSection.limbo[:] NullSection.limbo = [] for i in range(len(limbo_old)): limbo_all[0].add(limbo_old[i]) limbo_all[a].add(limbo_old[i]) if en[limbo_old[i]] == NullSection: continue if isinstance(en_new[en[limbo_old[i]]], list) and len( en_new[en[limbo_old[i]]]): pq = Queue.PriorityQueue() random.shuffle(en_new[en[limbo_old[i]]]) b = 0 for student in en_new[en[limbo_old[i]]]: pq.put((score[en[student]], student), False) b += 1 en_new[en[limbo_old[i]]] = pq if not cap[en[limbo_old[i]]]: move = en_new[en[limbo_old[i]]].get(False)[1] sys.stdout.flush() loc[move] = NullSection NullSection.limbo.append(move) else: cap[en[limbo_old[i]]] -= 1 loc[limbo_old[i]] = en[limbo_old[i]] print " done!" print "Saving enrollments ....", sys.stdout.flush() for student in students: if loc[student] != en[student] and loc[student] != NullSection: if save_enrollments: loc[student].preregister_student(student) if en[student] != NullSection: en[student].unpreregister_student(student) changed.add(student) else: unchanged.add(student) print " done!\n\n" sys.stdout.flush() unchanged -= changed print "Sending emails...." from django.conf import settings if hasattr(settings, 'EMAILTIMEOUT') and \ settings.EMAILTIMEOUT is not None: timeout = settings.EMAILTIMEOUT else: timeout = 2 f = open("classchanges.txt", 'w') from esp.dbmail.models import send_mail, MessageRequest, TextOfEmail subject = "[" + p.niceName() + "] Class Change" from_email = p.director_email bcc = p.director_email extra_headers = {} extra_headers['Reply-To'] = p.director_email for student in changed: text = "<html>\nHello " + student.first_name + ",<br /><br />\n\n" text += "We've processed your class change request, and have updated your schedule. Your new schedule is as follows: <br /><br />\n\n" text += get_student_schedule(student) + "\n\n<br /><br />\n\n" text += "We hope you enjoy your new schedule. See you soon!<br /><br />" text += "The " + p.niceName() + " Directors\n" text += "</html>" recipient_list = [student.email] print text, "\n\nSent to", student.username, "<", student.email, ">\n\n------------------------\n\n" f.write( text.replace(u'\u2019', "'").replace(u'\u201c', '"').replace( u'\u201d', '"') + "\n\nSent to " + student.username + "\n\n------------------------\n\n") if save_enrollments and send_emails: send_mail(subject, text, from_email, recipient_list, bcc=bcc, extra_headers=extra_headers) time.sleep(timeout) for student in unchanged: text = "<html>\nHello " + student.first_name + ",<br /><br />\n\n" text += "We've processed your class change request, and unfortunately are unable to update your schedule. Your schedule is still as follows: <br /><br />\n\n" text += get_student_schedule(student) + "\n\n<br /><br />\n\n" text += "See you soon!<br /><br />" text += "The " + p.niceName() + " Directors\n" text += "</html>" recipient_list = [student.email] print text, "\n\nSent to", student.username, "<", student.email, ">\n\n------------------------\n\n" f.write( text.replace(u'\u2019', "'").replace(u'\u201c', '"').replace( u'\u201d', '"') + "\n\nSent to " + student.username + "\n\n------------------------\n\n") if save_enrollments and send_emails: send_mail(subject, text, from_email, recipient_list, bcc=bcc, extra_headers=extra_headers) time.sleep(timeout) return 0
def send_email_requests(): """Go through all email requests that aren't sent and send them. Callers (e.g. dbmail_cron.py) should ensure that this function is not called in more than one thread simultaneously.""" now = datetime.now() one_week_ago = now - _ONE_WEEK retries = getattr(settings, 'EMAILRETRIES', None) if retries is None: # previous code thought that settings.EMAILRETRIES might be set to None # to be the default, rather than being undefined, so we keep that # behavior. retries = 2 # i.e. 3 tries total # Choose a set of emails to process. Anything which arrives later will # not be processed by this run of the script. Any outstanding requests # which were created over one week ago are assumed to be out-of-date, and # are ignored. mailtxts = TextOfEmail.objects.filter(Q(sent_by__lte=now) | Q(sent_by__isnull=True), created_at__gte=one_week_ago, sent__isnull=True, tries__lte=retries) mailtxts_list = list(mailtxts) wait = getattr(settings, 'EMAILTIMEOUT', None) if wait is None: wait = 1.5 num_sent = 0 errors = [] # if any messages failed to deliver for mailtxt in mailtxts_list: exception = mailtxt.send() if exception is not None: errors.append({'email': mailtxt, 'exception': str(exception)}) logger.warning("Encountered error while sending to %s: %s", mailtxt.send_to, exception) else: num_sent += 1 time.sleep(wait) if num_sent > 0: logger.info('Sent %d messages', num_sent) # Report any errors if errors: recipients = [mailtxt.send_from] if 'bounces' in settings.DEFAULT_EMAIL_ADDRESSES: recipients.append(settings.DEFAULT_EMAIL_ADDRESSES['bounces']) mail_context = {'errors': errors} delivery_failed_string = render_to_string('email/delivery_failed', mail_context) logger.warning('Mail delivery failure: %s', delivery_failed_string) # TODO(benkraft): this is probably redundant with the logging now? (or # rather, it will be if we log at the right level?) send_mail('Mail delivery failure', delivery_failed_string, settings.SERVER_EMAIL, recipients) elif num_sent > 0: logger.info('No mail delivery failures')