Skriptování: první verze
authorFrantišek Kučera <franta-hg@frantovo.cz>
Sat, 23 Jun 2012 18:00:41 +0200
changeset 94 4b3ba32f613c
parent 93 5b55827de220
child 95 eea9c4713045
Skriptování: první verze
vstup/skriptování.xml
šablona/funkce/src/cz/frantovo/xmlWebGenerator/makra/Skriptování.java
šablona/makra/skriptování.xsl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vstup/skriptování.xml	Sat Jun 23 18:00:41 2012 +0200
@@ -0,0 +1,109 @@
+<stránka
+	xmlns="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/strana"
+	xmlns:m="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/makro">
+	<nadpis>Skriptování</nadpis>
+	<perex>Na stránku můžeme vložit výstup skriptů.</perex>
+
+	<text xmlns="http://www.w3.org/1999/xhtml">
+	
+		<p>
+			Na stránkách můžeme používat skripty.
+			Spouští se při generování a jejich standardní výstup se vloží do stránky.
+			Třeba doprostřed ostavce nebo do jiného elementu.
+		</p>
+		<p>
+			Příklad:
+			Tyto stránky byly vygenerované v systému <m:skript jazyk="bash">uname -o</m:skript>.
+		</p>
+		
+		<p>
+			V současnosti jsou podporované tyto jazyky:
+		</p>
+		
+		<pre><m:skript jazyk="perl"><![CDATA[
+use strict;
+
+open(JAVA, "<", "šablona/funkce/src/cz/frantovo/xmlWebGenerator/makra/Skriptování.java") or die $!;
+
+while (<JAVA>) {
+#i.put("bash", "/bin/bash");
+	if (/podporovanýJazyk\.put\("(\w+)",\s*"(.*)"\);/) {
+		print "$1\n";
+	}
+}
+			]]></m:skript></pre>
+
+		<h2>Perl</h2>
+		<p>Jazyky použité nebo citované na této stránce:</p>
+		<pre><m:skript jazyk="perl"><![CDATA[
+use strict;
+
+open(XML, "<", $ENV{"XWG_STRANKA_SOUBOR"});
+my %skripty;
+
+while (<XML>) {
+	if (/m:skript\s+jazyk="(\w+)"/) {
+		$skripty{$1}++;
+	}
+}
+
+for(keys(%skripty)) {
+	print "$skripty{$_}×\t $_\n";
+}
+			]]></m:skript></pre>
+
+			<h2>BASH</h2>
+		<pre><m:skript jazyk="bash"><![CDATA[
+echo -n "Právě je: ";
+date;
+echo -n "Operační systém: ";
+uname -sir;
+echo -n "SHA-1 otisk zdrojáku této stránky: ";
+sha1sum < $XWG_STRANKA_SOUBOR;
+			]]></m:skript></pre>
+
+			<!--
+			<h2>PHP</h2>
+			<pre style="max-height: 200px;"><m:skript jazyk="php"><![CDATA[
+<?php
+phpinfo();
+?>
+			]]></m:skript></pre>
+			-->
+
+			<h2>Proměnné prostředí</h2>
+			<p>
+				Ve skriptech máme dostupné následující proměnné prostředí:
+			</p>
+			
+			<ul>
+				<li><code>XWG_STRANKA_URI</code> – URI aktuálně zpracovávané stránky</li>
+				<li><code>XWG_STRANKA_SOUBOR</code> – absolutní cesta k souboru</li>
+				<li><code>XWG_STRANKA_NADPIS</code> – nadpis stránky</li>
+				<li><code>XWG_STRANKA_PEREX</code> – perex stránky</li>
+			</ul>
+			
+			<p>
+				Kód:
+			</p>
+			
+			<m:pre jazyk="xml"><![CDATA[<m:skript jazyk="bash">
+echo "URI:    $XWG_STRANKA_URI";
+echo "Soubor: $XWG_STRANKA_SOUBOR";
+echo "Nadpis: $XWG_STRANKA_NADPIS";
+echo "Perex:  $XWG_STRANKA_PEREX";
+</m:skript>]]></m:pre>
+			
+			<p>nám vypíše:</p>
+			
+			<pre><m:skript jazyk="bash"><![CDATA[
+echo "URI:    $XWG_STRANKA_URI" | sed s/\\/home\\/$USER/\\/home\\/xwg/g;
+echo "Soubor: $XWG_STRANKA_SOUBOR" | sed s/\\/home\\/$USER/\\/home\\/xwg/g;
+echo "Nadpis: $XWG_STRANKA_NADPIS";
+echo "Perex:  $XWG_STRANKA_PEREX";
+		]]></m:skript></pre>
+
+	</text>
+
+</stránka>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/šablona/funkce/src/cz/frantovo/xmlWebGenerator/makra/Skriptování.java	Sat Jun 23 18:00:41 2012 +0200
@@ -0,0 +1,131 @@
+/**
+ * XML Web generátor – program na generování webových stránek
+ * Copyright © 2012 František Kučera (frantovo.cz)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package cz.frantovo.xmlWebGenerator.makra;
+
+import static cz.frantovo.xmlWebGenerator.NástrojeCLI.načtiProud;
+import java.io.File;
+import java.io.PrintStream;
+import java.net.URI;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Provedeme skript a do stránky vložíme jeho výstup.
+ *
+ * @author František Kučera (frantovo.cz)
+ */
+public class Skriptování {
+
+	/**
+	 * klíč = jazyk – např. bash
+	 * hodnota = interpret – např. /bin/bash
+	 */
+	private static final Map<String, String> interpreti;
+
+	static {
+		Map<String, String> podporovanýJazyk = new HashMap<String, String>();
+		podporovanýJazyk.put("bash", "/bin/bash");
+		podporovanýJazyk.put("perl", "/usr/bin/perl");
+		podporovanýJazyk.put("php", "/usr/bin/php");
+		podporovanýJazyk.put("python", "/usr/bin/python");
+		interpreti = Collections.unmodifiableMap(podporovanýJazyk);
+	}
+
+	/**
+	 * 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 jazyk programovací jazyk
+	 * @param uriStránky URI aktuálně generované stránky → proměnná prostředí
+	 * @param nadpisStránky nadpis stránky → proměnná prostředí
+	 * @param perexStránky perex stránky → proměnná prostředí
+	 * @return výstup příkazu
+	 */
+	public static String interpretuj(String skript, String jazyk, 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;
+			} else {
+				File f = File.createTempFile("xml-web-generátor-", ".skript");
+				f.deleteOnExit();
+
+				PrintStream ps = new PrintStream(f);
+				ps.print("#!");
+				ps.println(interpret);
+				ps.println();
+				ps.print(skript);
+				ps.close();
+
+				f.setExecutable(true);
+
+				String[] prostředí = new String[]{
+					"LANG=" + System.getenv("LANG"),
+					"USER=" + System.getenv("USER"),
+					"XWG_STRANKA_URI=" + uriStránky,
+					"XWG_STRANKA_SOUBOR=" + (new File(new URI(uriStránky)).getAbsolutePath()),
+					"XWG_STRANKA_NADPIS=" + nadpisStránky,
+					"XWG_STRANKA_PEREX=" + perexStránky
+				};
+
+
+
+				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());
+
+				p.waitFor();
+
+				/**
+				 * TODO: podporovat zvláštní návratový kód, kterým skript řekne,
+				 * že výstupem je XML a má se vložit jako fragment do dokumentu,
+				 * ne jako prostý text.
+				 */
+				if (p.exitValue() == 0) {
+					if (chyby.length() > 0) {
+						System.err.println("--- Cyhbový výstup skriptu -----");
+						System.err.println(chyby);
+						System.err.println("--------------------------------");
+					}
+
+					return výsledek.trim();
+				} 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 RuntimeException("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("--------");
+			e.printStackTrace(System.err);
+			return null;
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/šablona/makra/skriptování.xsl	Sat Jun 23 18:00:41 2012 +0200
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+XML Web generátor – program na generování webových stránek
+Copyright © 2012 František Kučera (frantovo.cz)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
+<xsl:stylesheet version="2.0"
+	xmlns="http://www.w3.org/1999/xhtml"
+	xmlns:m="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/makro"
+	xmlns:j="java:cz.frantovo.xmlWebGenerator.makra.Skriptování"
+	xmlns:s="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/strana"
+	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+	exclude-result-prefixes="m j s">
+
+	<!--
+		Skriptování
+		***********
+		Provedeme skript zadaný v těle elementu a jeho výstup vložíme do stránky.
+		*
+		@jazyk programovací jazyk, např. bash, perl, php
+		@src skript uložený v souboru místo v těle elementu
+	-->
+	<xsl:template match="m:skript">
+		<!--
+		TODO:
+			- ošetření chyb
+			- nastavení z web.conf (zákaz nebo ignorace skriptů)
+			- podpora vkládání fragmentů XML, ne jen prostého textu
+		-->
+		<xsl:value-of select="j:interpretuj(text(), @jazyk, document-uri(/), //s:stránka/s:nadpis/text(), //s:stránka/s:perex/text())"/>
+	</xsl:template>
+
+</xsl:stylesheet>
+