markup: process Documents inklist annotations

This commit is contained in:
2020-02-28 16:23:33 -08:00
parent 8a1b94b4dc
commit 97ef16e47a
3 changed files with 76 additions and 9 deletions

View File

@ -110,3 +110,22 @@ def write_debug_image(workdir, page_num, prods, scribbles):
img.save(path) img.save(path)
set_file_perms(path) set_file_perms(path)
def write_inklist(obj, path):
"""Draw an image of the inklist."""
pagew = int(11*72)
pageh = int(8.5*72)
img = Image.new('RGBA', (pagew, pageh), (0, 0, 0, 0))
draw = ImageDraw.Draw(img, 'RGBA')
for segment in obj['InkList']:
draw.line(segment, 'black', 3)
# account for the difference in coordinate systems
# between pdf and images.
img = img.transpose(Image.FLIP_TOP_BOTTOM)
img.save(path)
set_file_perms(path)

View File

@ -9,7 +9,8 @@ from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdftypes import PDFObjRef, resolve1 from pdfminer.pdftypes import PDFObjRef, resolve1
from .utils import pdf_rect, ensure_dir, set_file_perms from .utils import Rect, pdf_rect, ensure_dir, set_file_perms
from .img import write_inklist
def make_product_box(obj, pagenum, mediabox): def make_product_box(obj, pagenum, mediabox):
@ -39,7 +40,19 @@ def make_product_box(obj, pagenum, mediabox):
return None return None
def make_scribble(obj, pagenum, mediabox, workdir): def make_ink_scribble(obj, pagenum, mediabox, workdir):
oid = obj['NM'].decode('utf-8')
png_path = os.path.join(workdir, f"export-page{pagenum:03d}-nm{oid}.png")
write_inklist(obj, png_path)
return { 'page': pagenum,
'rect': Rect(*mediabox),
'objid': oid,
'image': png_path }
def make_aapl_scribble(obj, pagenum, mediabox, workdir):
rect = obj['Rect'] # position on page rect = obj['Rect'] # position on page
# walk the object tree down to the image # walk the object tree down to the image
@ -143,6 +156,10 @@ def write_pbm(obj, base_path):
return path return path
def is_inklist_annotation(anno):
return 'Subtype' in anno and anno["Subtype"] == LIT('Ink')
def parse_pdf(fname, workdir, debug=0): def parse_pdf(fname, workdir, debug=0):
PDFDocument.debug = debug PDFDocument.debug = debug
PDFParser.debug = debug PDFParser.debug = debug
@ -173,8 +190,10 @@ def parse_pdf(fname, workdir, debug=0):
for anno in annots: for anno in annots:
anno = resolve1(anno) anno = resolve1(anno)
if 'AAPL:AKExtras' in anno: if is_inklist_annotation(anno):
scribbles.append(make_scribble(anno, pagenum, mediabox, workdir)) scribbles.append(make_ink_scribble(anno, pagenum, mediabox, workdir))
elif 'AAPL:AKExtras' in anno:
scribbles.append(make_aapl_scribble(anno, pagenum, mediabox, workdir))
elif 'ProCatName' in anno: elif 'ProCatName' in anno:
prod_boxes.append(make_product_box(anno, pagenum, mediabox)) prod_boxes.append(make_product_box(anno, pagenum, mediabox))
else: else:

View File

@ -2,13 +2,16 @@ from __future__ import absolute_import, unicode_literals
from celery import task, shared_task from celery import task, shared_task
from celery.utils.log import get_task_logger from celery.utils.log import get_task_logger
import os
import re
import sys
import datetime import datetime
import fileinput import fileinput
import os
import re
import shutil
import smtplib import smtplib
import sys
from pathlib import Path from pathlib import Path
from os.path import basename, dirname, isfile
from email.feedparser import FeedParser from email.feedparser import FeedParser
from email.message import EmailMessage from email.message import EmailMessage
@ -75,7 +78,6 @@ def process_attachment(from_address, subject, attachment):
print(f'Using pdf name: {pdf_name}') print(f'Using pdf name: {pdf_name}')
pdf_base = Path(pdf_name).stem pdf_base = Path(pdf_name).stem
workdir = os.path.join(WORKDIR, clean_path(from_address), pdf_base) workdir = os.path.join(WORKDIR, clean_path(from_address), pdf_base)
ensure_dir(workdir) ensure_dir(workdir)
pdf_path = os.path.join(workdir, pdf_name) pdf_path = os.path.join(workdir, pdf_name)
@ -84,6 +86,32 @@ def process_attachment(from_address, subject, attachment):
att.write(attachment.get_payload(decode=True)) att.write(attachment.get_payload(decode=True))
set_file_perms(pdf_path) set_file_perms(pdf_path)
process_pdf(pdf_path, from_address, subject, workdir)
@shared_task(on_failure=on_fail_handler)
def process_markup_pdf(pdf_path, user):
if not Path(pdf_path).is_file():
print(f'No pdf - exiting ({pdf_path})')
return
pdf_stem = Path(pdf_path).stem
workdir = os.path.join(WORKDIR, clean_path(user.username), clean_path(pdf_stem))
ensure_dir(workdir)
pdf_name = Path(pdf_path).name
dest_path = os.path.join(workdir, pdf_name)
print(f'copying pdf to {dest_path}')
shutil.copy(pdf_path, dest_path)
set_file_perms(dest_path)
frm = str(make_header(decode_header(f'{user.get_full_name()} <{user.email}>')))
subject = str(make_header(decode_header(pdf_name)))
process_pdf(dest_path, frm, subject, workdir)
def process_pdf(pdf_path, from_address, subject, workdir):
# find matches # find matches
matches = find_marked_products(pdf_path, workdir, debug=0) matches = find_marked_products(pdf_path, workdir, debug=0)
if not matches: if not matches:
@ -94,7 +122,8 @@ def process_attachment(from_address, subject, attachment):
print(f'{len(matches)} product matches') print(f'{len(matches)} product matches')
# write spreadsheet # write spreadsheet
xls_path = write_spreadsheet(matches, workdir, pdf_base) pdf_stem = Path(pdf_path).stem
xls_path = write_spreadsheet(matches, workdir, pdf_stem)
if xls_path: if xls_path:
# send reply # send reply