def publishFromHTML(self, aruid, results_html): # The AR can be published only and only if allowed uc = getToolByName(self.context, 'uid_catalog') ars = uc(UID=aruid) if not ars or len(ars) != 1: return [] ar = ars[0].getObject(); wf = getToolByName(ar, 'portal_workflow') allowed_states = ['verified', 'published'] # Publish/Republish allowed? if wf.getInfoFor(ar, 'review_state') not in allowed_states: # Pre-publish allowed? if not ar.getAnalyses(review_state=allowed_states): return [] # HTML written to debug file debug_mode = App.config.getConfiguration().debug_mode if debug_mode: tmp_fn = tempfile.mktemp(suffix=".html") logger.debug("Writing HTML for %s to %s" % (ar.Title(), tmp_fn)) open(tmp_fn, "wb").write(results_html) # Create the pdf report (will always be attached to the AR) # we must supply the file ourself so that createPdf leaves it alone. pdf_fn = tempfile.mktemp(suffix=".pdf") pdf_report = createPdf(htmlreport=results_html, outfile=pdf_fn) # PDF written to debug file if debug_mode: logger.debug("Writing PDF for %s to %s" % (ar.Title(), pdf_fn)) else: os.remove(pdf_fn) recipients = [] contact = ar.getContact() lab = ar.bika_setup.laboratory if pdf_report: if contact: recipients = [{ 'UID': contact.UID(), 'Username': to_utf8(contact.getUsername()), 'Fullname': to_utf8(contact.getFullname()), 'EmailAddress': to_utf8(contact.getEmailAddress()), 'PublicationModes': contact.getPublicationPreference() }] reportid = ar.generateUniqueId('ARReport') report = _createObjectByType("ARReport", ar, reportid) report.edit( AnalysisRequest=ar.UID(), Pdf=pdf_report, Html=results_html, Recipients=recipients ) report.unmarkCreationFlag() renameAfterCreation(report) # Set status to prepublished/published/republished status = wf.getInfoFor(ar, 'review_state') transitions = {'verified': 'publish', 'published' : 'republish'} transition = transitions.get(status, 'prepublish') try: wf.doActionFor(ar, transition) except WorkflowException: pass # compose and send email. # The managers of the departments for which the current AR has # at least one AS must receive always the pdf report by email. # https://github.com/bikalabs/Bika-LIMS/issues/1028 mime_msg = MIMEMultipart('related') mime_msg['Subject'] = self.get_mail_subject(ar)[0] mime_msg['From'] = formataddr( (encode_header(lab.getName()), lab.getEmailAddress())) mime_msg.preamble = 'This is a multi-part MIME message.' msg_txt = MIMEText(results_html, _subtype='html') mime_msg.attach(msg_txt) to = [] mngrs = ar.getResponsible() for mngrid in mngrs['ids']: name = mngrs['dict'][mngrid].get('name', '') email = mngrs['dict'][mngrid].get('email', '') if (email != ''): to.append(formataddr((encode_header(name), email))) if len(to) > 0: # Send the email to the managers mime_msg['To'] = ','.join(to) attachPdf(mime_msg, pdf_report, pdf_fn) try: host = getToolByName(ar, 'MailHost') host.send(mime_msg.as_string(), immediate=True) except SMTPServerDisconnected as msg: logger.warn("SMTPServerDisconnected: %s." % msg) except SMTPRecipientsRefused as msg: raise WorkflowException(str(msg)) # Send report to recipients recips = self.get_recipients(ar) for recip in recips: if 'email' not in recip.get('pubpref', []) \ or not recip.get('email', ''): continue title = encode_header(recip.get('title', '')) email = recip.get('email') formatted = formataddr((title, email)) # Create the new mime_msg object, cause the previous one # has the pdf already attached mime_msg = MIMEMultipart('related') mime_msg['Subject'] = self.get_mail_subject(ar)[0] mime_msg['From'] = formataddr( (encode_header(lab.getName()), lab.getEmailAddress())) mime_msg.preamble = 'This is a multi-part MIME message.' msg_txt = MIMEText(results_html, _subtype='html') mime_msg.attach(msg_txt) mime_msg['To'] = formatted # Attach the pdf to the email if requested if pdf_report and 'pdf' in recip.get('pubpref'): attachPdf(mime_msg, pdf_report, pdf_fn) # For now, I will simply ignore mail send under test. if hasattr(self.portal, 'robotframework'): continue msg_string = mime_msg.as_string() # content of outgoing email written to debug file if debug_mode: tmp_fn = tempfile.mktemp(suffix=".email") logger.debug("Writing MIME message for %s to %s" % (ar.Title(), tmp_fn)) open(tmp_fn, "wb").write(msg_string) try: host = getToolByName(ar, 'MailHost') host.send(msg_string, immediate=True) except SMTPServerDisconnected as msg: logger.warn("SMTPServerDisconnected: %s." % msg) except SMTPRecipientsRefused as msg: raise WorkflowException(str(msg)) ar.setDatePublished(DateTime()) return [ar]
def __call__(self): workflow = getToolByName(self.context, 'portal_workflow') # SMTP errors are silently ignored if server is in debug mode self.debug_mode = App.config.getConfiguration().debug_mode # PDF and HTML files are written to disk if server is in debug mode self.out_path = join(Globals.INSTANCE_HOME, 'var') if self.debug_mode \ else None self._get_user_attributes() self._get_lab_attributes() # This for loop prints each AR individually to a PDF stored in the AR, # and sends whatever publication is required for ar_nr, ar in enumerate(self.analysis_requests): self.any_drymatter = ar.getReportDryMatter() self._get_ar_attributes(ar) self._get_client_attribues(ar) self._get_batch_attributes(ar) self._get_sample_attributes(ar) self._get_contact_attributes(ar) self._get_categorized_services(ar) self._get_categorized_qcservices(ar) self.Footer = to_utf8(self.context.bika_setup.getResultFooter()) out_fn = to_utf8(ar.Title()) # Create the html report ar_results = safe_unicode(self.template()).encode('utf-8') if self.out_path: open(join(self.out_path, out_fn + ".html"), "w").write(ar_results) # Create the pdf report (will always be attached to the AR) pdf_outfile = join(self.out_path, out_fn + ".pdf") if self.out_path else None pdf_css = resource_filename( "bika.lims", "skins/bika/analysisrequest_results_pdf.css") ar_css = join(self.portal_url, "analysisrequest_results.css") ar_results = ar_results.replace(ar_css, pdf_css) pdf_report = createPdf(ar_results, pdf_outfile, css=pdf_css) if self.contact['obj']: recipients = [{ 'UID': self.contact['obj'].UID(), 'Username': to_utf8(self.contact['obj'].getUsername()), 'Fullname': to_utf8(self.contact['obj'].getFullname()), 'EmailAddress': to_utf8(self.contact['obj'].getEmailAddress()), 'PublicationModes': self.contact['obj'].getPublicationPreference() }] else: recipients = [] if pdf_report: reportid = self.context.generateUniqueId('ARReport') report = _createObjectByType("ARReport", ar, reportid) report.edit( AnalysisRequest=ar.UID(), Pdf=pdf_report, Html=ar_results, Recipients=recipients ) report.unmarkCreationFlag() from bika.lims.idserver import renameAfterCreation renameAfterCreation(report) # Set status to published if self.action == 'publish': try: workflow.doActionFor(ar, 'publish') except WorkflowException: pass # compose and send email. # The managers of the departments for which the current AR has # at least one AS must receive always the pdf report by email. # https://github.com/bikalabs/Bika-LIMS/issues/1028 mime_msg = MIMEMultipart('related') mime_msg['Subject'] = self.get_mail_subject(ar)[0] mime_msg['From'] = formataddr( (encode_header(self.laboratory['obj'].getName()), self.laboratory['obj'].getEmailAddress())) mime_msg.preamble = 'This is a multi-part MIME message.' msg_txt = MIMEText(ar_results, _subtype='html') mime_msg.attach(msg_txt) to = [] mngrs = ar.getResponsible() for mngrid in mngrs['ids']: name = mngrs['dict'][mngrid].get('name', '') email = mngrs['dict'][mngrid].get('email', '') if (email != ''): to.append(formataddr((encode_header(name), email))) if len(to) > 0: # Send the email to the managers mime_msg['To'] = ','.join(to) attachPdf(mime_msg, pdf_report, out_fn) try: host = getToolByName(self.context, 'MailHost') host.send(mime_msg.as_string(), immediate=True) except SMTPServerDisconnected as msg: pass if not self.debug_mode: raise SMTPServerDisconnected(msg) except SMTPRecipientsRefused as msg: raise WorkflowException(str(msg)) to = [] # Send report to recipients recips = self.get_recipients(ar) for recip in recips: if 'email' not in recip.get('pubpref', []) \ or not recip.get('email', ''): continue title = encode_header(recip.get('title', '')) email = recip.get('email') formatted = formataddr((title, email)) # Create the new mime_msg object, cause the previous one # has the pdf already attached mime_msg = MIMEMultipart('related') mime_msg['Subject'] = self.get_mail_subject(ar)[0] mime_msg['From'] = formataddr( (encode_header(self.laboratory['obj'].getName()), self.laboratory['obj'].getEmailAddress())) mime_msg.preamble = 'This is a multi-part MIME message.' msg_txt = MIMEText(ar_results, _subtype='html') mime_msg.attach(msg_txt) mime_msg['To'] = formatted # Attach the pdf to the email if requested if pdf_report and 'pdf' in recip.get('pubpref'): attachPdf(mime_msg, pdf_report, out_fn) # For now, I will simply ignore mail send under test. if hasattr(self.portal, 'robotframework'): continue try: host = getToolByName(self.context, 'MailHost') host.send(mime_msg.as_string(), immediate=True) except SMTPServerDisconnected as msg: if not self.debug_mode: raise SMTPServerDisconnected(msg) except SMTPRecipientsRefused as msg: raise WorkflowException(str(msg)) return [ar.RequestID for ar in self.analysis_requests]
def notify_rejection(analysisrequest): """ Notifies via email that a given Analysis Request has been rejected. The notification is sent to the Client contacts assigned to the Analysis Request. :param analysisrequest: Analysis Request to which the notification refers :returns: true if success """ arid = analysisrequest.getRequestID() # This is the template to render for the pdf that will be either attached # to the email and attached the the Analysis Request for further access from bika.lims.browser.analysisrequest.reject import AnalysisRequestRejectPdfView tpl = AnalysisRequestRejectPdfView(analysisrequest, analysisrequest.REQUEST) html = tpl.template() html = safe_unicode(html).encode('utf-8') filename = '%s-rejected' % arid pdf_fn = tempfile.mktemp(suffix=".pdf") pdf = createPdf(htmlreport=html, outfile=pdf_fn) if pdf: # Attach the pdf to the Analysis Request attid = analysisrequest.aq_parent.generateUniqueId('Attachment') att = _createObjectByType("Attachment", analysisrequest.aq_parent, tmpID()) att.setAttachmentFile(open(pdf_fn)) # Awkward workaround to rename the file attf = att.getAttachmentFile() attf.filename = '%s.pdf' % filename att.setAttachmentFile(attf) att.unmarkCreationFlag() renameAfterCreation(att) atts = analysisrequest.getAttachment() + [att] if \ analysisrequest.getAttachment() else [att] atts = [a.UID() for a in atts] analysisrequest.setAttachment(atts) os.remove(pdf_fn) # This is the message for the email's body from bika.lims.browser.analysisrequest.reject import AnalysisRequestRejectEmailView tpl = AnalysisRequestRejectEmailView(analysisrequest, analysisrequest.REQUEST) html = tpl.template() html = safe_unicode(html).encode('utf-8') # compose and send email. mailto = [] lab = analysisrequest.bika_setup.laboratory mailfrom = formataddr((encode_header(lab.getName()), lab.getEmailAddress())) mailsubject = _('%s has been rejected') % arid contacts = [analysisrequest.getContact()] + analysisrequest.getCCContact() for contact in contacts: name = to_utf8(contact.getFullname()) email = to_utf8(contact.getEmailAddress()) if email: mailto.append(formataddr((encode_header(name), email))) if not mailto: return False mime_msg = MIMEMultipart('related') mime_msg['Subject'] = mailsubject mime_msg['From'] = mailfrom mime_msg['To'] = ','.join(mailto) mime_msg.preamble = 'This is a multi-part MIME message.' msg_txt = MIMEText(html, _subtype='html') mime_msg.attach(msg_txt) if pdf: attachPdf(mime_msg, pdf, filename) try: host = getToolByName(analysisrequest, 'MailHost') host.send(mime_msg.as_string(), immediate=True) except: pass return True
def publishFromHTML(self, prouid, results_html): uc = getToolByName(self.context, 'uid_catalog') pros = uc(UID=prouid) if not pros or len(pros) != 1: return [] pro = pros[0].getObject(); # HTML written to debug file debug_mode = App.config.getConfiguration().debug_mode if debug_mode: tmp_fn = tempfile.mktemp(suffix=".html") logger.debug("Writing HTML for %s to %s" % (pro.Title(), tmp_fn)) open(tmp_fn, "wb").write(results_html) # Create the pdf report (will always be attached to the Order) # we must supply the file ourself so that createPdf leaves it alone. # This version replaces 'attachment' links; probably not required, # so it's repeated below, without these localise_images. # cleanup, results_html_for_pdf = self.localise_images(results_html) # pdf_fn = tempfile.mktemp(suffix=".pdf") # pdf_report = createPdf(htmlreport=results_html_for_pdf, outfile=pdf_fn) # for fn in cleanup: # os.remove(fn) pdf_fn = tempfile.mktemp(suffix=".pdf") pdf_report = createPdf(htmlreport=results_html, outfile=pdf_fn) # PDF written to debug file if debug_mode: logger.debug("Writing PDF for %s to %s" % (pro.Title(), pdf_fn)) else: os.remove(pdf_fn) recipients = [] # Send report to supplier supplier_data = self._supplier_data(pro) title = encode_header(supplier_data.get('title', '')) email = supplier_data.get('email') formatted = formataddr((title, email)) # Create the new mime_msg object mime_msg = MIMEMultipart('related') mime_msg['Subject'] = self.get_mail_subject(pro) """ Edit this to change the From address mime_msg['From'] = formataddr( (encode_header(lab.getName()), lab.getEmailAddress())) """ mime_msg['From'] = formataddr(("BIKA IMM", "*****@*****.**")) mime_msg.preamble = 'This is a multi-part MIME message.' msg_txt = MIMEText(results_html, _subtype='html') mime_msg.attach(msg_txt) mime_msg['To'] = formatted # Attach the pdf to the email if requested if pdf_report: attachPdf(mime_msg, pdf_report, pdf_fn) msg_string = mime_msg.as_string() # content of outgoing email written to debug file if debug_mode: tmp_fn = tempfile.mktemp(suffix=".email") logger.debug("Writing MIME message for %s to %s" % (pro.Title(), tmp_fn)) open(tmp_fn, "wb").write(msg_string) try: host = getToolByName(pro, 'MailHost') host.send(msg_string, immediate=True) except SMTPServerDisconnected as msg: logger.warn("SMTPServerDisconnected: %s." % msg) except SMTPRecipientsRefused as msg: raise WorkflowException(str(msg)) pro.setDateDispatched(DateTime()) return [pro]
def publishFromHTML(self, aruid, results_html): # The AR can be published only and only if allowed uc = getToolByName(self.context, 'uid_catalog') ars = uc(UID=aruid) if not ars or len(ars) != 1: return [] ar = ars[0].getObject() wf = getToolByName(ar, 'portal_workflow') allowed_states = ['verified', 'published'] # Publish/Republish allowed? if wf.getInfoFor(ar, 'review_state') not in allowed_states: # Pre-publish allowed? if not ar.getAnalyses(review_state=allowed_states): return [] # HTML written to debug file debug_mode = App.config.getConfiguration().debug_mode if debug_mode: tmp_fn = tempfile.mktemp(suffix=".html") logger.debug("Writing HTML for %s to %s" % (ar.Title(), tmp_fn)) open(tmp_fn, "wb").write(results_html) # Create the pdf report (will always be attached to the AR) # we must supply the file ourself so that createPdf leaves it alone. pdf_fn = tempfile.mktemp(suffix=".pdf") pdf_report = createPdf(htmlreport=results_html, outfile=pdf_fn) # PDF written to debug file if debug_mode: logger.debug("Writing PDF for %s to %s" % (ar.Title(), pdf_fn)) else: os.remove(pdf_fn) recipients = [] contact = ar.getContact() lab = ar.bika_setup.laboratory if pdf_report: if contact: recipients = [{ 'UID': contact.UID(), 'Username': to_utf8(contact.getUsername()), 'Fullname': to_utf8(contact.getFullname()), 'EmailAddress': to_utf8(contact.getEmailAddress()), 'PublicationModes': contact.getPublicationPreference() }] reportid = ar.generateUniqueId('ARReport') report = _createObjectByType("ARReport", ar, reportid) report.edit(AnalysisRequest=ar.UID(), Pdf=pdf_report, Html=results_html, Recipients=recipients) report.unmarkCreationFlag() renameAfterCreation(report) # Set status to prepublished/published/republished status = wf.getInfoFor(ar, 'review_state') transitions = {'verified': 'publish', 'published': 'republish'} transition = transitions.get(status, 'prepublish') try: wf.doActionFor(ar, transition) except WorkflowException: pass # compose and send email. # The managers of the departments for which the current AR has # at least one AS must receive always the pdf report by email. # https://github.com/bikalabs/Bika-LIMS/issues/1028 mime_msg = MIMEMultipart('related') mime_msg['Subject'] = self.get_mail_subject(ar)[0] mime_msg['From'] = formataddr( (encode_header(lab.getName()), lab.getEmailAddress())) mime_msg.preamble = 'This is a multi-part MIME message.' msg_txt = MIMEText(results_html, _subtype='html') mime_msg.attach(msg_txt) to = [] mngrs = ar.getResponsible() for mngrid in mngrs['ids']: name = mngrs['dict'][mngrid].get('name', '') email = mngrs['dict'][mngrid].get('email', '') if (email != ''): to.append(formataddr((encode_header(name), email))) if len(to) > 0: # Send the email to the managers mime_msg['To'] = ','.join(to) attachPdf(mime_msg, pdf_report, pdf_fn) try: host = getToolByName(ar, 'MailHost') host.send(mime_msg.as_string(), immediate=True) except SMTPServerDisconnected as msg: logger.warn("SMTPServerDisconnected: %s." % msg) except SMTPRecipientsRefused as msg: raise WorkflowException(str(msg)) # Send report to recipients recips = self.get_recipients(ar) for recip in recips: if 'email' not in recip.get('pubpref', []) \ or not recip.get('email', ''): continue title = encode_header(recip.get('title', '')) email = recip.get('email') formatted = formataddr((title, email)) # Create the new mime_msg object, cause the previous one # has the pdf already attached mime_msg = MIMEMultipart('related') mime_msg['Subject'] = self.get_mail_subject(ar)[0] mime_msg['From'] = formataddr( (encode_header(lab.getName()), lab.getEmailAddress())) mime_msg.preamble = 'This is a multi-part MIME message.' msg_txt = MIMEText(results_html, _subtype='html') mime_msg.attach(msg_txt) mime_msg['To'] = formatted # Attach the pdf to the email if requested if pdf_report and 'pdf' in recip.get('pubpref'): attachPdf(mime_msg, pdf_report, pdf_fn) # For now, I will simply ignore mail send under test. if hasattr(self.portal, 'robotframework'): continue msg_string = mime_msg.as_string() # content of outgoing email written to debug file if debug_mode: tmp_fn = tempfile.mktemp(suffix=".email") logger.debug("Writing MIME message for %s to %s" % (ar.Title(), tmp_fn)) open(tmp_fn, "wb").write(msg_string) try: host = getToolByName(ar, 'MailHost') host.send(msg_string, immediate=True) except SMTPServerDisconnected as msg: logger.warn("SMTPServerDisconnected: %s." % msg) except SMTPRecipientsRefused as msg: raise WorkflowException(str(msg)) ar.setDatePublished(DateTime()) return [ar]
def notify_rejection(analysisrequest): """ Notifies via email that a given Analysis Request has been rejected. The notification is sent to the Client contacts assigned to the Analysis Request. :param analysisrequest: Analysis Request to which the notification refers :returns: true if success """ # We do this imports here to avoid circular dependencies until we deal # better with this notify_rejection thing. from bika.lims.browser.analysisrequest.reject import \ AnalysisRequestRejectPdfView, AnalysisRequestRejectEmailView arid = analysisrequest.getId() # This is the template to render for the pdf that will be either attached # to the email and attached the the Analysis Request for further access tpl = AnalysisRequestRejectPdfView(analysisrequest, analysisrequest.REQUEST) html = tpl.template() html = safe_unicode(html).encode('utf-8') filename = '%s-rejected' % arid pdf_fn = tempfile.mktemp(suffix=".pdf") pdf = createPdf(htmlreport=html, outfile=pdf_fn) if pdf: # Attach the pdf to the Analysis Request attid = analysisrequest.aq_parent.generateUniqueId('Attachment') att = _createObjectByType("Attachment", analysisrequest.aq_parent, attid) att.setAttachmentFile(open(pdf_fn)) # Awkward workaround to rename the file attf = att.getAttachmentFile() attf.filename = '%s.pdf' % filename att.setAttachmentFile(attf) att.unmarkCreationFlag() renameAfterCreation(att) analysisrequest.addAttachment(att) os.remove(pdf_fn) # This is the message for the email's body tpl = AnalysisRequestRejectEmailView(analysisrequest, analysisrequest.REQUEST) html = tpl.template() html = safe_unicode(html).encode('utf-8') # compose and send email. mailto = [] lab = analysisrequest.bika_setup.laboratory mailfrom = formataddr( (encode_header(lab.getName()), lab.getEmailAddress())) mailsubject = _('%s has been rejected') % arid contacts = [analysisrequest.getContact()] + analysisrequest.getCCContact() for contact in contacts: name = to_utf8(contact.getFullname()) email = to_utf8(contact.getEmailAddress()) if email: mailto.append(formataddr((encode_header(name), email))) if not mailto: return False mime_msg = MIMEMultipart('related') mime_msg['Subject'] = mailsubject mime_msg['From'] = mailfrom mime_msg['To'] = ','.join(mailto) mime_msg.preamble = 'This is a multi-part MIME message.' msg_txt = MIMEText(html, _subtype='html') mime_msg.attach(msg_txt) if pdf: attachPdf(mime_msg, pdf, filename) try: host = getToolByName(analysisrequest, 'MailHost') host.send(mime_msg.as_string(), immediate=True) except: logger.warning( "Email with subject %s was not sent (SMTP connection error)" % mailsubject) return True
def publishFromHTML(self, prouid, results_html): uc = getToolByName(self.context, 'uid_catalog') pros = uc(UID=prouid) if not pros or len(pros) != 1: return [] pro = pros[0].getObject() # HTML written to debug file debug_mode = App.config.getConfiguration().debug_mode if debug_mode: tmp_fn = tempfile.mktemp(suffix=".html") logger.debug("Writing HTML for %s to %s" % (pro.Title(), tmp_fn)) open(tmp_fn, "wb").write(results_html) # Create the pdf report (will always be attached to the Order) # we must supply the file ourself so that createPdf leaves it alone. # This version replaces 'attachment' links; probably not required, # so it's repeated below, without these localise_images. # cleanup, results_html_for_pdf = self.localise_images(results_html) # pdf_fn = tempfile.mktemp(suffix=".pdf") # pdf_report = createPdf(htmlreport=results_html_for_pdf, outfile=pdf_fn) # for fn in cleanup: # os.remove(fn) pdf_fn = tempfile.mktemp(suffix=".pdf") pdf_report = createPdf(htmlreport=results_html, outfile=pdf_fn) # PDF written to debug file if debug_mode: logger.debug("Writing PDF for %s to %s" % (pro.Title(), pdf_fn)) else: os.remove(pdf_fn) recipients = [] # Send report to supplier supplier_data = self._supplier_data(pro) title = encode_header(supplier_data.get('title', '')) email = supplier_data.get('email') formatted = formataddr((title, email)) # Create the new mime_msg object mime_msg = MIMEMultipart('related') mime_msg['Subject'] = self.get_mail_subject(pro) """ Edit this to change the From address mime_msg['From'] = formataddr( (encode_header(lab.getName()), lab.getEmailAddress())) """ mime_msg['From'] = formataddr(("BIKA IMM", "*****@*****.**")) mime_msg.preamble = 'This is a multi-part MIME message.' msg_txt = MIMEText(results_html, _subtype='html') mime_msg.attach(msg_txt) mime_msg['To'] = formatted # Attach the pdf to the email if requested if pdf_report: attachPdf(mime_msg, pdf_report, pdf_fn) msg_string = mime_msg.as_string() # content of outgoing email written to debug file if debug_mode: tmp_fn = tempfile.mktemp(suffix=".email") logger.debug("Writing MIME message for %s to %s" % (pro.Title(), tmp_fn)) open(tmp_fn, "wb").write(msg_string) try: host = getToolByName(pro, 'MailHost') host.send(msg_string, immediate=True) except SMTPServerDisconnected as msg: logger.warn("SMTPServerDisconnected: %s." % msg) except SMTPRecipientsRefused as msg: raise WorkflowException(str(msg)) pro.setDateDispatched(DateTime()) return [pro]
def publishFromHTML(self, aruid, results_html): # The AR can be published only and only if allowed uc = getToolByName(self.context, 'uid_catalog') #ars = uc(UID=aruid) ars = [p.getObject() for p in uc(UID=aruid)] if not ars or len(ars) != 1: return [] ar = ars[0] wf = getToolByName(ar, 'portal_workflow') allowed_states = ['verified', 'published'] # Publish/Republish allowed? if wf.getInfoFor(ar, 'review_state') not in allowed_states: # Pre-publish allowed? if not ar.getAnalyses(review_state=allowed_states): return [] # HTML written to debug file debug_mode = App.config.getConfiguration().debug_mode if debug_mode: tmp_fn = tempfile.mktemp(suffix=".html") logger.debug("Writing HTML for %s to %s" % (ar.Title(), tmp_fn)) open(tmp_fn, "wb").write(results_html) # Create the pdf report (will always be attached to the AR) # we must supply the file ourself so that createPdf leaves it alone. pdf_fn = tempfile.mktemp(suffix=".pdf") pdf_report = createPdf(htmlreport=results_html, outfile=pdf_fn) # PDF written to debug file if debug_mode: logger.debug("Writing PDF for %s to %s" % (ar.Title(), pdf_fn)) else: os.remove(pdf_fn) recipients = [] contact = ar.getContact() lab = ar.bika_setup.laboratory # BIKA Cannabis hack. Create the CSV they desire here now #csvdata = self.create_cannabis_csv(ars) csvdata = self.create_metrc_csv(ars) pdf_fn = to_utf8(ar.getRequestID()) if pdf_report: if contact: recipients = [{ 'UID': contact.UID(), 'Username': to_utf8(contact.getUsername()), 'Fullname': to_utf8(contact.getFullname()), 'EmailAddress': to_utf8(contact.getEmailAddress()), 'PublicationModes': contact.getPublicationPreference() }] reportid = ar.generateUniqueId('ARReport') report = _createObjectByType("ARReport", ar, reportid) report.edit(AnalysisRequest=ar.UID(), Pdf=pdf_report, CSV=csvdata, Html=results_html, Recipients=recipients) report.unmarkCreationFlag() renameAfterCreation(report) # Set blob properties for fields containing file data fld = report.getField('Pdf') fld.get(report).setFilename(pdf_fn + ".pdf") fld.get(report).setContentType('application/pdf') fld = report.getField('CSV') fld.get(report).setFilename(pdf_fn + ".csv") fld.get(report).setContentType('text/csv') # Set status to prepublished/published/republished status = wf.getInfoFor(ar, 'review_state') transitions = {'verified': 'publish', 'published': 'republish'} transition = transitions.get(status, 'prepublish') try: wf.doActionFor(ar, transition) except WorkflowException: pass # compose and send email. # The managers of the departments for which the current AR has # at least one AS must receive always the pdf report by email. # https://github.com/bikalabs/Bika-LIMS/issues/1028 mime_msg = MIMEMultipart('related') mime_msg['Subject'] = self.get_mail_subject(ar)[0] mime_msg['From'] = formataddr( (encode_header(lab.getName()), lab.getEmailAddress())) mime_msg.preamble = 'This is a multi-part MIME message.' msg_txt = MIMEText(results_html, _subtype='html') mime_msg.attach(msg_txt) to = [] #mngrs = ar.getResponsible() #for mngrid in mngrs['ids']: # name = mngrs['dict'][mngrid].get('name', '') # email = mngrs['dict'][mngrid].get('email', '') # if (email != ''): # to.append(formataddr((encode_header(name), email))) #if len(to) > 0: # # Send the email to the managers # mime_msg['To'] = ','.join(to) # attachPdf(mime_msg, pdf_report, pdf_fn) # # BIKA Cannabis hack. Create the CSV they desire here now # fn = pdf_fn # attachCSV(mime_msg,csvdata,fn) # try: # host = getToolByName(ar, 'MailHost') # host.send(mime_msg.as_string(), immediate=True) # except SMTPServerDisconnected as msg: # logger.warn("SMTPServerDisconnected: %s." % msg) # except SMTPRecipientsRefused as msg: # raise WorkflowException(str(msg)) # Send report to recipients recips = self.get_recipients(ar) for recip in recips: if 'email' not in recip.get('pubpref', []) \ or not recip.get('email', ''): continue title = encode_header(recip.get('title', '')) email = recip.get('email') formatted = formataddr((title, email)) # Create the new mime_msg object, cause the previous one # has the pdf already attached mime_msg = MIMEMultipart('related') mime_msg['Subject'] = self.get_mail_subject(ar)[0] mime_msg['From'] = formataddr( (encode_header(lab.getName()), lab.getEmailAddress())) mime_msg.preamble = 'This is a multi-part MIME message.' msg_txt = MIMEText(results_html, _subtype='html') mime_msg.attach(msg_txt) mime_msg['To'] = formatted # Attach the pdf to the email if requested if pdf_report and 'pdf' in recip.get('pubpref'): attachPdf(mime_msg, pdf_report, pdf_fn) # BIKA Cannabis hack. Create the CSV they desire here now fn = pdf_fn attachCSV(mime_msg, csvdata, fn) # For now, I will simply ignore mail send under test. if hasattr(self.portal, 'robotframework'): continue msg_string = mime_msg.as_string() # content of outgoing email written to debug file if debug_mode: tmp_fn = tempfile.mktemp(suffix=".email") logger.debug("Writing MIME message for %s to %s" % (ar.Title(), tmp_fn)) open(tmp_fn, "wb").write(msg_string) try: host = getToolByName(ar, 'MailHost') host.send(msg_string, immediate=True) except SMTPServerDisconnected as msg: logger.warn("SMTPServerDisconnected: %s." % msg) except SMTPRecipientsRefused as msg: raise WorkflowException(str(msg)) # Save file on the filesystem folder = os.environ.get('COAs_FOLDER', '') if len(folder) != 0: client_path = '{}/{}/'.format(folder, ar.getClientID()) if not os.path.exists(client_path): os.makedirs(client_path) today = self.ulocalized_time(DateTime(), long_format=0) today_path = '{}{}/'.format(client_path, today) if not os.path.exists(today_path): os.makedirs(today_path) fname = '{}{}.pdf'.format(today_path, pdf_fn) f = open(fname, 'w') f.write(pdf_report) f.close() csvname = '{}{}.csv'.format(today_path, pdf_fn) fcsv = open(csvname, 'w') fcsv.write(csvdata) fcsv.close() return [ar]