from __future__ import absolute_import, unicode_literals from celery import task, shared_task from celery.utils.log import get_task_logger import os import sys import datetime import fileinput import smtplib from pathlib import Path from email.feedparser import FeedParser from email.message import EmailMessage from email.header import decode_header, make_header import django from django.conf import settings os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'procat2.settings') django.setup() from .utils import clean_path, ensure_dir, set_file_perms, WORKDIR from .email import reply, reply_missing, reply_no_matches, send_error_email from .matching import find_marked_products from .spreadsheet import write_spreadsheet from procat2.settings import TREE_NAME logger = get_task_logger(__name__) def on_fail_handler(self, exc, task_id, args, kwargs, einfo): """Send an email if a task throws an exception.""" print(str(einfo)) send_error_email(f'ERROR: {TREE_NAME} celery task {task_id}', str(einfo)) # @shared_task(on_failure=on_fail_handler) # def test_fail(x, y): # test_fail_internal() # def test_fail_internal(): # raise KeyError() @shared_task(on_failure=on_fail_handler) def process_message(path): parser = FeedParser() with open(path) as f: for line in f: parser.feed(line) msg = parser.close() frm = str(make_header(decode_header(msg['From']))) subject = str(make_header(decode_header(msg['Subject']))) found_pdf = False for attach in msg.walk(): if attach.get_content_type() == 'application/pdf': process_attachment(frm, subject, attach) found_pdf = True if not found_pdf: reply_missing(frm, subject) def process_attachment(from_address, subject, attachment): # write out pdf pdf_name = attachment.get_filename() pdf_base = Path(pdf_name).stem workdir = os.path.join(WORKDIR, clean_path(from_address), pdf_base) ensure_dir(workdir) pdf_path = os.path.join(workdir, pdf_name) print(f'saving pdf to {pdf_path}') with open(pdf_path, 'wb') as att: att.write(attachment.get_payload(decode=True)) set_file_perms(pdf_path) # find matches matches = find_marked_products(pdf_path, workdir, debug=0) if not matches: print('no product matches') reply_no_matches(from_address, subject) return print(f'{len(matches)} product matches') # write spreadsheet xls_path = write_spreadsheet(matches, workdir, pdf_base) if xls_path: # send reply print(f'wrote spreadsheet: {xls_path}') reply(from_address, subject, xls_path, pdf_path) else: # send error print(f'error creating spreadsheet')