Online PDF Tools, un webware pour effectuer quelques opérations sur vos PDF

Toujours dans la lignée avec ce que j’ai créé sur abricocotierfr.appspot.com, je voulais créer une application qui me serait vraiment utile tous les jours, et qui remplacerait (pourquoi pas avantageusement) une application que j’utilise chaque jour. Et ça tombe bien, j’utilise assez fréquemment un outil pour fusionner les PDF (celui-là, en l’occurence), mais il est truffé de pubs, et ne fonctionne plus correctement à partir d’un certain nombre de PDF. Bref, il n’est pas parfait. Pourquoi ne pas tenter, avec Online PDF Tools, d’en faire un moi-même sur AppEngine ?

Soyons clair, ce n’est pas ma première tentative avec cette application. J’avais déjà tenté une première approche il y a environ deux semaines. Approche qui s’était révélée infructueuse, devant la difficulté pour trouver des ressources en la matière (du coup, ça tombe bien : c’est moi qui vais les fournir, cette fois). En effet, sur internet, on trouve majoritairement deux librairies pour manipuler des PDF en python : PyPDF et ReportLab. ReportLab, dans sa version gratuite, permet de créer des PDF, mais pas vraiment de les lire ni de les fusionner. Cette fonctionnalité semble être offerte par un addon payant, PageCatcher.

A l’inverse, PyPDF propose une solution très rapidement maîtrisable pour lire des pages d’un PDF, les concaténer, et donc faire des opérations de fusion ou d’extraction de PDF de façon très rapide. Sauf… que pour AppEngine, il n’existait aucune ressource indiquant comment on pouvait « écrire » le fichier de sortie sur la sortie HTTP, soit donc pour le client. Je rappelle que la plateforme AppEngine ne permet pas réellement d’écrire et de créer des fichiers, et n’autorise cela que via des Blobs dans le DataStore (ou dans le BlobStore, si on a activé le billing, ce qui n’est pas mon cas). A l’inverse, il existait pas mal de ressources sur le net pour utiliser ReportLab avec AppEngine. Gloups, j’étais tiraillé entre deux librairies.

Après pas mal d’essais infructueux, j’ai eu, par chance, la possibilité d’obtenir enfin la création de PDF (avec PyPDF, et donc je n’utilise pas du tout ReportLab), puis celle de la lecture correcte de PDF venant des fichiers envoyés à la page (et non de fichiers lus en local, ce qui est différent). Et du coup, de fil en aiguille, j’ai fait l’outil qui est disponible là.

Plusieurs choses :

Le premier outil permet de fusionner des PDF. Le titre du document est réglé pour être celui du premier document dans la liste. Le serveur ne traite pas les documents n’ayant pas l’extension .pdf, et fait des try/catch sur la concaténation d’un PDF au fichier de sortie. En gros : si sur le lot, un PDF n’est pas lisible, le programme l’ignore, et continue sa route avec le reste.

Le deuxième outil permet d’enlever certaines pages à un PDF. Sachant qu’il faut impérativement lister correctement les pages entre virgules. C’est simple, le programme prend le fichier en entrée, ainsi que la liste des chiffres représentant les pages à ne pas mettre. Pour chaque page, le programme demande si le numéro de cette page fait partie de la liste des pages à ne pas mettre, et si oui, il ne l’ajoute pas au fichier de sortie.

Le troisième outil permet d’extraire une partie de PDF d’un PDF d’entrée. En gros, si, sur un PDF, vous ne voulez conserver qu’une partie, il suffit d’indiquer la page de début et la page de fin de la partie de document que vous voulez conserver.

Voilà ! C’est tout simple. Si vous avez des problèmes pour l’utilisation, n’hésitez pas à venir le dire ici, je tenterai ensuite de résoudre ce bug.

Pour le reste, voici le code python permettant de manipuler un PDF acquis en variable POST et de le renvoyer en réponse au client. C’est, en allégé, le code que j’utilise pour le premier programme. Voilà la partie du code qui est importante :

from pyPdf import PdfFileWriter, PdfFileReader

pdf_filename = ''
output = PdfFileWriter()
pdf_file = self.request.POST.get("file",None)
pdf_filename = cgi.escape(pdf_file.filename)
pdf_content = PdfFileReader(pdf_file.file)
numpages = pdf_content.getNumPages()
for i in range(0,numpages):
    output.addPage(pdf_content.getPage(i))
self.response.headers['Content-Type'] = 'application/pdf'
self.response.headers['Content-Disposition'] = 'pdf; filename='+pdf_filename
output.write(self.response.out)

10 réflexions sur « Online PDF Tools, un webware pour effectuer quelques opérations sur vos PDF »

  1. Sympa comme outil simple et pratique. Je bookmark.

    Demain je publie un billet sur un logiciel sympa, s’il existait en webware ce serait le top… enfin je dis ça comme ça… 😉

    RépondreRépondre
  2. Même si je n’utilise pas de PDF, faut avouer qu’une fois de plus tu fais un truc sympa 🙂

    RépondreRépondre
  3. @Louis: Huum, je sais plus si je te l’avais déjà dit mais tu pourrais faire un truc style twitterfeed mais uniquement pour WordPress 3.
    Je m’explique : avec les shortlink de la V3 combiné aux flux RSS, ça serait pas mal de pouvoir publier automatiquement nos articles via notre URL raccourcie pour ainsi éviter de passer par des services tiers du genre bit.ly 🙂
    De plus, une adaptation pour twitter et identi.ca serait top, fin c’est qu’un idée parmi d’autres 🙂

    RépondreRépondre
  4. @PSP: Ben il me semble qu’il y a déjà pleins de plugins qui font ça non ? Genre ceux qui twittent (sur Facebook, Twitter et Identi.ca) le billet dès qu’il a été publié. Je pense que la v3 de WP a dû forcer certains plugins à s’adapter et à prendre désormais en compte les nouvelles URL raccourcies. Je regarderai ça !

    RépondreRépondre
  5. @Louis: Oui ça se peut fortement qu’il y ait des plugins WordPress qui font ça mais bon une application comme je propose serait mieux, pourquoi ?

    – on évite d’utiliser un plugin pour pas grand chose
    – si l’on a plusieurs sites (comme moi) alors il faut activer plusieurs fois le plugin
    – la personne qui crée se genre d’utilitaire (en l’occurrence toi) pourrait se faire sa petite pub dans la partie « Il y a environ XX heures via XXXX » et peut être devenir un service populaire

    RépondreRépondre
  6. @PSP: Oui ok, mais je ne vois pas comment je peux la faire partager à tous les utilisateurs de WordPress tout en l’écrivant en python et en l’hébergeant sur AppEngine…

    RépondreRépondre
  7. @Louis: Alors la j’en sais rien mais bon si c’est trop complexe et si tu veux d’autres idées, il se peut que j’en ai ^^

    RépondreRépondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.