def _mail_html(gcn, mail_to, clobber=False, tweet=True, out_url_path='http://swift.qmorgan.com/', grbhtml=None): if not hasattr(gcn, 'mailed_web'): gcn.mailed_web = False if not gcn.mailed_web: email_subject = 'New Web Page for Swift trigger %i' % int( gcn.triggerid) email_body = '''Please visit %s%i/ for information on this event, updated as more information arrives.''' % ( out_url_path, int(gcn.triggerid)) # Crap, the following doesn't work because of clobber=True when reloading new GCNs # EVENTUALL UPDATE SO WE DON'T RELOAD THE ENTIRE GCN EACH TIME, JUST ADD THE NEW NOTICES? # gcn.mailed_web = True # send_gmail.domail(mail_to,email_subject,email_body) # LoadGCN.SaveGCN(gcn) # # Temporary hack mailchkpath = storepath + '/.mlchk%i' % int(gcn.triggerid) if not os.path.exists(mailchkpath) or clobber == True: cmd = "echo y > %s" % mailchkpath os.system(cmd) print 'Email with web link has not been sent yet; doing that now...' send_gmail.domail(mail_to, email_subject, email_body) if tweet: try: # python-twitter requires some kind of oAuth authentication now which is a pain # so just use tumblr, linked to the q.mailbot account. tumblrmail = '*****@*****.**' # import twitter # requires http://code.google.com/p/python-twitter/ #import tinyurl # requires http://pypi.python.org/pypi/TinyUrl/0.1.0 bigurl = '%s%i/' % (out_url_path, int(gcn.triggerid)) #littleurl = tinyurl.create_one(bigurl) if grbhtml: ra = str(gcn.best_pos[0]).rstrip('0') dec = str(gcn.best_pos[1]).rstrip('0') uncertainty = str(gcn.best_pos[2]).rstrip('0') pos_label = gcn.best_pos_type, twitsub = "New GRB! Swift Trigger %i" % (int( gcn.triggerid)) twittext = ''' * RA = %s<br> * Dec = %s<br> * Uncertainty = %s %s<br> * Visit %s for more info''' % ( ra, dec, uncertainty, pos_label, bigurl) else: twitsub = '' twittext = 'New GRB! Swift Trigger %i. Visit %s for more info.' % ( int(gcn.triggerid), bigurl) # api = twitter.Api(username='******', password='******') # status = api.PostUpdate(twittext) print 'Sending Tweet - %s' % (twittext) send_gmail.domail(tumblrmail, twitsub, twittext, sig=False) except: qErr.qErr() else: print 'Email has already been sent for this trigger.'
def _mail_html(gcn,mail_to,clobber=False,tweet=True,out_url_path='http://swift.qmorgan.com/',grbhtml=None): if not hasattr(gcn,'mailed_web'): gcn.mailed_web = False if not gcn.mailed_web: email_subject = 'New Web Page for Swift trigger %i' % int(gcn.triggerid) email_body = '''Please visit %s%i/ for information on this event, updated as more information arrives.''' % (out_url_path,int(gcn.triggerid)) # Crap, the following doesn't work because of clobber=True when reloading new GCNs # EVENTUALL UPDATE SO WE DON'T RELOAD THE ENTIRE GCN EACH TIME, JUST ADD THE NEW NOTICES? # gcn.mailed_web = True # send_gmail.domail(mail_to,email_subject,email_body) # LoadGCN.SaveGCN(gcn) # # Temporary hack mailchkpath = storepath + '/.mlchk%i' % int(gcn.triggerid) if not os.path.exists(mailchkpath) or clobber == True: cmd = "echo y > %s" % mailchkpath os.system(cmd) print 'Email with web link has not been sent yet; doing that now...' send_gmail.domail(mail_to,email_subject,email_body) if tweet: try: # python-twitter requires some kind of oAuth authentication now which is a pain # so just use tumblr, linked to the q.mailbot account. tumblrmail = '*****@*****.**' # import twitter # requires http://code.google.com/p/python-twitter/ #import tinyurl # requires http://pypi.python.org/pypi/TinyUrl/0.1.0 bigurl = '%s%i/' % (out_url_path,int(gcn.triggerid)) #littleurl = tinyurl.create_one(bigurl) if grbhtml: ra=str(gcn.best_pos[0]).rstrip('0') dec=str(gcn.best_pos[1]).rstrip('0') uncertainty=str(gcn.best_pos[2]).rstrip('0') pos_label=gcn.best_pos_type, twitsub = "New GRB! Swift Trigger %i" % (int(gcn.triggerid)) twittext = ''' * RA = %s<br> * Dec = %s<br> * Uncertainty = %s %s<br> * Visit %s for more info''' % (ra,dec,uncertainty,pos_label,bigurl) else: twitsub = '' twittext = 'New GRB! Swift Trigger %i. Visit %s for more info.' % (int(gcn.triggerid),bigurl) # api = twitter.Api(username='******', password='******') # status = api.PostUpdate(twittext) print 'Sending Tweet - %s' % (twittext) send_gmail.domail(tumblrmail,twitsub,twittext,sig=False) except: qErr.qErr() else: print 'Email has already been sent for this trigger.'
def qErr(mail=True, mail_to='*****@*****.**', errtitle="An error has occured!", errtext=''): '''Output the traceback of an error to a log file, and send the tail of the log file to someone by email, if desired. Most useful in the try/except, i.e. when you want information that something failed, but don't want the program to crash. Usage: >>> a=[1,2,3] >>> try: ... print a[6] ... except: ... qErr() ... Exception Triggered, traceback info forwarded to log file. the following will be appended to the log and emailed: ------------ Wed Oct 28 16:47:46 2009 Traceback (most recent call last): File "<stdin>", line 2, in <module> IndexError: list index out of range ''' print "Exception Triggered, traceback info forwarded to log file." print errtitle errfilepath = storepath + 'errlog.txt' errfile = open(errfilepath, "a") errfile.write('------------\n') errfile.write(time.ctime()) errfile.write('\n') traceback.print_exc(file=errfile) errfile.write('\n') errfile.close() if mail: errfilemailpath = storepath + 'errlogmail.txt' err_mail_sub = errtitle err_mail_text = 'Please see attached for error log.\n\n' err_mail_text += errtext operation = "tail -n 20 %s > %s" % (errfilepath, errfilemailpath) os.system(operation) send_gmail.domail(mail_to, err_mail_sub, err_mail_text, [errfilemailpath])
def qErr(mail=True,mail_to='*****@*****.**',errtitle="An error has occured!",errtext=''): '''Output the traceback of an error to a log file, and send the tail of the log file to someone by email, if desired. Most useful in the try/except, i.e. when you want information that something failed, but don't want the program to crash. Usage: >>> a=[1,2,3] >>> try: ... print a[6] ... except: ... qErr() ... Exception Triggered, traceback info forwarded to log file. the following will be appended to the log and emailed: ------------ Wed Oct 28 16:47:46 2009 Traceback (most recent call last): File "<stdin>", line 2, in <module> IndexError: list index out of range ''' print "Exception Triggered, traceback info forwarded to log file." print errtitle errfilepath = storepath + 'errlog.txt' errfile = open(errfilepath,"a") errfile.write('------------\n') errfile.write(time.ctime()) errfile.write('\n') traceback.print_exc(file=errfile) errfile.write('\n') errfile.close() if mail: errfilemailpath = storepath + 'errlogmail.txt' err_mail_sub = errtitle err_mail_text = 'Please see attached for error log.\n\n' err_mail_text += errtext operation = "tail -n 20 %s > %s" % (errfilepath, errfilemailpath) os.system(operation) send_gmail.domail(mail_to,err_mail_sub,err_mail_text,[errfilemailpath])
def _do_new_entry_actions(new_entry,email=True,email_to='*****@*****.**'): # being fed a parsed rss entry try: psn_id_full=new_entry.id.split('/followups/')[1].strip('"').split('.html')[0] # for some reason, the URL has a space when PSN label gets added # http://cbat.eps.harvard.edu/unconf/followups/PSN J15111485+4609115 #u'PSN J15111485+4609115' psn_id = str(psn_id_full.split()[-1]) #u'J15111485+4609115' except: qErr.qErr(errtitle="PSN ID URL malformed", errtext=new_entry.id) psn_id = "Unknown" psn_id_full = "Unknown" # check if it's in the pickle file # if so, update it - add to summary list all_pkl_path = storepath + 'psn_parsed_entries.pkl' all_entries = qPickle.load(all_pkl_path) if all_entries == None: all_entries = {} is_new_id = False if not psn_id in all_entries.keys(): is_new_id = True all_entries.update({psn_id:{}}) #update with a new empty dict with proper id # load and parse the PSN string psn_url="http://cbat.eps.harvard.edu/unconf/followups/%s" % (psn_id) psn_string = _download_and_obtain_psn_string(psn_url) if psn_string != None: psn_dict = _parse_psn_format(psn_string) else: psn_dict = None ## Make html if psn_dict: all_entries[psn_id].update(psn_dict) #add/update the dictionary values; though should they change? dss_url = "http://fc.qmorgan.com/fcserver.py?ra=%f&dec=%f&uncertainty=2&err_shape=combo&incl_scale=yes&size=4&src_name=%s&pos_label=Pos&cont_str=&survey=dss2red" % (psn_dict['ra_deg'],psn_dict['dec_deg'],psn_dict['designation']) dss_html = "<a href='%s'>DSS Finding Chart</a><br>" % (dss_url) sdss_url = "http://fc.qmorgan.com/fcserver.py?ra=%f&dec=%f&uncertainty=2&err_shape=combo&incl_scale=yes&size=4&src_name=%s&pos_label=Pos&cont_str=&survey=sdss" % (psn_dict['ra_deg'],psn_dict['dec_deg'],psn_dict['designation']) sdss_html = "<a href='%s'>SDSS Finding Chart</a> (May not be available)<br>" % (sdss_url) pretty_output=''' <br><br> <table border="0"> <tr><td>Object:</td><td>%s</td></tr> <tr><td>Designation:</td><td>%s</td></tr> <tr><td>Discovery date:</td><td>%s</td></tr> <tr><td>Mag at date:</td><td>%s</td></tr> <tr><td>Filter:</td><td>%s</td></tr> <tr><td>RA:</td><td>%s (= %f)</td></tr> <tr><td>Dec:</td><td>%s (= %f)</td></tr> <tr><td>Presumed host:</td><td>%s</td></tr> <tr><td>Offset from host:</td><td>%s, %s (arcsec)</td></tr> <tr><td>Discoverer:</td><td>%s</td></tr> <tr><td>Obs. arc:</td><td>%s</td></tr> </table> <br> ''' % (psn_dict['obj_type'],psn_dict['designation'], psn_dict['date_string'].replace(' ','-').replace('2013','UT2013'), psn_dict['mag'],psn_dict['filter'], psn_dict['ra'],psn_dict['ra_deg'],psn_dict['dec'],psn_dict['dec_deg'], psn_dict['locale'],psn_dict['ra_offset'],psn_dict['dec_offset'], psn_dict['discoverer'],psn_dict['arc']) else: pretty_output = 'Cannot parse PSN Message.' print pretty_output html_body = '''<html><body> <a href="%s">%s</a>''' % (psn_url,psn_id) if is_new_id: html_body += ' (First report of this transient)' else: html_body += ' (Update)' html_body += '<br><br>' if psn_dict: html_body += dss_html html_body += sdss_html html_body += pretty_output html_body+= new_entry.summary html_body+= '<br><br><br></body></html>' if 'summary_list' in all_entries[psn_id]: summary_list = all_entries[psn_id]['summary_list'] summary_list.append(new_entry.summary) else: summary_list = [new_entry.summary] all_entries[psn_id].update({'summary_list':summary_list}) # do email if new if email == True: if is_new_id: subject = "New Transient %s" % (psn_id_full) else: subject = "Update to Transient %s" % (psn_id_full) print "Sending email: '%s'" % (subject) send_gmail.domail(email_to,subject,html_body,html=True) # do separate/no email if updated? # save the updated pickle file qPickle.save(all_entries,all_pkl_path,clobber=True) return is_new_id
def mail_grb_region(gcn,mail_to,reg_file_path): from AutoRedux import qImage triggerid = gcn.triggerid # Eventually want to depreciate the following - don't want get_positions() # to have to be run each time. I created this function before I did the # more general extract_values(), so it's somewhat vestigial... though maybe keep it if not os.path.exists(reg_file_path): reg_file_path = gcn.get_positions(create_reg_file=True) if not hasattr(gcn,'bat_pos'): gcn.get_positions() from AutoRedux import send_gmail email_fc = '*****@*****.**' email_fc_sub = 'Finding Chart for Swift trigger %i' % int(triggerid) email_fc_body = 'Finding Chart for this trigger below.' fc_list = [] email_to = mail_to #email_fc # if mail_toosci == True: email_to += ' [email protected]' email_subject = 'DS9 region files for Swift trigger %i' % int(triggerid) email_body = 'Please find the latest region file for this burst below\n\n' # check to see if the new region file is actually different from the previous one # denoted with a ~. If it is, then assume the position has been updated, and email it. # Make sure a position exists before sending (reg_contents != blank) # reg_file_path = gcn.get_positions(create_reg_file = True) reg_check_path = reg_file_path+'~' reg_contents = 'Contains: ' if gcn.dict.has_key('Swift-BAT GRB Position'): reg_contents += 'BAT Position' if gcn.dict.has_key('Swift-XRT Position'): reg_contents += ', XRT Position' source_name = 'Swift_' + str(gcn.triggerid) # fc_list = qImage.MakeFindingChart(ra=gcn.pdict['xrt_ra'],dec=gcn.pdict['xrt_dec'],\ # uncertainty=gcn.pdict['xrt_pos_err'],src_name=source_name,pos_label='XRT',survey='dss2red') if gcn.dict.has_key('Swift-XRT Position UPDATE'): reg_contents += ', XRT Position UPDATE' source_name = 'Swift_' + str(gcn.triggerid) # fc_list = qImage.MakeFindingChart(ra=gcn.xrt_pos_update[0],dec=gcn.xrt_pos_update[1],\ # uncertainty=gcn.xrt_pos_update[2],src_name=source_name,pos_label='XRT upd.',survey='dss2red') if gcn.dict.has_key('Swift-UVOT Position'): reg_contents += ', UVOT Position' source_name = 'Swift_' + str(gcn.triggerid) # fc_list = qImage.MakeFindingChart(ra=gcn.uvot_pos[0],dec=gcn.uvot_pos[1],\ # uncertainty=gcn.uvot_pos[2],src_name=source_name,pos_label='UVOT',survey='dss2red') email_body += reg_contents # check to see if there's a finding chart already created. fc_path = _incl_fc(gcn) # If the region files already exist, add the word "updated" to subject line if os.path.exists(reg_check_path): email_subject = "UPDATED " + email_subject # Make sure position already exists before sending email!!! if (reg_contents != 'Contains: ') and hasattr(gcn,'bat_pos'): if not os.path.exists(reg_check_path) or \ (os.path.getsize(reg_check_path) != os.path.getsize(reg_file_path)): send_gmail.domail(email_to,email_subject,email_body,[reg_file_path]) if fc_path: send_gmail.domail(email_to,email_fc_sub,email_fc_body,[fc_path]) # Only make copy of region file if it is not blank os.system('cp ' + reg_file_path + ' ' + reg_check_path)
def mail_grb_region(gcn, mail_to, reg_file_path): from AutoRedux import qImage triggerid = gcn.triggerid # Eventually want to depreciate the following - don't want get_positions() # to have to be run each time. I created this function before I did the # more general extract_values(), so it's somewhat vestigial... though maybe keep it if not os.path.exists(reg_file_path): reg_file_path = gcn.get_positions(create_reg_file=True) if not hasattr(gcn, 'bat_pos'): gcn.get_positions() from AutoRedux import send_gmail email_fc = '*****@*****.**' email_fc_sub = 'Finding Chart for Swift trigger %i' % int(triggerid) email_fc_body = 'Finding Chart for this trigger below.' fc_list = [] email_to = mail_to #email_fc # if mail_toosci == True: email_to += ' [email protected]' email_subject = 'DS9 region files for Swift trigger %i' % int(triggerid) email_body = 'Please find the latest region file for this burst below\n\n' # check to see if the new region file is actually different from the previous one # denoted with a ~. If it is, then assume the position has been updated, and email it. # Make sure a position exists before sending (reg_contents != blank) # reg_file_path = gcn.get_positions(create_reg_file = True) reg_check_path = reg_file_path + '~' reg_contents = 'Contains: ' if gcn.dict.has_key('Swift-BAT GRB Position'): reg_contents += 'BAT Position' if gcn.dict.has_key('Swift-XRT Position'): reg_contents += ', XRT Position' source_name = 'Swift_' + str(gcn.triggerid) # fc_list = qImage.MakeFindingChart(ra=gcn.pdict['xrt_ra'],dec=gcn.pdict['xrt_dec'],\ # uncertainty=gcn.pdict['xrt_pos_err'],src_name=source_name,pos_label='XRT',survey='dss2red') if gcn.dict.has_key('Swift-XRT Position UPDATE'): reg_contents += ', XRT Position UPDATE' source_name = 'Swift_' + str(gcn.triggerid) # fc_list = qImage.MakeFindingChart(ra=gcn.xrt_pos_update[0],dec=gcn.xrt_pos_update[1],\ # uncertainty=gcn.xrt_pos_update[2],src_name=source_name,pos_label='XRT upd.',survey='dss2red') if gcn.dict.has_key('Swift-UVOT Position'): reg_contents += ', UVOT Position' source_name = 'Swift_' + str(gcn.triggerid) # fc_list = qImage.MakeFindingChart(ra=gcn.uvot_pos[0],dec=gcn.uvot_pos[1],\ # uncertainty=gcn.uvot_pos[2],src_name=source_name,pos_label='UVOT',survey='dss2red') email_body += reg_contents # check to see if there's a finding chart already created. fc_path = _incl_fc(gcn) # If the region files already exist, add the word "updated" to subject line if os.path.exists(reg_check_path): email_subject = "UPDATED " + email_subject # Make sure position already exists before sending email!!! if (reg_contents != 'Contains: ') and hasattr(gcn, 'bat_pos'): if not os.path.exists(reg_check_path) or \ (os.path.getsize(reg_check_path) != os.path.getsize(reg_file_path)): send_gmail.domail(email_to, email_subject, email_body, [reg_file_path]) if fc_path: send_gmail.domail(email_to, email_fc_sub, email_fc_body, [fc_path]) # Only make copy of region file if it is not blank os.system('cp ' + reg_file_path + ' ' + reg_check_path)
def _do_new_entry_actions(new_entry, email=True, email_to='*****@*****.**'): # being fed a parsed rss entry try: psn_id_full = new_entry.id.split('/followups/')[1].strip('"').split( '.html')[0] # for some reason, the URL has a space when PSN label gets added # http://cbat.eps.harvard.edu/unconf/followups/PSN J15111485+4609115 #u'PSN J15111485+4609115' psn_id = str(psn_id_full.split()[-1]) #u'J15111485+4609115' except: qErr.qErr(errtitle="PSN ID URL malformed", errtext=new_entry.id) psn_id = "Unknown" psn_id_full = "Unknown" # check if it's in the pickle file # if so, update it - add to summary list all_pkl_path = storepath + 'psn_parsed_entries.pkl' all_entries = qPickle.load(all_pkl_path) if all_entries == None: all_entries = {} is_new_id = False if not psn_id in all_entries.keys(): is_new_id = True all_entries.update({psn_id: {}}) #update with a new empty dict with proper id # load and parse the PSN string psn_url = "http://cbat.eps.harvard.edu/unconf/followups/%s" % (psn_id) psn_string = _download_and_obtain_psn_string(psn_url) if psn_string != None: psn_dict = _parse_psn_format(psn_string) else: psn_dict = None ## Make html if psn_dict: all_entries[psn_id].update( psn_dict ) #add/update the dictionary values; though should they change? dss_url = "http://fc.qmorgan.com/fcserver.py?ra=%f&dec=%f&uncertainty=2&err_shape=combo&incl_scale=yes&size=4&src_name=%s&pos_label=Pos&cont_str=&survey=dss2red" % ( psn_dict['ra_deg'], psn_dict['dec_deg'], psn_dict['designation']) dss_html = "<a href='%s'>DSS Finding Chart</a><br>" % (dss_url) sdss_url = "http://fc.qmorgan.com/fcserver.py?ra=%f&dec=%f&uncertainty=2&err_shape=combo&incl_scale=yes&size=4&src_name=%s&pos_label=Pos&cont_str=&survey=sdss" % ( psn_dict['ra_deg'], psn_dict['dec_deg'], psn_dict['designation']) sdss_html = "<a href='%s'>SDSS Finding Chart</a> (May not be available)<br>" % ( sdss_url) pretty_output = ''' <br><br> <table border="0"> <tr><td>Object:</td><td>%s</td></tr> <tr><td>Designation:</td><td>%s</td></tr> <tr><td>Discovery date:</td><td>%s</td></tr> <tr><td>Mag at date:</td><td>%s</td></tr> <tr><td>Filter:</td><td>%s</td></tr> <tr><td>RA:</td><td>%s (= %f)</td></tr> <tr><td>Dec:</td><td>%s (= %f)</td></tr> <tr><td>Presumed host:</td><td>%s</td></tr> <tr><td>Offset from host:</td><td>%s, %s (arcsec)</td></tr> <tr><td>Discoverer:</td><td>%s</td></tr> <tr><td>Obs. arc:</td><td>%s</td></tr> </table> <br> ''' % (psn_dict['obj_type'], psn_dict['designation'], psn_dict['date_string'].replace(' ', '-').replace( '2013', 'UT2013'), psn_dict['mag'], psn_dict['filter'], psn_dict['ra'], psn_dict['ra_deg'], psn_dict['dec'], psn_dict['dec_deg'], psn_dict['locale'], psn_dict['ra_offset'], psn_dict['dec_offset'], psn_dict['discoverer'], psn_dict['arc']) else: pretty_output = 'Cannot parse PSN Message.' print pretty_output html_body = '''<html><body> <a href="%s">%s</a>''' % (psn_url, psn_id) if is_new_id: html_body += ' (First report of this transient)' else: html_body += ' (Update)' html_body += '<br><br>' if psn_dict: html_body += dss_html html_body += sdss_html html_body += pretty_output html_body += new_entry.summary html_body += '<br><br><br></body></html>' if 'summary_list' in all_entries[psn_id]: summary_list = all_entries[psn_id]['summary_list'] summary_list.append(new_entry.summary) else: summary_list = [new_entry.summary] all_entries[psn_id].update({'summary_list': summary_list}) # do email if new if email == True: if is_new_id: subject = "New Transient %s" % (psn_id_full) else: subject = "Update to Transient %s" % (psn_id_full) print "Sending email: '%s'" % (subject) send_gmail.domail(email_to, subject, html_body, html=True) # do separate/no email if updated? # save the updated pickle file qPickle.save(all_entries, all_pkl_path, clobber=True) return is_new_id