def ratemeeting(request, rmid, email=None): try: rfmeeting = RapidMeeting.objects.get(id=rmid) except: msg = "Invalid meeting id: " + str(rmid) LogWarning(msg) return render_to_response('error.html', { 'message': msg, 'menu': generate_error_menu(request), }, context_instance=RequestContext(request)) try: pid = int(email) pi = NSFInvestigator.objects.get(id=pid) except: try: pi = NSFInvestigator.objects.get(email=email) except: msg = "No PI found for email: " + email LogWarning(msg) return render_to_response('error.html', { 'message': msg, 'menu': generate_error_menu(request), }, context_instance=RequestContext(request)) participants = rfmeeting.getParticipants() try: participants.remove(pi) except ValueError: msg = "Invalid request: can only rate meetings in which you were a participant!" msg += "\n<br><p>Meeting: " + rfmeeting.displayMeeting() + " </p>" LogWarning(msg) return render_to_response('error.html', { 'message': msg, 'menu': generate_error_menu(request), }, context_instance=RequestContext(request)) ratingform = RatingForm() ratingform.fields['participants'].choices = [ (str(pname.id), pname.displayNameInst() if not pname.noshow else pname.displayNameInst() + ' [Did not attend meeting]') for pname in participants ] ratingform.initial['participants'] = [ str(pname.id) for pname in participants if not pname.noshow ] return render_to_response('ratedates.html', { 'pi': pi, 'rfid': rfmeeting.id, 'round': rfmeeting.round, 'menu': generate_menu(request), 'form': ratingform, }, context_instance=RequestContext(request))
def selectProjectsFromRequest(cls, request, institution=None): startafter = request.GET.get('startafter') startbefore = request.GET.get('startbefore') endafter = request.GET.get('endafter') endbefore = request.GET.get('endbefore') if limitActive(request) and not endafter: endafter = datetime.date.today().isoformat() minamount = request.GET.get('minamount') if minamount: try: minamount = int(minamount) except: LogWarning("Cannot convert minamount: " + minamount) minamount = None maxamount = request.GET.get('maxamount') if maxamount: try: maxamount = int(maxamount) except: LogWarning("Cannot convert maxamount: " + maxamount) maxamount = None if not institution: institution = request.GET.get('institution') if institution: try: institutionid = int(institution) institution = Institutions.objects.get(id=institutionid) except: LogWarning("Error with institution parameter: " + institution) institution = None pi = request.GET.get('pi') satc = isSaTC(request) attending = (scope(request) == 'attending') if attending: satc = True # this is just for limiting processing, but misses non-satc return cls.selectProjects(satc=satc, attending=attending, startafter=startafter, startbefore=startbefore, endafter=endafter, endbefore=endbefore, pi=pi, institution=institution, minamount=minamount, maxamount=maxamount)
def process_poster(row, header): presenters = [] presenter = row[header.index('Poster Presenter')] presenter2 = row[header.index('Poster Presenter 2')] presenter3 = row[header.index('Poster Presenter 3')] title = row[header.index('Poster name')] try: pi = NSFInvestigator.objects.get(email = presenter) presenters.append(pi) # LogMessage("Poster presenter: " + pi.fullDisplay()) except: LogWarning("No matching PI: " + presenter + " for " + title) pi2 = None if len(presenter2) > 1: try: pi2 = NSFInvestigator.objects.get(email = presenter2) presenters.append(pi2) # LogMessage("Poster presenter: " + pi2.fullDisplay()) except: LogWarning("No matching PI for presenter 2: " + presenter2) pi3 = None if len(presenter3) > 1: try: pi3 = NSFInvestigator.objects.get(email = presenter3) presenters.append(pi3) # LogMessage("Poster presenter: " + pi3.fullDisplay()) except: LogWarning("No matching PI for presenter 3: " + presenter3) project = None try: project = NSFProject.objects.get(awardID=row[header.index('NSF Grant Number')]) except: LogWarning("No matching project: " + row[header.index('NSF Grant Number')] + " for " + title) poster = None try: poster = Posters.objects.get(title=title) poster.project=project poster.save() PosterPresenters.objects.delete(poster=poster) LogWarning("Poster already exists: " + title + " -> updated") except: poster = Posters.objects.create(title=title, project=project) # print "Poster: " + title for pi in presenters: PosterPresenters.objects.create(poster=poster, presenter=pi)
def lookupMatchingPI(email): if email: pis = NSFInvestigator.objects.filter(email=email) if len(pis) == 1: pi = pis[0] else: if len(pis) == 0: LogWarning("No matching pi for: " + email) assert False pi = None else: LogWarning("Multiple matching pis for: " + email) pi = pis[0] return pi return None
def addPI(email, firstname, lastname, institution, cityname=None, statename=None): pi = NSFInvestigator.objects.filter(email=email) if pi.count() > 0: [eachpi.delete() for eachpi in pi] LogWarning("Duplicate add: " + email) else: inst = Institutions.objects.filter(name=institution) if inst.count() == 0: instobj = Institutions.objects.create(name=institution, cityname=cityname, statename=statename) instobj.save() else: instobj = inst[0] pi = NSFInvestigator.objects.create(email=email, firstname=firstname, lastname=lastname, institution=instobj, satc=True, attendee=True) print "Added PI: " + pi.fullDisplay() return pi
def breakout(request, bid): LogRequest(request, "Breakout: " + str(bid)) breakout = Breakout.objects.filter(number=bid) if breakout.count() < 1: msg = "No breakout for id: " + str(bid) LogWarning(msg) return render_to_response('error.html', { 'message': msg, 'menu': generate_error_menu(request), }, context_instance=RequestContext(request)) assert breakout.count() == 1 breakout = breakout[0] participantobjs = BreakoutParticipant.objects.filter(breakout=breakout) pis = [ participant.pi for participant in participantobjs if not participant.leader ] leaders = [ participant.pi for participant in participantobjs if participant.leader ] pis.sort(key=lambda r: r.lastname + ' ' + r.firstname) leaders.sort(key=lambda r: r.lastname + ' ' + r.firstname) return render_to_response('breakout.html', { 'menu': generate_menu(request), 'breakout': breakout, 'leaders': leaders, 'pis': pis, }, context_instance=RequestContext(request))
def check_logged_in(request): userid = request.user if not userid: return error_response( request, "No user logged in. Must be logged in to view this page.") email = userid.email try: pi = NSFInvestigator.objects.get(email=email) return pi except: msg = "No PI found for email: " + str(email) + """ <br><p> To login, you must use the email address associated with your NSF profile. You should have received this in an email, but if not you can find yourself in the <a href="/pis?scope=attending">list of attending PIs</a>. If you do not find yourself in that list, or you are not able to access the email account associated with your NSF grant, please <a href="mailto:[email protected]">contact us</a>. """ LogWarning(msg) return render_to_response('error.html', { 'message': msg, 'menu': generate_error_menu(request), }, context_instance=RequestContext(request))
def project(request, abstractid): LogRequest(request, "project: " + str(abstractid)) try: project = NSFProject.objects.get(awardID=abstractid) except: msg = "No project found for award ID: " + str(abstractid) LogWarning(msg) return render_to_response('error.html', { 'message': msg, 'menu': generate_error_menu(request), }, context_instance=RequestContext(request)) pis = project.getPIs() collabs = uniq( [c.project2 for c in CollabProjects.objects.filter(project1=project)]) collabpis = uniq([(p.investigator, collab) for collab in collabs for p in ProjectPIs.objects.filter(project=collab)]) collabpis.sort(key=lambda r: r[0].lastname) amount = format_amount(project.amount) return render_to_response('project.html', { 'project': project, 'menu': generate_menu(request), 'amount': amount, 'pis': pis, 'collabs': collabs, 'collabpis': collabpis }, context_instance=RequestContext(request))
def error_response(request, msg): LogWarning(msg) return render_to_response('error.html', { 'message': msg, 'menu': generate_error_menu(request), }, context_instance=RequestContext(request))
def loadBreakouts(breakouts, fname): shortnames = {} bleaders = {} for breakout in breakouts: (number, session, room, tag, shortname, leaders, description) = breakout shortnames[tag] = number LogMessage("shortnames: " + tag + " = " + str(number)) bleaders[number] = leaders LogMessage("Adding breakout: " + str(number) + ": " + shortname) Breakout.objects.create(number=number, title=shortname, description=description, location=room, session=session) with open(fname, 'rU') as file: reader = csv.reader(file, dialect="excel") firstRow = True for row in reader: if firstRow: header = row print "Read header: " + str(header) firstRow = False continue nsfemail = row[header.index('NSF Email')] breakout = row[header.index('Breakout')] if not breakout: LogMessage("No breakout for: " + row[header.index('First Name')] + " " + row[header.index('Last Name')]) continue if not nsfemail: LogWarning("No nsfemail: " + row[header.index('First Name')] + " " + row[header.index('Last Name')]) continue # for now...should fail! if breakout == 'Excluded' or breakout == 'Keynote': LogMessage("Excluded: " + row[header.index('First Name')] + " " + row[header.index('Last Name')]) continue pi = lookupMatchingPI(nsfemail) bnum = shortnames[breakout] bobjs = Breakout.objects.filter(number=bnum) assert bobjs.count() == 1 bobj = bobjs[0] leader = pi.email in bleaders[bnum] LogMessage("Adding breakout participant " + pi.displayName() + " to " + bobj.title + " leader: " + str(leader)) BreakoutParticipant.objects.create(breakout=bobj, pi=pi, leader=leader)
def lookupAddInvestigator(self, firstname, lastname, email, institution): # -> Researcher if email in self.investigators: researcher = self.investigators[email] if researcher.firstname != firstname: LogWarning("Firstnames do not match for " + email + ": " + str(researcher) + " / " + firstname) if researcher.lastname != lastname: LogWarning("Lastnames do not match for " + email + ": " + str(researcher) + " / " + lastname) if researcher.institution != institution: LogWarning("Institutions do not match for " + email + ": " + str(researcher) + " / " + institution) researcher.institution = institution # update to new institution! return researcher else: researcher = Researcher(firstname, lastname, email, institution) self.investigators[email] = researcher return researcher
def sessionTime(self): if self.session == 1: return "Monday, 1:30-3:00pm" elif self.session == 2: return "Tuesday, 1:30-3:00pm" elif self.session == 3: return "Tuesday, 3:30-5:00pm" else: LogWarning("Bad session time: " + str(self.session)) return "[Session Error]"
def selectLocation(spaces, meeting, round, pi1, pi2, pi3, pi4): # assumes rounds are processed in order print "Finding location for: " + str(meeting) round = round - 1 # offset by 1 if round == 0: location = findNearestOpenLocation(spaces[round], random.randint(0, MAXLOCATION - 1)) spaces[round][location] = meeting else: closest = None distance = None for pi in [pi1, pi2, pi3, pi4]: if pi: lastround = RapidMeeting.objects.filter( pi1=pi) | RapidMeeting.objects.filter( pi2=pi) | RapidMeeting.objects.filter( pi3=pi) | RapidMeeting.objects.filter(pi4=pi) lastround = lastround.filter(round=round) # note: round is -1 if lastround.count() == 1: lastlocation = lastround[0].location nearest = findNearestOpenLocation(spaces[round], lastlocation) if (not closest) or ( abs(lastlocation - nearest) < distance) or ( abs(lastlocation - nearest) == distance and random.randint(0, 1) == 0): closest = nearest distance = abs(lastlocation - nearest) print("Found better location: " + str(closest) + " (distance " + str(distance) + " for " + pi.displayName() + ")") else: if lastround.count() == 0: LogWarning("No previous round for " + pi.displayName()) else: LogWarning("Multiple previous rounds for " + pi.displayName()) assert closest location = closest return location
def piEmail(request, email): try: pi = NSFInvestigator.objects.get(email=email) except: msg = "No PI found for email: " + email LogWarning(msg) return render_to_response('error.html', { 'message': msg, 'menu': generate_error_menu(request), }, context_instance=RequestContext(request)) return displayPI(request, pi)
def findNearestOpenLocation(spaces, start): # print("Finding nearest open to " + str(start) + "..." + str(MAXLOCATION)) for offset in range(0, MAXLOCATION / 2): # print("Try offset: " + str(offset)) if spaces[(start + offset) % MAXLOCATION] == -1: # print("Found open location: " + str((start + offset) % MAXLOCATION)) return (start + offset) % MAXLOCATION if spaces[(start - offset) % MAXLOCATION] == -1: # print("Found open - location: " + str((start - offset) % MAXLOCATION)) return (start - offset) % MAXLOCATION LogWarning("No open locations!") assert False
def pi(request, userid): LogRequest(request, "pi: " + str(userid)) try: pi = NSFInvestigator.objects.get(id=userid) except: msg = "No PI found for id: " + str(userid) LogWarning(msg) return render_to_response('error.html', { 'message': msg, 'menu': generate_error_menu(request), }, context_instance=RequestContext(request)) return displayPI(request, pi)
def schedule(pi): rm = RapidMeeting.objects.filter(pi1=pi) | RapidMeeting.objects.filter(pi2=pi) | RapidMeeting.objects.filter(pi3=pi) | RapidMeeting.objects.filter(pi4=pi) rm = rm.order_by('round') # LogMessage("rapid meeting 1: " + ' / '.join([m.displayMeeting() for m in rm])) # lots of sanity checking to do here... posterobj = PosterPresenters.objects.filter(presenter=pi) if posterobj: poster = posterobj[0].poster else: poster = None breakout1 = None breakout2 = None breakout3 = None breakoutleader = False breakout1leader = False breakout2leader = False breakout3leader = False breakouts = BreakoutParticipant.objects.filter(pi=pi) for bobj in breakouts: breakout = bobj.breakout leader = bobj.leader if leader: breakoutleader = True if breakout.session == 1: assert not breakout1 breakout1 = breakout breakout1leader = leader elif breakout.session == 2: assert not breakout2 breakout2 = breakout breakout2leader = leader elif breakout.session == 3: assert not breakout3 breakout3 = breakout breakout3leader = leader else: LogWarning("Bad breakout session: " + breakout.title) return latex_schedule(pi, rm, poster, breakout1, breakout2, breakout3, breakoutleader, breakout1leader, breakout2leader, breakout3leader)
def institution(request, institutionid): satc = isSaTC(request) try: institution = Institutions.objects.get(id=institutionid) except: msg = "No institution for id: " + str(institutionid) LogWarning(msg) return render_to_response('error.html', { 'message': msg, 'menu': generate_error_menu(request), }, context_instance=RequestContext(request)) projects, explanation = NSFProject.selectProjectsFromRequest( request, institution=institution) totalawarded = format_amount(sum([project.amount for project in projects])) pis = project_pis(projects) if scope(request) == 'attending': pis = [pi for pi in pis if pi.attendee] pis.sort(key=lambda r: r.lastname + ' ' + r.firstname) # include all projects with (relevant) PIs # use projects only for scoped projects piprojects, _ = NSFProject.selectProjects(satc=False, institution=institution) graph = generate_graph(tuple(piprojects), tuple(project_pis(projects))) return render_to_response('institution.html', { 'institution': institution, 'menu': generate_menu(request), 'satc': satc, 'pis': pis, 'projects': projects, 'json_str': graph, 'explanation': explanation, 'totalawarded': totalawarded }, context_instance=RequestContext(request))
def displayPI(request, pi): piprojects = ProjectPIs.objects.filter(investigator=pi) projects = sorted(uniq([p.project for p in piprojects if p.project]), key=lambda proj: proj.startDate) totalawarded = format_amount(sum([project.amount for project in projects])) collaborators = getCollaborators(projects) try: collaborators.remove(pi) except: LogWarning("Not a self-collaborator: " + pi.fullDisplay()) institutions = pi.getInstitutions() return render_to_response('pi.html', { 'pi': pi, 'menu': generate_menu(request), 'totalawarded': totalawarded, 'institutions': institutions, 'projects': projects, 'collaborators': collaborators }, context_instance=RequestContext(request))
def submitrating(request, rmid, email=None): try: rfmeeting = RapidMeeting.objects.get(id=rmid) except: msg = "Invalid meeting id: " + str(rmid) LogWarning(msg) return render_to_response('error.html', { 'message': msg, 'menu': generate_error_menu(request), }, context_instance=RequestContext(request)) try: pid = int(email) pi = NSFInvestigator.objects.get(id=pid) except: try: pi = NSFInvestigator.objects.get(email=email) except: msg = "No PI found for email: " + email LogWarning(msg) return render_to_response('error.html', { 'message': msg, 'menu': generate_error_menu(request), }, context_instance=RequestContext(request)) if request.method != 'POST': return error_response(request, 'POST request expected') rpi1 = None rpi1present = False rpi2 = None rpi2present = False rpi3 = None rpi3present = False if 'participants' in request.POST: participants = request.POST.getlist('participants') ## yuck! not for consumption by cs101 students... if len(participants) >= 1: try: rpi1 = getPI(participants[0]) except: return error_response(request, 'No PI found for: ' + participants[0]) rpi1present = True if len(participants) >= 2: rpi2 = getPI(participants[1]) rpi2present = True if len(participants) >= 3: rpi3 = getPI(participants[2]) rpi3present = True if 'guessreason' in request.POST: guessreason = request.POST['guessreason'] else: guessreason = None if 'matchquality' in request.POST: try: matchquality = int(request.POST['matchquality']) except: msg = "Cannot convert quality to value: " + request.POST[ 'matchquality'] LogWarning(msg) return render_to_response('error.html', { 'message': msg, 'menu': generate_error_menu(request), }, context_instance=RequestContext(request)) else: matchquality = None if 'comments' in request.POST: comments = request.POST['comments'] else: comments = None msg = "" oldrme = RapidMeetingEval.objects.filter(rm=rfmeeting, pi=pi) if oldrme.count() > 0: LogWarning( "Duplicate rating recieved. This rating will replace previous rating: " + rfmeeting.displayMeetingReason() + " / pi: " + pi.displayName()) rme = RapidMeetingEval.objects.create(rm=rfmeeting, pi=pi, rpi1=rpi1, rpi1present=rpi1present, rpi2=rpi2, rpi2present=rpi2present, rpi3=rpi3, rpi3present=rpi3present, guessreason=guessreason, matchquality=matchquality, comments=comments) rme.save() if rfmeeting.round < 4: nextround = rfmeeting.round + 1 nextmeeting = RapidMeeting.objects.filter(round=nextround, pi1=pi) \ | RapidMeeting.objects.filter(round=nextround, pi2=pi) \ | RapidMeeting.objects.filter(round=nextround, pi3=pi) \ | RapidMeeting.objects.filter(round=nextround, pi4=pi) if nextmeeting.count() == 1: return ratemeeting(request, nextmeeting[0].id, pi.email) else: msg = "No meeting found for round " + str(nextround) LogWarning(msg) return render_to_response('error.html', { 'message': msg, 'menu': generate_error_menu(request), }, context_instance=RequestContext(request)) else: rmos = RapidMeeting.objects.filter( pi1=pi) | RapidMeeting.objects.filter( pi2=pi) | RapidMeeting.objects.filter( pi3=pi) | RapidMeeting.objects.filter(pi4=pi) rmos = rmos.order_by('round') report = "" for rfm in rmos: report += "<p><b>Meeting " + str(rfm.round) + "</b><blockquote>" ## # report += str(rfm.id) + " for " + str(pi.id) + "</br>" report += ', '.join( [pid.displayLinkName() for pid in rfm.getParticipants()]) + "<br>" realreason = rfm.reason if realreason == 'similar-topics' or realreason == 'dissimilar-topics': realreason = 'bug' rmes = RapidMeetingEval.objects.filter(pi=pi, rm=rfm) if rmes.count() == 0: rme = None report += "<span class=\"warning\">Error: no evaluation for: " + str( rfm.id) + " by " + str(pi.id) + ".</span><br>" elif rmes.count() > 1: report += "<span class=\"warning\">Warning: multiple ratings found for this meeting. Using last rating.</span><br>" rme = rmes.latest('id') # assert rme.id == rfm.id else: rme = rmes[0] if rme: assert rme.rm == RapidMeeting.objects.get(id=rfm.id) assert rme.rm == rfm if not rme.guessreason: report += "No guessed reason recorded" else: if rme.guessreason == 'bug': report += "Guessed reason: Bug in implementation" else: report += "Guessed reason: " + displayReason( rme.guessreason) report += "<br>Actual reason: " + displayReason(realreason) if not realreason == 'bug': report += " (Score: " + str(rfm.score) + ")" report += "</br></blockquote></p>" return render_to_response('finishedratings.html', { 'menu': generate_error_menu(request), 'pi': pi, 'report': report, }, context_instance=RequestContext(request))
def after(request, email=None): ## todo: support token login allgood = False tok = request.GET.get('tok') if not email: return error_response(request, "No email provided.") if not tok: return error_response(request, "No authentication token provided.") if tok == key_from_email(email): # all good! allgood = True request.user = User(email=email, username=email) else: # return error_response(request, "Expected token: " + str(key_from_email(email)) + " got token " + str(tok) + " for email: " + str(email)) return error_response( request, "Bad token provided! (This server is unhackable. Please don't try!)" ) if not allgood and not request.user.is_authenticated(): if email: LogRequest(request, "Rate meetings for: " + email) msg = "To see this page, you must login as " + email + """. Authentication is done using Mozilla's <a href="https://www.mozilla.org/en-US/persona/">Persona</a> single sign-on service with your NSF email address.""" else: msg = """To see this page, you must be logged in. Authentication is done using Mozilla's <a href="https://www.mozilla.org/en-US/persona/">Persona</a> single sign-on service with your NSF email address.""" return render_to_response('login.html', { 'message': msg, 'menu': generate_error_menu(request), }, context_instance=RequestContext(request)) userid = request.user if not userid.email == email and not user_has_superpowers(request.user): return render_to_response('error.html', { 'message': "Authentication error: email mismatch.", 'menu': generate_error_menu(request), }, context_instance=RequestContext(request)) try: pid = int(email) pi = NSFInvestigator.objects.get(id=pid) except: try: pi = NSFInvestigator.objects.get(email=email) except: msg = "No PI found for email: " + email LogWarning(msg) return render_to_response('error.html', { 'message': msg, 'menu': generate_error_menu(request), }, context_instance=RequestContext(request)) rm = RapidMeeting.objects.filter(pi1=pi) | RapidMeeting.objects.filter(pi2=pi) \ | RapidMeeting.objects.filter(pi3=pi) | RapidMeeting.objects.filter(pi4=pi) rm = rm.order_by('round') if rm.count() == 0: return error_response(request, "No meetings to rate for " + pi.displayName()) else: return ratemeeting(request, rm[0].id, pi.email)
def schedule(request, email): # TODO: check logged in! LogRequest(request, "View schedule: " + email) try: pid = int(email) pi = NSFInvestigator.objects.get(id=pid) except: try: pi = NSFInvestigator.objects.get(email=email) except: msg = "No PI found for email: " + email LogWarning(msg) return render_to_response('error.html', { 'message': msg, 'menu': generate_error_menu(request), }, context_instance=RequestContext(request)) # rapid meetings # this is kludgey...should have used a separate table rm = RapidMeeting.objects.filter(pi1=pi) | RapidMeeting.objects.filter( pi2=pi) | RapidMeeting.objects.filter( pi3=pi) | RapidMeeting.objects.filter(pi4=pi) rm = rm.order_by('round') # lots of sanity checking to do here... posterobj = PosterPresenters.objects.filter(presenter=pi) if posterobj: poster = posterobj[0].poster else: poster = None breakout1 = None breakout2 = None breakout3 = None breakoutleader = False breakout1leader = False breakout2leader = False breakout3leader = False breakouts = BreakoutParticipant.objects.filter(pi=pi) for bobj in breakouts: breakout = bobj.breakout leader = bobj.leader if leader: breakoutleader = True if breakout.session == 1: assert not breakout1 breakout1 = breakout breakout1leader = leader elif breakout.session == 2: assert not breakout2 breakout2 = breakout breakout2leader = leader elif breakout.session == 3: assert not breakout3 breakout3 = breakout breakout3leader = leader else: LogWarning("Bad breakout session: " + breakout.title) return render_to_response('schedule.html', { 'pi': pi, 'menu': generate_menu(request), 'rm': rm, 'poster': poster, 'breakout1': breakout1, 'breakout2': breakout2, 'breakout3': breakout3, 'breakoutleader': breakoutleader, 'breakout1leader': breakout1leader, 'breakout2leader': breakout2leader, 'breakout3leader': breakout3leader, }, context_instance=RequestContext(request))
def delete_project(award): try: bad = NSFProject.objects.get(awardID=award) bad.delete() except: LogWarning("Cannot find project to delete: " + award)
def email_poster(row, header): sys.exit("Don't email unless you really mean it!") presenters = [] presenter = row[header.index('Poster Presenter')] presenter2 = row[header.index('Poster Presenter 2')] presenter3 = row[header.index('Poster Presenter 3')] title = row[header.index('Poster name')] try: pi = NSFInvestigator.objects.get(email = presenter) presenters.append(pi) # LogMessage("Poster presenter: " + pi.fullDisplay()) except: LogWarning("No matching PI: " + presenter) pi2 = None if len(presenter2) > 1: try: pi2 = NSFInvestigator.objects.get(email = presenter2) presenters.append(pi2) # LogMessage("Poster presenter: " + pi2.fullDisplay()) except: LogWarning("No matching PI for presenter 2: " + presenter2) pi3 = None if len(presenter3) > 1: try: pi3 = NSFInvestigator.objects.get(email = presenter3) presenters.append(pi3) # LogMessage("Poster presenter: " + pi3.fullDisplay()) except: LogWarning("No matching PI for presenter 3: " + presenter3) project = None try: project = NSFProject.objects.get(awardID=row[header.index('NSF Grant Number')]) except: LogWarning("No matching project: " + row[header.index('NSF Grant Number')]) msg = "Dear " msg += ', '.join([pi.firstname + " " + pi.lastname for pi in presenters]) msg += ":\n" msg += """ Thank you for requesting to present a poster at the NSF SaTC PIs Meeting. Your poster: """ msg += " " + title + "\n" msg += """ has been accepted for presentation. The poster session will be held Monday, January 5 in the evening. You should bring a printed poster to the session. We will provide an easel and 3' x 4' poster board. Feel free to also bring any printed materials you would like to distribute. Thank you for your contribution to the meeting, and I look forward to seeing you at the meeting. Best, --- Dave ======================================== David Evans http://www.cs.virginia.edu/evans Organizer, NSF SaTC PIs Meeting """ print msg sender = 'SaTC PIs Meeting<*****@*****.**>' recipients = [pi.email for pi in presenters] # recipients = ['*****@*****.**', '*****@*****.**'] msg = MIMEText(msg) msg['Subject'] = 'SaTC PIs Meeting Poster: ' + title msg['From'] = sender msg['To'] = ', '.join(recipients) msg['Cc'] = '*****@*****.**' msg['Reply-To'] = '*****@*****.**' s = smtplib.SMTP('smtp.gmail.com',587) s.set_debuglevel(1) s.ehlo() s.starttls() s.login("*****@*****.**", "qpjsmodegdkkzptg") s.sendmail(sender, recipients, msg.as_string()) s.quit() print "Sent message: " + msg.as_string() print "sleeping..." time.sleep(5 + len(msg['To'])) # sys.exit("Done!") if False: poster = None try: poster = Posters.objects.get(title=title) poster.project=project poster.save() LogWarning("Poster already exists: " + title + " -> updated") return except: poster = Posters.objects.create(title=title, project=project) print "Poster: " + title for pi in presenters: PosterPresenters.objects.create(poster=poster, presenter=pi) print " " + pi.lastname, print