J2S LayoutToolbox - automatiser
Version #29 du 15052014
Contexte
Cette documentation décrit comment déclencher l’exécution d’un module à partir de différents environnements comme Python par exemple.
Présentation
J2S NetToolbox est un serveur de requêtes TCP/IP.
Seul, J2S NetToolbox sait traiter nativement certains types de requêtes comme “ExportDocToPDF” qui permet de demander à Adobe InDesign d’exécuter un script JavaScript (voir plus bas pour la description de cette requête).
J2S LayoutToolbox est le moteur permettant de fabriquer une mise en page.
C’est une extension à J2S NetToolbox.
Les requêtes J2S !NetToolbox sont des structures XML. Pour déclencher cette requête, il faut poster cette structure XML en employant le protocole de communication J2S NetToolbox. Une fois le traitement terminé, J2S NetToolbox renvoie une structure XML contenant le résultat.
Communiquer avec J2S NetToolbox
J2S NetToolbox est un serveur TCP/IP qui “écoute” les requêtes sur le port 60666 par défaut.
Les requêtes sont des structures XML préfixées par un entête. L’entête est composé du préfixe “J2SX” de quatre octets suivi de quatre autres octets contenant la longueur de la structure XML au format “big endian”.
Le résultat est renvoyé sous la même forme.
Exemple d’envoi de requête en Python :
import socket
HOST= "127.0.0.1"
PORT= 60666
s= socket.socket(socket.AF\_INET, socket.SOCK\_STREAM)
s.connect((HOST, PORT))
s.send("J2SX");
requestLength= len(requestAsAString)
s.send(chr((requestLength >> 24) % 256));
s.send(chr((requestLength >> 16) % 256));
s.send(chr((requestLength >> 8) % 256));
s.send(chr(requestLength % 256));
s.send(requestAsAString);
receivedAnswer= ""
while True:
data= s.recv(1024)
if not data: break
receivedAnswer= receivedAnswer+data
s.close()
receivedAnswer= receivedAnswer\[8:]
print 'Received', receivedAnswer
Pour demander à J2S NetToolbox d’écouter un autre port, il faut éditer le fichier “NTBConfigurationFile.xml”. Il suffit alors de changer l’attribut “portIn” dans la ligne originale suivante :
<tcpIp portIn="60666" portOut="60667" />
Ne pas oublier de redémarrer Adobe InDesign après le changement.
Sous Mac OS, ce fichier se trouve dans le package du plug-in (“/Applications/Adobe InDesign CS6/Plug-Ins/J2SNetToolbox_CS6.InDesignPlugin/Versions/A/NTBConfigurationFile.xml” par exemple).
Sous Windows, il se trouve à côté du plug-in ou dans le dossier des préférences d’Adobe InDesign.
La structure de la requête J2S NetToolbox
Une requête est composée d’un élément XML racine “Request” qui possède un attribut “name” et un nombre variable d’attributs et éléments fils secondaires.
L’attribut “name” est le plus important, car il détermine le type de requête qui va être exécuté par le serveur (la liste des requêtes supportées est décrite plus loin dans ce document).
Chaque requête possède son lot propre de paramètres passés dans les attributs ou dans les éléments fils de l’élément “Request” racine.
Par exemple, cette requête va demander à J2S NetToolbox sa version :
<?xml version=”1.0” encoding=”UTF-8” standalone=”no” ?>
<Request name="NTBServerVersion" />
J2S NetToolbox répondra par exemple :
<ResultList err="0">
<Result date="Mar 14 2013" err="0" errMsg="" name="NTBServerVersion" time="14:26:05" version="2.0.7"/>
À noter que J2S Module Editor permet de voir la requête envoyée à J2S NetToolbox pour exécuter un module (lancer J2S Module Editor, afficher la console après une exécution).
Exploiter un module de fiche J2S LayoutToolbox
Créer une mise en page (exécuter un module)
J2S LayoutToolbox ajoute un nouveau type de requête à J2S NetToolbox : “CreateLabel”.
“CreateLabel” nécessite les paramètres suivants :
- “xmlPath” est un chemin vers le fichier XML de commande (voir plus loin).
- “debugLevel” permet de choisir le niveau que l’on veut pour le fichier de log qui sera créé à côté du fichier XML de commande :
- 0 = pas de log,
- 1 = erreurs,
- 2 = erreurs + warnings,
- 3 = erreurs + warnings + infos,
- 4 = erreurs + warnings + infos + debug.
- “keepFileOpen” permet de garder le document InDesign ouvert en fin de génération (utile surtout en phase de tests).
Exemple de fichier XML de commande :
<Root>
<DataBase path="/J2S/Documents_Clients/J2S_LYTB/MAJ/Database.xml" />
<TemplateMgr persistence="1" rootFolderPath="/Applications/J2S Module Editor.app/Contents/Resources/scripts" />
<Document path="/J2S/Documents_Clients/J2S_LYTB/MAJ/ccc(AVirer).indd" create="force" width="210" height="297" master="/J2S/Documents_Clients/J2S_LYTB/MAJ/Cockpit_FondDePage.indd">
<Spread>
<Page>
<Label templateName="Module2" templatePath="/J2S/Documents_Clients/ 2S_LYTB/MAJ/Gabarit.indd" productID="P1" x="0" y="0" width="105" height="147.5" />
</Page>
</Spread>
</Document>
Ce fichier décrit les traitements qui vont être effectués par J2S LayoutToolbox :
- L’élément “DataBase” regroupe les options concernant la base de données :
- L’attribut “path” contient le chemin d’accès au fichier XML contenant les données.
- L’élément “TemplateMgr” regroupe les options concernant le gestionnaire des modules :
- L’attribut “persistence” doit être mis à 1 si la page générée peut être mise à jour dans un second temps.
- L’attribut “rootFolderPath” contient le chemin d’accès aux scripts standards. Quand le module à exécuter contient un appel à un script standard, cet attribut doit être spécifié.
- Le nœud “Document” décrit le fichier Adobe InDesign qui va être créé :
- L’attribut “path” contient le chemin d’accès au fichier Adobe InDesign qui sera créé.
- “width” et “height” contiennent les dimensions des pages en millimètres.
- “create=force” permet d’écraser le fichier Adobe InDesign s’il existe déjà.
- “master” permet de préciser le chemin d’accès à un fichier Adobe InDesign qui servira de base à la génération.
- Sous le nœud “Document”, “Spread” permet d’indiquer qu’il faut créer une planche (un “spread”). Dans cette page sera placé un enregistrement grâce au nœud “Label”.
- “Label” permet d’exécuter un module J2S LayoutToolbox :
- “templateName” définit le nom du module. “templatePath” définit le chemin d’accès au fichier Adobe InDesign associé au module.
- “productID” contient l’ID du produit dont les données seront utilisées pour exécuter le module.
- “x”, “y”, “width”, “height” indiquent où placer la mise en page dans la page. L’unité est toujours le millimètre.
Exemple
L’exemple effectue un appel J2S NetToolbox qui crée un fichier Adobe InDesign à l’aide de J2S LayoutToolbox.
Le code source se trouve dans le fichier “CockpitCreateLabel.py”.
L’exemple a été développé en Python.
Pour exécuter l’exemple, utiliser la syntaxe suivante :
python CockpitCreateLabel.py -p "/Chemin d’accès au dossier/Cockpit"
Mettre à jour
Le principe est le même que lors de l’exécution.
La différence se situe au niveau du fichier XML de commande.
Exemple de fichier XML de commande :
<?xml version="1.0" encoding="UTF-8" ?>
<Root>
<DataBase path="/J2S/Documents_Clients/Francis_Bilard/DemoAuchan/CUG_DataBase2.xml" rootFolderPath="/J2S/Documents_Clients" />
<TemplateMgr rootFolderPath="/J2S/Documents_Clients/Francis_Bilard/DemoAuchan/Gabarits" />
<!-- Ouverture de document deja existant -->
<Document path="/J2S/Documents_Clients/Francis_Bilard/DemoAuchan/WF/SECTIONS_Out.indd" create="no">
<UpdateFields productID="*" onlyIfPresentInDB="1">
<dbField dbPath="*" />
</UpdateFields>
</Document>
</Root>
On insère dans ce fichier une balise “UpdateFields” qui détermine le niveau à partir duquel effectuer la mise à jour.
Cette balise peut donc être placée sous les balises “Document”, “Spread” ou “Page”.
Le choix des produits à mettre à jour se fait par l’attribut “productID” qui peut comporter les jokers “*” et “?” (pour faire des mises à jour multiples).
L’attribut “onlyIfPresentInDB” à 1 permet de ne pas faire d’erreur quand un produit n’est pas retrouvé dans la base de données. Cela permet de faire une mise à jour partielle limitée à l’extrait de base de données en mettant “*” dans “productID”.
Sous la balise “UpdateFields”, on indique les champs à mettre à jour avec des balises “DBField” : Le choix des produits à mettre à jour se fait par l’attribut “dbPath” qui peut prendre des jokers “*” et “?” pour faire des mises à jour multiples.
Exploiter un module de page J2S LayoutToolbox
Créer une mise en page (exécuter)
Pour rappel : la génération se fait grâce à un appel NTB avec une requête “PlayScript” qui exécute un fichier Script (“LYTB_Generate.jsx”).
L’activation de la persistance se fait par l’ajout d’un attribut persistence=“1” dans la liste des propriétés passées par le script à InDesign.
Si on a besoin de choisir le comportement à la volée, on rajoutera aussi ce paramètre dans l’appel NTB.
Pour permettre la persistance et la MAJ des sections, il faut leur rajouter un id dans le fichier XML de la BDD.
Lors d’une création avec persistance, de nouvelles informations sont stockées dans la structure XML d’ID pour permettre la future MAJ.
Toutes les balises boites d’un même produit sont regroupées au sein d’une balise Product (avec un attribut id pour les retrouver dans la BDD).
Toutes les balises enfants des boites associées à une valeur de BDD reçoivent un attribut dbid (+ un attribut pour la langue si nécessaire).
On considère comme un produit, le résultat d’une génération issue d’un module. Chaque Label d’un fichier de commande XML de CreateLabel génère un produit. Une génération Têtu ne génère qu’un seul produit, car c’est un seul module avec plein de répéteurs. La génération de la démo Auchan crée un produit par fond de page en plus de ceux générés pour chaque vrai produit.
Pour différencier les produits de niveaux différents, un attribut “kind” est rajouté sur les produits qui ne sont pas “standard” : pour l’instant, il n’y a que “Section”.
Il n’y a pas d’imbrication des niveaux de produits : en mode livre, on ne retrouvera pas la hiérarchie Section/Produit dans la structure XML d’ID et on ne stocke pas cette information. Les IDs d’un niveau doivent donc être uniques pour la globalité du doc.
Mettre à jour
Mise à jour de sections, exemple de fichier XML de commandes :
<?xml version="1.0" encoding="UTF-8" ?>
<Root>
<DataBase path="/J2S/Documents_Clients/Francis_Bilard/DemoAuchan/CUG_DataBase2.xml" rootFolderPath="/J2S/Documents_Clients" />
<TemplateMgr rootFolderPath="/J2S/Documents_Clients/Francis_Bilard/DemoAuchan/Gabarits" />
<!-- Ouverture de document deja existant -->
<Document path="/J2S/Documents_Clients/Francis_Bilard/DemoAuchan/WF/SECTIONS_Out.indd" create="no">
<UpdateFields productID="*" onlyIfPresentInDB="1" productKind="Section">
<DBField dbPath="*" />
</UpdateFields>
</Document>
</Root>
Les requêtes J2S NetToolbox
Grouper les requêtes
Il est possible de regrouper plusieurs requêtes en utilisant le nœud “RequestList”. Par exemple :
<?xml version=”1.0” encoding=”UTF-8” standalone=”no” ?>
<RequestList> <Request name="Add" lVal="1" rVal="2"/>
<Request name="Multiply" lVal="23" rVal="37"/>
<Request name="Add" lVal="1.5" rVal="17.356"/>
</RequestList>
Cette requête renverra le résultat suivant :
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<ResultList err="0">
<Result err="0" name="Add" value="3"/>
<Result err="0" name="Multiply" value="851"/>
<Result err="0" name="Add" value="18.856"/>
</ResultList>
Les résultats “Result” seront récupérés dans une liste de résultats “ResultList”. Une erreur globale est remontée sur la liste de résultats. Une valeur zéro indique que tout s’est bien passé, une valeur différente de zéro indique une erreur en cours de traitement des sous- requêtes. La dernière sous-requête pour laquelle il y a un résultat est celle qui pose problème.
Les variables
Pour déclarer une variable et lui affecter une valeur, il suffit de passer un attribut qui commence par “var_”.
Par exemple, pour définir 2 variables V1 et V2, on peut écrire :
<Request var\_V1="12" var\_V2="34" />
Pour utiliser une variable, il suffit de mettre son nom entre %. Par exemple :
<Request name="Add" lVal="%V1%" rVal="%V2%" />
On peut aussi récupérer un résultat dans une variable. Pour cela, il faut rajouter un attribut qui commence par “var_result_” dans la ligne produisant le résultat voulu. La valeur de l’attribut doit contenir le nom du résultat que l’on veut récupérer. Par exemple, pour récupérer le résultat de l’addition dans une variable V3 :
<Request name="Add" lVal="%V1%" rVal="%V2%" var\_result\_V3="value"/>
Voilà l’exemple complet :
<RequestList>
<Request var\_V1="12" var\_V2="34" />
<Request name="Add" lVal="%V1%" rVal="%V2%" var\_result\_V3="value"/>
<Request name="Multiply" lVal="10" rVal="%V3%"/>
</RequestList>
Pour l’instant, la portée des variables est locale à la liste de requêtes en cours.
Comme les variables utilisent le caractère %, il faut le quoter (%%) s’il apparait dans le contenu de paramètres des requêtes.
Requêtes supportées
Add
<Request name="Add" lVal="2" rVal="3"/>
<Result err="0" value="5" />
CloseDoc
Voir “CloseDoc”.
CreateLabel
Voir plus haut.
ExportDocToPDF
<RequestList>
<Request name="OpenDoc" docPath="file:///J2S/SampleDoc.indd" var\_result\_DOCREF="docRef"/>
<Request name="ExportDocToPDF" docRef="%DOCREF%" pdfPath="file:///J2S/SampleDoc.pdf" presetName="\[High Quality Print]" firstPage="-1" lastPage="-1" />
<Request name="CloseDoc" docRef="%DOCREF%" />
</RequestList>
Cette liste de requêtes :
* Ouvre un document InDesign et sauvegarde une référence sur le doc ouvert. C’est ce qui va servir à référencer le doc dans tous les appels suivants.
* Fait un export PDF de toutes les pages en utilisant un preset PDF donné.
* Ferme le document.
Voici le résultat quand tout se passe correctement :
<?xml version="1.0" encoding="UTF-8" standalone="no" ?><ResultList err="0">
<Result docRef="1372317360\_1" err="0" name="OpenDoc"/>
<Result err="0" name="ExportDocToPDF"/>
<Result err="0" name="CloseDoc"/>
</ResultList>
ExportDocToJPG
<RequestList>
<Request name="OpenDoc" docPath="file:///J2S/SampleDoc.indd" var\_result\_DOCREF="docRef"/>
<Request name="ExportDocToJPG" asSpread="0" firstPage= "0" lastPage= "0" scaleFactor="1" docRef="%DOCREF%" quality="2" jpgPath="file:///J2S/SampleDoc"/>
<Request name="CloseDoc" docRef="%DOCREF%" />
</RequestList>
Cette liste de requêtes :
- Ouvre un document InDesign et sauvegarde une référence sur le doc ouvert. C’est ce qui va servir à référencer le doc dans tous les appels suivants.
- Fait un export JPEG de qualité moyenne de la première page du document à 72 dpi et stocke le résultat dans “/J2S/SampleDoc0.jpg”.
- Ferme le document.
Voici le résultat quand tout se passe correctement :
<?xml version="1.0" encoding="UTF-8" standalone="no" ?><ResultList err="0">
<Result docRef="1372317360\_1" err="0" name="OpenDoc"/>
<Result err="0" name="ExportDocToJPG"/>
<Result err="0" name="CloseDoc"/>
</ResultList>
Paramètres :
- “docRef” : le document à traiter.
- “scalefactor” : permet d’agrandir ou réduire la taille du JPEG créé ; 1 équivaut à exporter la page à 72 dpi ; 2 doublera le nombre de pixels.
- “quality” : il s’agit de la qualité du JPEG ; ce champ peut prendre les valeurs 0 à 3 (2 par défaut).
- “asSpread” : si ce champ vaut 1, on indique que l’on veut spécifier les planches à exporter à l’aide des paramètres “firstspread” et “lastspread” ; si ce champ vaut 0, des pages seront exportées et les paramètres “firstpage” et “lastPage” seront employés.
- firstSpread : indice de la première planche à exporter.
- lastSpread : indice de la dernière planche à exporter.
- firstPage : indice de la première page à exporter.
- lastPage : indice de la dernière page à exporter.
- jpgPath : chemin d’accès au fichier JPEG qui sera créé ; comme plusieurs pages ou plusieurs planches peuvent être exportées, il ne faut pas spécifier le suffixe dans ce chemin ; un indice et le suffixe “jpg” seront automatiquement ajoutés.
Multiply
<Request name="Multiply" lVal="2" rVal="3"/>
<Result err="0" value="6" />
OpenDoc
Voir “ExportDocToPDF”.
Paramètres :
- “closeMode” : avec cette option, il est inutile de fermer explicitement le document, il sera fermé dès que possible en fonction de l’option spécifiée. Options possibles :
- “NONE” : le fichier n’est pas fermé automatiquement.
- “ASAP_DONTSAVE” : le fichier est fermé dès que possible sans sauvegarder les modifications.
- “ASAP_SAVEALWAYS” : le fichier est fermé dès que possible en sauvegardant les modifications.
- “ASAP_SAVEIFNOERR” : le fichier est fermé dès que possible en ne sauvegardant pas les modifications si une erreur s’est produite.
NTBServerVersion
<Request name="NTBServerVersion" />
<Result date="May 4 2010" err="0" name="NTBServerVersion" time="17:59:11" version="1.8.0"/>
Liste des erreurs
Numéro | ID | Description |
---|---|---|
–30000 | Not implemented function | Fonction pas implémentée |
–30001 | Null object | Utilisation d’un objet pas créé |
–30007 | Unexpected data | Donnée inattendue |
–30014 | Out of interval index | Index hors intervalle |
–30031 | Premature end of data | Fin prématurée des données |
–30032 | No more space | Plus de place disponible |
–30033 | Value not yet computed | Utilisation d’une valeur pas encore calculée |
–30034 | Container not found | Conteneur pas trouvé |
–30035 | Unexpected container type | Type de conteneur inattendu |
–30036 | Unexpected method call | Appel de methode inattendu |
–30037 | Undefined identifier | Identifieur indéfini |
–30038 | Master spread not found | Master Spread non trouvé |
–30039 | Separator not found | Séparateur non trouvé |
–30040 | Page not found in spread | Page non trouvée dans le spread |
–30041 | Unknown name | Nom inconnu |
–30042 | Undefined root folder | Le dossier racine n’est pas défini |
–30043 | LYTB Scripting Object not found | Objet de scripting LYTB non trouvé |
–30044 | Object is locked | Objet verrouillé |
–30200 | Not supported | Fonction pas supportée dans cette version |
–30201 | Not yet available | Fonction pas encore disponible |
–30202 | Not applicable | Fonction pas applicable dans le contexte ou sur le type de données |
–30203 | Invalid UIDRef | Référence à un objet InDesign (UIDRef) invalide |
–30204 | Invalid story ref. | Référence à un texte InDesign invalide |
–30205 | Invalid box ref. | Référence à une boite InDesign invalide |
–30206 | Invalid text range | Référence à une portion de texte InDesign invalide |
–30207 | Incorrect box type: graphic type awaited | La boite n’est pas du bon type : type graphique attendu. |
–30208 | Incorrect box type: text type awaited | La boite n’est pas du bon type : type texte attendu. |
–30209 | Invalid doc ref. | Référence à un document InDesign invalide. |
–30210 | No front document | Pas de document InDesign ouvert. |
–30211 | Link resource not found | Ressource non trouvée dans une boite image. |
–30212 | Invalid table cell address | Utilisation d’une cellule de tableau InDesign invalide |
–30213 | Duplicates not allowed | Doublons non autorisés |
–30214 | Invalid text tag reference | Référence à un tag de texte invalide |
–30215 | Invalid XML reference | Référence à un tag XML invalide |
–30216 | Invalid table row range | Utilisation d’un ensemble de lignes de tableau InDesign invalide |
–30217 | Layer not found | Calque non trouvé |
–31001 | Exception err | Exception (probablement dans le traitement de données XML). |
–31005 | Null XML | Noeud XML vide |
–31006 | Bad XML root name | Le nom de la racine des données XML ne correspond pas à celle attendue |
–31007 | XML element not found | Element XML non trouvé |
–31008 | XML attribute not found | Attribut XML non trouvé |
–31009 | XML node not found | Noeud XML non trouvé |
–31010 | Bad XML node type | Le type du noeud XML ne correspond pas à celui attendu |
–31020 | Cannot get XML node name | Impossible d’avoir le nom du noeud XML |
–31021 | Cannot get XML node value | Impossible d’avoir la valeur du noeud XML |
–31022 | XML stream failure | Erreur lors de l’ouverture du flux XML |
–31023 | XML parse failure | Erreur lors du parcours de données XML |
–31024 | XPathLight request not well formed | Requête XPathLight mal formée |
–31030 | ID XML structure element not found | Element de la structure XML InDesign non trouvé |
–31031 | ID XML attribute element not found | Attribut de la structure XML InDesign non trouvé |
–31032 | ID style not found | Style InDesign non trouvé |
–31033 | ID style hierarchy not found | Hiérarchie de style InDesign non trouvée |
–31034 | Page duplication failure | Erreur lors de la duplication d’une page InDesign |
–31035 | Page item size too small | Changement de la taille d’un bloc InDesign avec une valeur trop petite |
–31036 | Value not found | Valeur non trouvée |
–31037 | Special value not found | Valeur spéciale non trouvée |
–31038 | CallBack type not specified | Type de call-back non renseigné |
–31039 | Parameter not found | Paramètre non trouvé |
–32000 | Request not processed | Requête non traitée |
–32001 | Undefined variable | Variable indéfinie |
–32002 | Undefined result variable | Variable de résultat indéfinie |
–32003 | PDF Preset not found | Preset PDF non trouvé |
–32004 | Label not found | Label not found |
–32005 | Empty path | Chemin vers un fichier ou un dossier vide |
–32006 | Cannot create IDFile | Impossible de créer un spécificateur de fichier InDesign |
–32007 | Circular reference | Référence cyclique |
–32008 | Cannot create write file stream | Impossible de créer un flux de sortie (ou un fichier) |
–32009 | Mismatching databases | Utilisation conjointe d’objets provenant de plusieurs documents InDesign |
–32010 | Cannot create copy file | Impossible de faire une copie du fichier |
–32011 | Cannot delete output file | Impossible de supprimer le fichier de sortie |
–32012 | Document already open | Document déjà ouvert |
–32100 | J2S licence not found | Licence J2S non trouvée |
–32101 | J2S licence not readable | Impossible de lire la licence J2S |
–32102 | J2S licence expired | Licence J2S expirée |
–32103 | J2S licence invalid | License J2S invalide ou corrompue |
En plus de ces erreurs propres à J2S LayoutToolbox et à J2S NetToolbox, les erreurs liées au système peuvent être émises (erreur Mac OS ou Windows).
De même, des erreurs propres à Adobe InDesign peuvent être mentionnées (la plus courante est l’erreur générique 1 qui indique qu’un traitement Adobe InDesign a échoué).