Source code for uw.local.print_.bin.requisition_received

from collections import namedtuple
from email import message_from_file
from subprocess import check_call
from sys import argv

import os.path
import re

from uw.sql.wrap import open_psycopg2_db_service_cursor

from ..db.cursor import Cursor

subject_re = re.compile ('^New Media Services Online Req #R([0-9]+): (.*)$')
filename_re = re.compile ('^newmediareq_R([0-9]+).pdf$')
body_text = "This is an automated message. Your order has been placed. A copy of the requisition is attached for your records. Please do not send files to this email address. For instructions on sending files to New Media Services, visit the New Media Services web site.\n"

parse_result = namedtuple ('parse_result', ['req_num', 'req_filename', 'req_title', 'req_pdf'])

[docs]def parse_file (f): msg = message_from_file (f) if msg['from'] != 'Retail Services <webslave@lists.uwaterloo.ca>': raise ValueError("Message is not from proper sender") if not msg['message-id'].endswith ('@info.uwaterloo.ca>'): raise ValueError("Message has unexpected Message-Id") if not msg.is_multipart (): raise ValueError("Message is not multi-part") if len (msg.get_payload ()) != 2: raise ValueError("Message does not have exactly 2 parts") body, attachment = msg.get_payload () # Identify requisition m = subject_re.match (msg['subject']) if m is None: raise ValueError("Message subject not recognized") req_num = int (m.group (1)) req_title = m.group (2) # Check body if body.is_multipart (): raise ValueError("Body is multipart") if body.get_payload () != body_text: raise ValueError("Unexpected body contents") # Get attachment if attachment.is_multipart (): raise ValueError("Attachment is multipart") req_filename = attachment.get_filename () m = filename_re.match (req_filename) if m is None: raise ValueError("Attachment filename not recognized") if int (m.group (1)) != req_num: raise ValueError("Attachment requisition number mismatch") req_pdf = bytearray (attachment.get_payload (decode=True)) return parse_result (req_num, req_filename, req_title, req_pdf)
[docs]def record_requisition (cursor, req_info): return cursor.callproc_required_value ("nms_requisition_receive", req_info.req_num, str (req_info.req_title), req_info.req_pdf)
[docs]def clean_filename (filename): return ''.join ([c if c.isalnum () or c in "-_.,() " else '_' for c in filename])
[docs]def complete_filename (job_file): if job_file.requisition_title is None: components = ['%d' % job_file.job_id] else: components = ['R%d' % job_file.requisition_num, clean_filename (job_file.requisition_title)] components.append (job_file.file_code) return ' - '.join (components)
[docs]def main (): if len (argv) != 2: raise ValueError ('Temp file name not specified') tempfile = argv[1] req_info = parse_file (open (tempfile)) cursor = open_psycopg2_db_service_cursor (cursor_class=Cursor) job_id = record_requisition (cursor, req_info) cursor.connection.commit () if job_id is None: # Not necessarily a big problem - if we fill out a requisition by # hand we will get this. But we would like to be informed. print('Unexpected Requisition #%d received.' % req_info.req_num) else: # Next send files (now that we have requisition number to include in # directory name) jobname = 'R%d - %s' % (req_info.req_num, req_info.req_title) dirname = clean_filename (jobname) basedir = os.path.dirname (tempfile) tempdir = os.path.join (basedir, dirname) os.mkdir (tempdir) for file in cursor.files_by_job (job_id=job_id): f = open (os.path.join (tempdir, complete_filename (file)), "wb") f.write (file.file_contents) f.close () # Include requisition PDF with files in case it is handy f = open (os.path.join (tempdir, req_info.req_filename), "wb") f.write (req_info.req_pdf) f.close () check_call (["scp", "-rq", tempdir, "dock:print"]) cursor.callproc_none ("nms_requisition_files_sent", job_id) cursor.connection.commit ()