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)
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.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):
@ -39,7 +40,19 @@ def make_product_box(obj, pagenum, mediabox):
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
# walk the object tree down to the image
@ -143,6 +156,10 @@ def write_pbm(obj, base_path):
return path
def is_inklist_annotation(anno):
return 'Subtype' in anno and anno["Subtype"] == LIT('Ink')
def parse_pdf(fname, workdir, debug=0):
PDFDocument.debug = debug
PDFParser.debug = debug
@ -173,8 +190,10 @@ def parse_pdf(fname, workdir, debug=0):
for anno in annots:
anno = resolve1(anno)
if 'AAPL:AKExtras' in anno:
scribbles.append(make_scribble(anno, pagenum, mediabox, workdir))
if is_inklist_annotation(anno):
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:
prod_boxes.append(make_product_box(anno, pagenum, mediabox))
else:

View File

@ -2,13 +2,16 @@ from __future__ import absolute_import, unicode_literals
from celery import task, shared_task
from celery.utils.log import get_task_logger
import os
import re
import sys
import datetime
import fileinput
import os
import re
import shutil
import smtplib
import sys
from pathlib import Path
from os.path import basename, dirname, isfile
from email.feedparser import FeedParser
from email.message import EmailMessage
@ -75,7 +78,6 @@ def process_attachment(from_address, subject, attachment):
print(f'Using pdf name: {pdf_name}')
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)
@ -84,6 +86,32 @@ def process_attachment(from_address, subject, attachment):
att.write(attachment.get_payload(decode=True))
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
matches = find_marked_products(pdf_path, workdir, debug=0)
if not matches:
@ -94,7 +122,8 @@ def process_attachment(from_address, subject, attachment):
print(f'{len(matches)} product matches')
# 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:
# send reply