{"id":4702,"date":"2020-02-11T22:07:16","date_gmt":"2020-02-11T21:07:16","guid":{"rendered":"http:\/\/gpmfactory.com\/?p=4702"},"modified":"2020-02-12T18:35:11","modified_gmt":"2020-02-12T17:35:11","slug":"creation-dun-magazine-imprime-a-partir-dun-groupe-facebook","status":"publish","type":"post","link":"https:\/\/gpmfactory.com\/index.php\/2020\/02\/11\/creation-dun-magazine-imprime-a-partir-dun-groupe-facebook\/","title":{"rendered":"Cr\u00e9ation d&rsquo;un magazine imprim\u00e9 \u00e0 partir d&rsquo;un groupe Facebook"},"content":{"rendered":"\n\n\n<h3 class=\"wp-block-heading\">Objectif<\/h3>\n\n\n\n<p>L&rsquo;objectif est de produire,  \u00e0 partir des articles d&rsquo;un groupe Facebook,  un <strong>magazine PDF destin\u00e9 \u00e0 \u00eatre imprim\u00e9<\/strong> . <\/p>\n\n\n\n<p>Un cas d&rsquo;usage est celui d&rsquo;une famille qui souhaite \u00e9diter un petit journal destin\u00e9 \u00e0 des personnes peu connect\u00e9es sur internet et pour qui le support papier reste un m\u00e9dia pr\u00e9f\u00e9rable. Il peut s&rsquo;agir aussi d&rsquo;un document rassemblant des reportages sportifs r\u00e9alis\u00e9s par les membres d&rsquo;une association. Par extension, les principes expos\u00e9s peuvent \u00eatre utilis\u00e9s par tout utilisateur Facebook pour la constitution d&rsquo;un magazine imprim\u00e9 \u00e0 partir de ses publications, ou tout simplement pour exporter son contenu vers un syst\u00e8me externe. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Approche<\/h3>\n\n\n\n<p>Le proc\u00e9d\u00e9 qui a \u00e9t\u00e9 choisi est le suivant:<\/p>\n\n\n\n<p>Extraire les publications d&rsquo;un groupe de fa\u00e7on programmatique en s&rsquo;appuyant sur l&rsquo;<a href=\"https:\/\/developers.facebook.com\/docs\/graph-api\">API Graph de Facebook<\/a> afin de r\u00e9cup\u00e9rer le texte, les images associ\u00e9es ainsi que l&rsquo;auteur et la date.<\/p>\n\n\n\n<p>Enregistrer les informations dans une database de fa\u00e7on \u00e0 pouvoir effectuer un post-traitement (filtrage, corrections orthographiques, mise \u00e0 l&rsquo;\u00e9cart de certaines publications selon des crit\u00e8res)<\/p>\n\n\n\n<p>Retraiter \u00e9ventuellement les images  de type paysage afin d&rsquo;obtenir un ratio diff\u00e9rent de celui utilis\u00e9 par Facebook qui est de 1,3 environ.<\/p>\n\n\n\n<p>Produire un document au format XML ou JSON et leur appliquer un gabarit de mise en page \u00e0 l&rsquo;aide d&rsquo;un moteur d&rsquo;\u00e9dition. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Principe et Architecture<\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li>Utilisation de l&rsquo;API Graph de Facebook (REST api) pour extraire en format JSON les \u00e9l\u00e9ments \u00e0 imprimer (photo + texte)<\/li><li>R\u00e9alisation d&rsquo;une interface utilisateur avec Oracle APEX pour extraire les articles via l&rsquo;API Graph, indiquer la p\u00e9riode \u00e0 s\u00e9lectionner dans le groupe ou la page et produire le fichier XML interm\u00e9diaire.<\/li><li>Traitement sp\u00e9cifique (<em>cropping<\/em>) des images avec ImageMagik afin d&rsquo;obtenir un ratio largeur\/hauteur adapt\u00e9 pour l&rsquo;impression en A4<\/li><li>Production du document PDF avec <a href=\"https:\/\/xmlgraphics.apache.org\/fop\/\">Apache FOP<\/a><\/li><li>Impression et fa\u00e7onnage du magazine<\/li><\/ul>\n\n\n\n<p>Les appels REST vers l&rsquo;api Graph sont lanc\u00e9es depuis du code PL\/SQL. C&rsquo;est donc une proc\u00e9dure stock\u00e9e dans la database qui coordonne les appels n\u00e9cessaires pour rassembler les articles contenant la description ainsi que le lien vers l&rsquo;image associ\u00e9e.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Architecture simplifi\u00e9e<\/h4>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"546\" src=\"http:\/\/gpmfactory.com\/wp-content\/uploads\/2020\/02\/Image2-1024x546.png\" alt=\"\" class=\"wp-image-4770\" srcset=\"https:\/\/gpmfactory.com\/wp-content\/uploads\/2020\/02\/Image2-1024x546.png 1024w, https:\/\/gpmfactory.com\/wp-content\/uploads\/2020\/02\/Image2-300x160.png 300w, https:\/\/gpmfactory.com\/wp-content\/uploads\/2020\/02\/Image2-768x409.png 768w, https:\/\/gpmfactory.com\/wp-content\/uploads\/2020\/02\/Image2.png 1855w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Dans le sch\u00e9ma d&rsquo;architecture ci-dessus, les services sont identifi\u00e9s par la couleur bleue. On constate qu&rsquo;il y en a trois. Dans mon cas, j&rsquo;ai group\u00e9 les services de traitement d&rsquo;image et Apache FOP sur une m\u00eame instance cloud de type <em>compute <\/em>tandis que l&rsquo;interface de pilotage (Application Oracle APEX) fonctionne sur une autre instance cloud. Il est bien sur possible de tout faire fonctionner sur un simple PC en local.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">R\u00e9alisation<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Cr\u00e9er un groupe Facebook<\/h4>\n\n\n\n<p>Pour m\u00e9moire: Cr\u00e9er un groupe Facebook ou en utiliser un d\u00e9j\u00e0 existant, indiquer une visibilit\u00e9 de type \u00ab\u00a0priv\u00e9\u00a0\u00bb et enr\u00f4ler les membres. Seul un administrateur de groupe peut inviter d&rsquo;autres membres, sous r\u00e9serve qu&rsquo;il ait d\u00e9j\u00e0 une connexion individuelle avec ceux-ci. Il est cependant possible de constituer un  groupe avec des membres qui ne poss\u00e8dent pas de connexion entre eux. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Cr\u00e9er une application Facebook<\/h4>\n\n\n\n<p>Cr\u00e9er une nouvelle application Facebook \u00e0 partir de la <a href=\"https:\/\/developers.facebook.com\/\">console de d\u00e9veloppement<\/a>. Dans le cadre du prototype, l&rsquo;application a \u00e9t\u00e9 gard\u00e9e dans un mode \u00ab\u00a0en cours de d\u00e9veloppement\u00a0\u00bb et n&rsquo;a pas \u00e9t\u00e9 publi\u00e9e.<\/p>\n\n\n\n<p>Tester le bon fonctionnement des APIs en se connectant \u00e0 la <a href=\"https:\/\/developers.facebook.com\/tools\/explorer\/v2\/\">console de d\u00e9veloppement API Explorer<\/a> (API Graph). Tout appel doit \u00eatre accompagn\u00e9 d&rsquo;un jeton d\u2019acc\u00e8s (<em>Access Token<\/em>) obtenu apr\u00e8s identification puis consentement quant aux privil\u00e8ges accord\u00e9s \u00e0 l&rsquo;application. cf <a href=\"#Manipulations_simples_sur_lAPI_Graph\">annexes<\/a><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignright\"><img loading=\"lazy\" decoding=\"async\" width=\"162\" height=\"166\" src=\"http:\/\/gpmfactory.com\/wp-content\/uploads\/2020\/02\/image-7.png\" alt=\"\" class=\"wp-image-4761\"\/><\/figure><\/div>\n\n\n\n<p>Tant que l&rsquo;application n&rsquo;a pas fait l&rsquo;objet d&rsquo;une demande de certification aupr\u00e8s de Facebook, l&rsquo;appel \u00e0 certaines m\u00e9thodes n&rsquo;est pas possible. C&rsquo;est le cas en particulier de la r\u00e9cup\u00e9ration du nom de l&rsquo;auteur d&rsquo;un article. Cela est \u00e9videmment tr\u00e8s g\u00eanant pour la fabrication de notre magazine, puisque il s&rsquo;agit d&rsquo;une information \u00e9ditoriale essentielle. Pour contourner cette limitation et puisque il n&rsquo;\u00e9tait pas dans mon intention d&rsquo;aller jusqu&rsquo;au bout du processus de d\u00e9claration de l&rsquo;application,  j&rsquo;ai demand\u00e9 aux contributeurs du groupe d&rsquo;ajouter syst\u00e9matiquement leur pr\u00e9nom sur la derni\u00e8re ligne de l&rsquo;article. Les pr\u00e9noms et les photos de profil sont g\u00e9r\u00e9s manuellement dans une table.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Cr\u00e9er une application de pilotage<\/h4>\n\n\n\n<p>Cr\u00e9er une application Oracle APEX \u00e0 partir d&rsquo;une instance APEX existante (depuis une instance <em>Oracle Free Tiers<\/em> par exemple, qui est gratuite). L&rsquo;instance https:\/\/apex.oracle.com risque d\u2019\u00eatre inadapt\u00e9e car il y a un quota d&rsquo;appels de services web qui est assez bas. Chaque extraction g\u00e9n\u00e8re un nombre d&rsquo;appels repr\u00e9sentant le double environ du nombre d&rsquo;articles<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Appliquer un traitement d&rsquo;image<\/h4>\n\n\n\n<p>Cette contrainte est li\u00e9e au choix de pouvoir disposer deux articles sur une  page A4. Il s&rsquo;agit d&rsquo;un choix de mise en page purement arbitraire. (cf plus loin sur la partie <a href=\"#Design_et_mise_en_page\">Design et mise en page<\/a>)<br>Les images de type paysage doivent \u00eatre retrait\u00e9es afin d&rsquo;obtenir un ratio 1,7 au lieu de 1,3. Pour cela on a recourt \u00e0 un traitement de recadrage pour aplatir l&rsquo;image tout en gardant les proportions d&rsquo;origine. Le choix technique est d&rsquo;installer un service \u00e9crit en php avec le module <a href=\"https:\/\/www.php.net\/manual\/fr\/book.imagick.php\">php_imagemagick<\/a>. <br>Il aurait \u00e9t\u00e9 possible d&rsquo;utiliser les packages Oracle ORD_IMAGE, mais ceux-ci n&rsquo;\u00e9taient pas disponibles dans l&rsquo;instance <em>Oracle Free Tiers<\/em> que j&rsquo;ai utilis\u00e9e.  <\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Fabriquer le document PDF<\/h4>\n\n\n\n<p>On utilise <a href=\"https:\/\/xmlgraphics.apache.org\/fop\/\">Apache FOP<\/a>. Il faut t\u00e9l\u00e9charger le logiciel sous Windows ou Linux. Il est possible de le faire fonctionner en mode commande, <em>standalone<\/em>. <\/p>\n\n\n\n<p>Il est important de bien param\u00e9trer FOP afin de disposer des polices de caract\u00e8res souhait\u00e9es. Pour cela, on param\u00e8tre le fichier de configuration avec la directive auto-detect (fichier de configuration fop.xconf) et on copie les polices de caract\u00e8res sur le serveur Linux, si n\u00e9cessaire. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;fonts>\n...   \n &lt;directory>C:\\Windows\\Fonts&lt;\/directory>\n\n    &lt;!-- auto-detect fonts -->\n    &lt;auto-detect\/>\n&lt;\/fonts><\/code><\/pre>\n\n\n\n<p>Une tache importante de r\u00e9alisation a consist\u00e9 \u00e0 mettre au point le gabarit de mise en page automatique. Ce <em>template<\/em> se pr\u00e9sente sous la forme d&rsquo;un fichier contenant des d\u00e9clarations XSLT de formatage. Les donn\u00e9es extraites depuis Facebook sont pr\u00e9sent\u00e9es en format XML \u00e0 Apache FOP qui les fusionne avec le template XSL.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Design et mise en page<\/h3>\n\n\n\n<p>Je me suis largement <a href=\"https:\/\/www.famileo.com\/bundles\/web\/files\/Gazette-DEMONSTRATION.pdf?v5-3\">inspir\u00e9 du design<\/a> utilis\u00e9 par le service payant <a href=\"https:\/\/www.famileo.com\/famileo\/fr-FR\/\">Famileo<\/a> et  j&rsquo;ai utilis\u00e9 les m\u00eames principes de formatage.<br>Leur choix de mise en page consiste \u00e0 assembler deux articles sur une m\u00eame page A4. Si l&rsquo;image est verticale, le texte est plac\u00e9 \u00e0 droite, sinon au-dessous dans le cas d&rsquo;une image horizontale. La quantit\u00e9 de texte est, d&rsquo;apr\u00e8s leur FAQ,  arbitrairement limit\u00e9e \u00e0 300 caract\u00e8res. <br><br>Une des cons\u00e9quences est que le rapport de forme (Largeur divis\u00e9e par hauteur)  pour les images horizontales est de l&rsquo;ordre de 1,7 au minimum alors qu&rsquo;il est de 1,3, voire moins pour les images enregistr\u00e9es dans Facebook. Cela explique que dans ce cas, il faut rogner les images en hauteur (cela fait l&rsquo;objet du traitement de recadrage qui est effectu\u00e9 \u00e0 la vol\u00e9e par le module PHP). <br>Pour le texte, j&rsquo;ai fix\u00e9 une limite plus haute que 300, quitte \u00e0 r\u00e9duire dans une certaine limite la taille des images selon l&rsquo;article.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"719\" height=\"633\" src=\"http:\/\/gpmfactory.com\/wp-content\/uploads\/2020\/02\/image-8.png\" alt=\"\" class=\"wp-image-4763\" srcset=\"https:\/\/gpmfactory.com\/wp-content\/uploads\/2020\/02\/image-8.png 719w, https:\/\/gpmfactory.com\/wp-content\/uploads\/2020\/02\/image-8-300x264.png 300w\" sizes=\"auto, (max-width: 719px) 100vw, 719px\" \/><figcaption>Echantillon de page avec deux articles<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Fa\u00e7onnage du magazine imprim\u00e9<\/h3>\n\n\n\n<p>Il faut faire un choix sur le format de papier et cette d\u00e9cision entra\u00eene un type de reliure correspondant. Le plus simple est de partir sur du format A4 \u00ab\u00a0portrait\u00a0\u00bb et d&rsquo;imprimer en recto-verso. Les feuilles sont ensuite agraf\u00e9es en cinq points sur le bord gauche et un ruban adh\u00e9sif opaque (blanc ou fantaisie) et plac\u00e9 par dessus les agrafes.<\/p>\n\n\n\n<p>L&rsquo;autre solution consiste \u00e0 partir sur du format A3 \u00ab\u00a0Paysage\u00a0\u00bb en mode recto\/verso et d&rsquo;imprimer sur deux colonnes. La reliure sera effectu\u00e9e par deux points de couture au milieu des deux colonnes. L&rsquo;avantage est de procurer de meilleures sensation \u00e0 la manipulation puisque les pages A3 seront pli\u00e9es et le magazine pourra se maintenir en position ouverte sur une table. Le probl\u00e8me \u00e0 r\u00e9soudre concerne le \u00ab\u00a0chemin de fer\u00a0\u00bb car les pages devront \u00eatre assembl\u00e9es dans un ordre qui n&rsquo;est pas s\u00e9quentiel:<\/p>\n\n\n\n<p>Par exemple la premi\u00e8re feuille physique comprend 4 pages:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>2<\/li><li>n-1<\/li><li>n<\/li><li>1 (couverture)<\/li><\/ul>\n\n\n\n<p>Je n&rsquo;ai pas encore \u00e9tudi\u00e9 cette option A3.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Conclusions et enseignements<\/h3>\n\n\n\n<p>La r\u00e9alisation automatis\u00e9e d&rsquo;un journal aboutit \u00e0 un r\u00e9sultat qui peut \u00eatre consid\u00e9r\u00e9 comme correct mais qui n&rsquo;est peut-\u00eatre pas aussi attractif que lorsque la composition est r\u00e9alis\u00e9e manuellement. <\/p>\n\n\n\n<p>L&rsquo;avantage d\u2019utiliser Facebook est de pouvoir constituer ais\u00e9ment un pool de participants, ind\u00e9pendamment de la tranche d&rsquo;age car FB est tr\u00e8s populaire \u00e0 la fois chez les jeunes et moins jeunes. Il n&rsquo;est donc pas n\u00e9cessaire de r\u00e9aliser un r\u00e9seau social priv\u00e9 avec  les inconv\u00e9nients de changement d&rsquo;habitude, confidentialit\u00e9, perte de mot de passe que cela aurait pu entra\u00eener.<\/p>\n\n\n\n<p>La destination des publications Facebook sur un support imprim\u00e9 impose une discipline dans la r\u00e9daction des articles et notamment une exigence quant \u00e0 la quantit\u00e9 minimum du texte associ\u00e9 \u00e0 l&rsquo;image. Or, sur FB, les usages donnent une plus grande importance \u00e0 l&rsquo;image qu&rsquo;au texte. Cela implique donc une coordination \u00e9ditoriale pour inciter les participants \u00e0 contribuer diff\u00e9remment de leurs habitudes.<\/p>\n\n\n\n<p>D&rsquo;un point de vue budget, il faut :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>disposer d&rsquo;un ordinateur sur lequel seront install\u00e9s tous les softs r\u00e9pertori\u00e9s plus haut ou bien avoir une instance en cloud<\/li><li>Co\u00fbt d&rsquo;impression des pages A4 en couleur recto\/verso : <br>environ 50 c \/feuille, soit 4 \u20ac pour un magazine de 8 pages<\/li><li>Co\u00fbt d&rsquo;envoi au destinataire: environ 2  \u20ac<\/li><\/ul>\n\n\n\n<p>Par comparaison, l&rsquo;abonnement mensuel \u00e0 Famileo et de 5,90\u20ac\/mois par destinataire, ce qui en faite une solution comp\u00e9titive s&rsquo;il n&rsquo;y a qu&rsquo;un seul destinataire.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Annexes<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Mat\u00e9riel, Code, templates<\/h4>\n\n\n\n<p>Sera mis \u00e0 disposition plus tard sur Github. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Manipulations simples sur l&rsquo;API Graph<\/h4>\n\n\n\n<ul class=\"wp-block-list\"><li>Pour obtenir la liste des groupes:<br>\/me\/groups<\/li><li>Liste des posts<br>\/&lt;group_id&gt;\/feed?since=&lt;date_depart au format YYYY-MM-DD&gt;<\/li><li>R\u00e9cup\u00e9rer les images<br>\/&lt;feed_id\/attachments<\/li><\/ul>\n\n\n\n<p>Remarque: si la publication Facebook est issue d&rsquo;un partage depuis un espace personnel ou bien une page ou un autre groupe, il faut effectuer un appel suppl\u00e9mentaire car l&rsquo;\u00e9l\u00e9ment est consid\u00e9r\u00e9 comme une story.  cf <em>subattachments <\/em><\/p>\n\n\n<p><!--EndFragment--><\/p>\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Objectif L&rsquo;objectif est de produire, \u00e0 partir des articles d&rsquo;un groupe Facebook, un magazine PDF destin\u00e9 \u00e0 \u00eatre imprim\u00e9 . Un cas d&rsquo;usage est&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"ppma_author":[150],"class_list":["post-4702","post","type-post","status-publish","format-standard","hentry","category-non-classe"],"authors":[{"term_id":150,"user_id":1,"is_guest":0,"slug":"admin8700","display_name":"Patrick","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/209d5ed69b74d288390621ab4c1d3773?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/posts\/4702","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/comments?post=4702"}],"version-history":[{"count":36,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/posts\/4702\/revisions"}],"predecessor-version":[{"id":4776,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/posts\/4702\/revisions\/4776"}],"wp:attachment":[{"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/media?parent=4702"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/categories?post=4702"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/tags?post=4702"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/ppma_author?post=4702"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}