def prepare_email_report(new_items_dict, user): """Using new_items_dict, builds an HTML-tree report to send, and returns HTML-as-string and stripped of tags HTML (text).""" html = ( E.html( E.body( E.h3('Library Renewal script report', style='font-family: Helvetica, arial, sans-serif;'), E.p(E.strong('Account Name: '), user['name'], style='font: 13px Helvetica, arial, sans-serif;'), E.p('The library renewal script has renewed, or attempted to renew items for you. A report listing items that were renewed as well as those that could not be renewed is below.', style='font: 13px Helvetica, arial, sans-serif;'), E.p('If you notice any strange behaviour, or have questions about this script, please contact David Lane at ', E.a('*****@*****.**', href="mailto:[email protected]?Subject=Library%20Renewal%20Script", target="_top"), '.', style='font: 13px Helvetica, arial, sans-serif;'), E.h2('Renewed:', style='color: green; font-family: Helvetica, arial, sans-serif;'), E.table( E.tr( E.th('Title', style='padding: 0.5rem; background-color: #ddd;'), E.th('Author', style='padding: 0.5rem; background-color: #ddd;'), E.th('Renewals', style='padding: 0.5rem; background-color: #ddd;'), E.th('Due date', style='padding: 0.5rem; background-color: #ddd;'), E.th('Error', style='padding: 0.5rem; background-color: #ddd;') ), style='border-collapse: collapse; font-size: inherit; font: 13px Helvetica, arial, sans-serif; text-align: left;'), E.h2('Could not be renewed:', style='color: firebrick; font-family: Helvetica, arial, sans-serif;'), E.table( E.tr( E.th('Title', style='padding: 0.5rem; background-color: #ddd;'), E.th('Author', style='padding: 0.5rem; background-color: #ddd;'), E.th('Renewals', style='padding: 0.5rem; background-color: #ddd;'), E.th('Due date', style='padding: 0.5rem; background-color: #ddd;'), E.th('Error', style='padding: 0.5rem; background-color: #ddd;') ), style='border-collapse: collapse; font-size: inherit; font: 13px Helvetica, arial, sans-serif; text-align: left;') ))) renewed_table = html.findall('.//table')[0] not_renewed_table = html.findall('.//table')[1] for item in new_items_dict: error = new_items_dict[item].get('error') if error is None: error = '' item_tree = (E.tr( E.td(new_items_dict[item]['title'], style='padding: 0.5rem;'), E.td(new_items_dict[item]['author'], style='padding: 0.5rem;'), E.td('{0!s}'.format(new_items_dict[item]['renewals']), style='padding: 0.5rem;'), E.td(new_items_dict[item]['due_date'], style='padding: 0.5rem;'), E.td(error, style='padding: 0.5rem;'), )) if new_items_dict[item].get('renewed') is True: # Add an entry to the renewed table renewed_table.append(item_tree) elif new_items_dict[item].get('renewed') is False: # Add to the could-not-renew table not_renewed_table.append(item_tree) elif new_items_dict[item].get('error') is not None: # also add to the could-not-renew table not_renewed_table.append(item_tree) return etree.tostring(html), strip_tags(etree.tostring(html, pretty_print=True))
def gen_html(title, alignment, alignment_IDs, additional_data_fields=[], aa_css_class_list=None, sections={}): ''' additional_data_fields structure: [ { [PDB_ID]_[PDB_CHAIN_ID] : data }, { [PDB_ID]_[PDB_CHAIN_ID] : data }, ... ] with a separate dict for each data type, and where data is of len(alignment). Column headers not required. aa_css_class_list can be used to override the CSS classes assigned to each residue. Should be given as a list of lists, with shape: (len(alignment), len(alignment[0])). sections structure: {int(position): [section_title, additional_field_header1, additional_field_header2, ...]} ''' output_html_tree = E.html( E.head( E.link() ), E.body( E.h2(title), E.table() ) ) link = output_html_tree.find('head/link') link.set('type', 'text/css') link.set('href', 'seqlib.css') link.set('rel', 'stylesheet') html_body = output_html_tree.find('body') html_table = html_body.find('table') for i in range(len(alignment)): if i in sections: #html_table.append( E.tr( E.td( E.div( E.strong(E.u(sections[i])) ), nowrap='' ) ) ) tr = etree.SubElement(html_table, 'tr') for col in range(len(sections[i])): tr.append( E.td( E.div( E.strong(E.u(sections[i][col])) ), nowrap='' ) ) # row row = E.tr() # alignment ID div row.append( E.td( E.div( str(alignment_IDs[i]) ,CLASS='ali') ) ) # add any additional data fields (also in divs) for d in range(len(additional_data_fields)): data = additional_data_fields[d][alignment_IDs[i]] if data != None: row.append( E.td( E.div(data, CLASS='ali'), nowrap='') ) else: row.append( E.td( E.div('', CLASS='ali'), nowrap='') ) # format sequence with css classes. Returned as a list of span objects if aa_css_class_list != None: if aa_css_class_list[i] != None: prettyseq = targetexplorer.core.seq2pretty_html(alignment[i], aa_css_class_list=aa_css_class_list[i]) else: prettyseq = targetexplorer.core.seq2pretty_html(alignment[i]) else: prettyseq = targetexplorer.core.seq2pretty_html(alignment[i]) # set up sequence div seq_div = E.div(id='sequence',CLASS='ali') seq_div.set('style','background-color:#dddddd;letter-spacing:-5px') # add sequence to div for span in prettyseq: seq_div.append(span) row.append( E.td( seq_div, nowrap='' ) ) # add the row to the table html_table.append(row) return output_html_tree