Example #1
0
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.'
Example #2
0
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.'
Example #3
0
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])
Example #4
0
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])
Example #5
0
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
Example #6
0
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)
Example #7
0
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)
Example #8
0
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