PyWaw #20 - perypetie z obsługą PDF
Za nami już 20 spotkanie warszawskiej grupy Pythonistów. Miałem przyjemność wystąpić obok Piotrka Malińskiego, Radka Czajki i Grześka Noska i opowiedziałem o tym, jak tworzyliśmy webowy edytor plików PDF, który jest częścią platformy Issue Stand.
Niestety obsługa PDF-ów w Pythonie nieco kuleje i aby zrealizować założone przez nas cele, musieliśmy wykorzystać aż 3 różne narzędzia/biblioteki.
Edytor PDF-ów online
Webowy edytor umożliwia wydawcom prasy łatwe dodawanie treści multimedialnych do istniejących plików PDF, nie jest to jednak rozwiązanie rozbudowane na skalę InDesigna/Acrobata. Wydawca uploaduje plik PDF do panelu, następnie w edytorze może dodawać widżety audio, video, galerie zdjęć itp. Zapis powoduje wygenerowanie paczki w formacie specyficznym dla aplikacji mobilnej, która jest docelowym odbiorcą treści.
Wszelkie widgety z punktu widzenia edytora są traktowane jako linki, czy to do stron internetowych, czy to do osadzonych multimediów lub do innych stron w danym pliku. Upraszcza to komunikację javascriptowej części edytora z backendem, gdzie możemy przechowywać linki w jednej tabeli w bazie danych.
PyPDF2
Biblioteka PyPDF2 posłużyła do wyciągania linków z treści PDF-a. Dokumentacja pozostawia wiele do życzenia, więc kod służący do ekstrakcji linków powstawał w oparciu o przykłady ze Stack Overflow, naginanie zdroworozsądkowego podejścia do struktury danych w PDF-ie, a nawet otwieranie plików .pdf w vimie i optymistyczną interpretację zastanej sytuacji.
ReportLab
PyPDF2 pozwala dość swobodnie odczytywać strukturę pliku, ale zaczyna kuleć, gdy chodzi o zapis, dodawanie nowych elementów itp. Zatem kolejnym krokiem było wygenerowanie drugiego PDF-a, w któym znajdą się wyłącznie obiekty, które chcemy dodać. Użyliśmy do tego opensourcowej wersji biblioteki ReportLab, za pomocą której rysujemy klikalne prostokąty-linki na czystych stronach. Tak powstały watermark możemy nałożyć na oryginalnego PDF-a.
pdftk
Tu też było pod górkę. Według dokumentacji pdftk opcja multistamp
powinna wziąć naszego watermarka i strona po stronie nałożyć go na pierwotny plik. To jednak z niewyjaśnionych przyczyn nie działa, linki się nie nakładają. W desperacji wywołałem pdftk z opcją multibackground
, odwróciłem kolejność plików tak, by sens operacji polegał na podłożeniu oryginalnego PDF-a jako tło pod wygenerowanego watermarka... i zadziałało. Reszta już była prosta - wygenerowanie paczki zawierającej finalny dokument, pliki multimedialne i metadane oraz wysłanie notyfikacji do aplikacji mobilnych w momencie gdy wydawca zdecyduje się opublikować dane wydanie magazynu.
A oto i slajdy z mojej prezentacji: