# HG changeset patch # User František Kučera <franta-hg@frantovo.cz> # Date 1341146601 -7200 # Node ID aa91d1c6d4c10250d4d5bc1afca162661546ab35 # Parent ca045963fced26d434465a91c59f29e5e754fcac #20 Skriptování: možnost spouštět skripty ze souborů (atribut: src). diff -r ca045963fced -r aa91d1c6d4c1 vstup/skriptování-proměnné.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vstup/skriptování-proměnné.pl Sun Jul 01 14:43:21 2012 +0200 @@ -0,0 +1,16 @@ +#!/usr/bin/perl + +# Projde zdroják v javě a najde v něm, +# jaké proměnné prostředí se nastavují pro běh skriptů + +use strict; +use warnings; + +open(JAVA, "<", $ENV{"XWG_SKRIPTOVANI_JAVA"}) or die $!; + +while (<JAVA>) { + if (/"(.*)=".*\/\/\s+env:(.*)/) { + print "<tr><td><code>$1</code></td><td>$2</td></tr>\n"; + } +} + diff -r ca045963fced -r aa91d1c6d4c1 vstup/skriptování.xml --- a/vstup/skriptování.xml Sat Jun 23 23:19:09 2012 +0200 +++ b/vstup/skriptování.xml Sun Jul 01 14:43:21 2012 +0200 @@ -21,9 +21,16 @@ </p> <p> - Díky skriptování můžeme stránky obohatit o prakticky libovolný obsah. - Tato funkce ale může být nebezpečná – pokud byste spustili generátor na stránkách, + Díky skriptování můžeme stránky obohatit o prakticky libovolný obsah – + jak prostý text, tak i XHTML fragmenty.<m:podČarou>zapíná se pomocí atributu + <code>výstup="xml"</code> a generátor pak kontroluje správné formátování – + nestane se vám, že byste omylem vygenerovali stránky s překříženými nebo neuzavřenými značkami.</m:podČarou> + </p> + <p> + Skriptování ale může být nebezpečné, pokud byste spustili generátor na stránkách, které psal někdo nedůvěryhodný a vložil do nich škodlivý kód. + Kromě toho, ukázková sada stránek by měla být přeložitelná kdekoli a mít minimum závislostí + (ne každý musí mít nainstalovaný Perl nebo Python či další podporované interprety). Proto je skriptování ve výchozím stavu vypnuté – je potřeba ho povolit v souboru <code>web.conf</code>. </p> @@ -40,8 +47,9 @@ </tr> </thead> <tbody> - <m:skript jazyk="perl" výstup="xml"><![CDATA[ + <m:skript jazyk="perl" výstup="xml"><![CDATA[ use strict; +use warnings; open(JAVA, "<", $ENV{"XWG_SKRIPTOVANI_JAVA"}) or die $!; @@ -62,6 +70,7 @@ --> <pre><m:skript jazyk="perl"><![CDATA[ use strict; +use warnings; open(XML, "<", $ENV{"XWG_STRANKA_SOUBOR"}); my %skripty; @@ -109,18 +118,8 @@ </tr> </thead> <tbody> - <m:skript jazyk="perl" výstup="xml"><![CDATA[ -use strict; - -open(JAVA, "<", $ENV{"XWG_SKRIPTOVANI_JAVA"}) or die $!; - -while (<JAVA>) { -#i.put("bash", "/bin/bash"); - if (/"(.*)=".*\/\/\s+env:(.*)/) { - print "<tr><td><code>$1</code></td><td>$2</td></tr>\n"; - } -} - ]]></m:skript> + <!-- Pokud načítáme skript ze souboru, je atribut jazyk nepovinný. --> + <m:skript jazyk="perl" výstup="xml" src="skriptování-proměnné.pl"/> </tbody> </table> diff -r ca045963fced -r aa91d1c6d4c1 šablona/funkce/src/cz/frantovo/xmlWebGenerator/makra/Skriptování.java --- a/šablona/funkce/src/cz/frantovo/xmlWebGenerator/makra/Skriptování.java Sat Jun 23 23:19:09 2012 +0200 +++ b/šablona/funkce/src/cz/frantovo/xmlWebGenerator/makra/Skriptování.java Sun Jul 01 14:43:21 2012 +0200 @@ -55,7 +55,8 @@ * TODO: podporovat i složitější scénáře (např. kompilaci), * než jen vložení do souboru a přidání správného záhlaví. * - * @param skript program k vykonání + * @param skriptText skript k vykonání + * @param skriptSoubor cesta k souboru se skriptem/programem * @param jazyk programovací jazyk * @param výstupníFormát text (výchozí) | xml (v tom případě kontrolujeme validitu) * @param uriStránky URI aktuálně generované stránky → proměnná prostředí @@ -63,66 +64,91 @@ * @param perexStránky perex stránky → proměnná prostředí * @return výstup příkazu */ - public static String interpretuj(String skript, String jazyk, String výstupníFormát, String uriStránky, String nadpisStránky, String perexStránky) { + public static String interpretuj(String skriptText, String skriptSoubor, String jazyk, String výstupníFormát, String uriStránky, String nadpisStránky, String perexStránky) { try { - System.err.println("\tInterpretuji skript v jazyce: " + jazyk); - String interpret = interpreti.get(jazyk); - if (interpret == null) { - System.err.println("Neznámý skriptovací jazyk: " + jazyk); - return null; + if (isNeprázdný(skriptSoubor)) { + System.err.println("\tInterpretuji skript ze souboru: " + skriptSoubor); } else { - File f = File.createTempFile("xml-web-generátor-", ".skript"); + System.err.println("\tInterpretuji skript v jazyce: " + jazyk); + } + + File souborStránky = new File(new URI(uriStránky)); + File f; + + if (isNeprázdný(skriptText)) { + /** Skript je zadán uvnitř elementu přímo ve stránce */ + String interpret = interpreti.get(jazyk); + if (interpret == null) { + throw new Exception("Neznámý skriptovací jazyk: " + jazyk); + } + + f = File.createTempFile("xml-web-generátor-", ".skript"); f.deleteOnExit(); + f.setExecutable(true); PrintStream ps = new PrintStream(f); ps.print("#!"); ps.println(interpret); ps.println(); - ps.print(skript); + ps.print(skriptText); ps.close(); + } else if (isNeprázdný(skriptSoubor)) { + /** Skript/program je uložen v externím souboru */ + if (skriptSoubor.startsWith(File.separator)) { + /** absolutní cesta */ + f = new File(skriptSoubor); + } else { + /** relativní cesta */ + f = new File(souborStránky.getParent(), File.separatorChar + skriptSoubor); + } + + if (!f.canExecute()) { + throw new Exception("Soubor se skriptem není spustitelný → nastavte: chmod +x " + f); + } + } else { + throw new Exception("Musí být vyplněn text skriptu, nebo cesta k souboru."); + } - String[] prostředí = new String[]{ - "LANG=" + System.getenv("LANG"), - "USER=" + System.getenv("USER"), - "XWG_SKRIPTOVANI_JAVA=" + "šablona" + File.separator + "funkce" + File.separator + "src" + File.separator + Skriptování.class.getName().replaceAll("\\.", File.separator) + ".java", - "XWG_STRANKA_URI=" + uriStránky, // env:URI aktuálně zpracovávané stránky - "XWG_STRANKA_SOUBOR=" + (new File(new URI(uriStránky)).getAbsolutePath()), // env:absolutní cesta k souboru - "XWG_STRANKA_NADPIS=" + nadpisStránky, // env:nadpis stránky - "XWG_STRANKA_PEREX=" + perexStránky // env:perex stránky - }; + String[] prostředí = new String[]{ + "LANG=" + System.getenv("LANG"), + "USER=" + System.getenv("USER"), + "XWG_SKRIPTOVANI_JAVA=" + "šablona" + File.separator + "funkce" + File.separator + "src" + File.separator + Skriptování.class.getName().replaceAll("\\.", File.separator) + ".java", + "XWG_STRANKA_URI=" + uriStránky, // env:URI aktuálně zpracovávané stránky + "XWG_STRANKA_SOUBOR=" + souborStránky.getAbsolutePath(), // env:absolutní cesta k souboru + "XWG_STRANKA_NADPIS=" + nadpisStránky, // env:nadpis stránky + "XWG_STRANKA_PEREX=" + perexStránky // env:perex stránky + }; - f.setExecutable(true); - Runtime r = Runtime.getRuntime(); - Process p = r.exec(new String[]{f.getAbsolutePath()}, prostředí); + Runtime r = Runtime.getRuntime(); + Process p = r.exec(new String[]{f.getAbsolutePath()}, prostředí); - String výsledek = načtiProud(p.getInputStream()); - String chyby = načtiProud(p.getErrorStream()); + String výsledek = načtiProud(p.getInputStream()); + String chyby = načtiProud(p.getErrorStream()); - p.waitFor(); - - if (p.exitValue() == 0) { - if (chyby.length() > 0) { - System.err.println("--- Chybový výstup skriptu -----"); - System.err.println(chyby); - System.err.println("--------------------------------"); - System.err.println("Nicméně skript skončil úspěšně, takže pokračujeme dál."); - } + p.waitFor(); - return připravVýstup(výsledek, výstupníFormát); - } else { - System.err.println("--- Standardní výstup skriptu: -----"); - System.err.println(výsledek); - System.err.println("--- Cyhbový výstup skriptu: ---------"); + if (p.exitValue() == 0) { + if (chyby.length() > 0) { + System.err.println("--- Chybový výstup skriptu -----"); System.err.println(chyby); - System.err.println("--------------------------------------"); - throw new RuntimeException("Návratová hodnota: " + p.exitValue()); + System.err.println("--------------------------------"); + System.err.println("Nicméně skript skončil úspěšně, takže pokračujeme dál."); } + + return připravVýstup(výsledek, výstupníFormát); + } else { + System.err.println("--- Standardní výstup skriptu: -----"); + System.err.println(výsledek); + System.err.println("--- Cyhbový výstup skriptu: ---------"); + System.err.println(chyby); + System.err.println("--------------------------------------"); + throw new Exception("Návratová hodnota: " + p.exitValue()); } } catch (Exception e) { System.err.println("Došlo k chybě při vykonávání skriptu v jazyce: " + jazyk); System.err.println("--------"); - System.err.println(skript); + System.err.println(skriptText); System.err.println("--------"); e.printStackTrace(System.err); return null; @@ -143,6 +169,10 @@ } } + private static boolean isNeprázdný(String s) { + return !(s == null || s.trim().isEmpty()); + } + /** * @param xml fragment XML vygenerovaný skriptem * @return true v případě, že výstup je validním fragmentem XML diff -r ca045963fced -r aa91d1c6d4c1 šablona/makra/skriptování.xsl --- a/šablona/makra/skriptování.xsl Sat Jun 23 23:19:09 2012 +0200 +++ b/šablona/makra/skriptování.xsl Sun Jul 01 14:43:21 2012 +0200 @@ -28,10 +28,11 @@ <!-- Skriptování *********** - Provedeme skript zadaný v těle elementu a jeho výstup vložíme do stránky. + Provedeme skript zadaný v těle elementu nebo v souboru a jeho výstup vložíme do stránky. * - @jazyk programovací jazyk, např. bash, perl, php + @jazyk programovací jazyk, např. bash, perl, php (nepovinné, pokud je vyplněn atribut src) @výstup formát výstupu skriptu: text (výchozí) | xml (musí být validním fragmentem XML) + @src soubor se skriptem/programem (volitelný parametr – buď zadáme skript do těla elementu, nebo nastavíme tento atribut) --> <xsl:template match="m:skript"> @@ -41,6 +42,7 @@ <xsl:when test="$režim = 'povolit'"> <xsl:variable name="výstupSkriptu" select="j:interpretuj( text(), + @src, @jazyk, @výstup, document-uri(/),