itsb/xslt/feedgen.xsl

233 lines
6.7 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:itsb="http://tilde.town/~lucidiot/itsb/">
<xsl:output method="text" />
<xsl:variable name="apos">'</xsl:variable>
<xsl:variable name="escapedApos">'"'"'</xsl:variable>
<!--
Recursive template that allows single quote escaping in strings
Usage:
<xsl:call-template name="escape">
<xsl:with-param name="text" select="." />
</xsl:call-template>
-->
<xsl:template name="escape">
<xsl:param name="text" />
<xsl:choose>
<xsl:when test="contains($text, $apos)">
<xsl:call-template name="escape">
<xsl:with-param name="text" select="concat(
substring-before($text, $apos),
$escapedApos,
substring-after($text, $apos))"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="/">
<xsl:text><![CDATA[#!/bin/bash
function usage {
echo "Usage: $0 [-d BASE_DIR] [-q]"
echo " -d, --base-dir Set the base directory for the feed generator files and output."
echo " -q, --quiet Hide status logs - useful when running the script as a cronjob."
exit 1
}
while [[ "$#" > 0 ]]; do case $1 in
-d|--base-dir) DIR="$2"; shift;;
-q|--quiet) QUIET=yes;;
*) echo "Unknown parameter: $1"; usage;;
esac; shift; done
function log {
test -z "$QUIET" && echo "$@"
}
[ -z "$DIR" ] && DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
log Building to $DIR/feeds
mkdir -p $DIR/feeds
if ! command -v json2xml >/dev/null 2>&1; then
log "Adding $DIR/bin to PATH"
PATH="$DIR/bin:$PATH"
fi
]]></xsl:text>
<xsl:apply-templates select="//itsb:feed[not(itsb:link)]" />
</xsl:template>
<xsl:template match="itsb:feed[not(itsb:link)]">
<xsl:text>log Building </xsl:text>
<xsl:value-of select="./@id" />
<xsl:text> feed to $DIR/feeds/</xsl:text>
<xsl:value-of select="./itsb:output/text()" />
<xsl:text>
</xsl:text>
<xsl:if test="contains(./itsb:output/text(), '/')">
<xsl:text>mkdir -p $DIR/feeds/</xsl:text>
<xsl:value-of select="substring-before(./itsb:output/text(), '/')" />
<xsl:text>
</xsl:text>
</xsl:if>
<xsl:for-each select="./itsb:curl|./itsb:jq|./itsb:pup|./itsb:json2xml|./itsb:xml2json|./itsb:shell|./itsb:output">
<xsl:apply-templates select="." />
<xsl:if test="not(position()=last())">
<xsl:text> \
</xsl:text>
<!-- Only include a pipe if the element strictly afterwards is not the output -->
<xsl:if test="not(name(./following-sibling::*[1]) = 'output')">
<xsl:text>| </xsl:text>
</xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="itsb:curl">
<xsl:text>curl --fail -s </xsl:text>
<xsl:if test="itsb:url/@verify-ssl = 'false' or itsb:url/@verify-ssl = '0'">
<xsl:text>-k </xsl:text>
</xsl:if>
<xsl:for-each select="./itsb:url|./itsb:header|./itsb:requestBody">
<xsl:apply-templates select="." />
<xsl:if test="not(position()=last())">
<xsl:text> \
</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="itsb:url">
<xsl:text>'</xsl:text>
<xsl:call-template name="escape">
<xsl:with-param name="text" select="text()" />
</xsl:call-template>
<xsl:text>'</xsl:text>
</xsl:template>
<xsl:template match="itsb:header">
<xsl:text>-H '</xsl:text>
<xsl:call-template name="escape">
<xsl:with-param name="text" select="@name" />
</xsl:call-template>
<xsl:text>: </xsl:text>
<xsl:call-template name="escape">
<xsl:with-param name="text" select="text()" />
</xsl:call-template>
<xsl:text>'</xsl:text>
</xsl:template>
<xsl:template match="itsb:requestBody">
<xsl:text>-d '</xsl:text>
<xsl:call-template name="escape">
<xsl:with-param name="text" select="text()" />
</xsl:call-template>
<xsl:text>'</xsl:text>
</xsl:template>
<xsl:template match="itsb:jq">
<xsl:text>jq \
-L $DIR/jq \
-f $DIR/jq/</xsl:text>
<xsl:value-of select="@path" />
<xsl:for-each select="./itsb:arg">
<xsl:text> \
</xsl:text>
<xsl:apply-templates select="." />
</xsl:for-each>
</xsl:template>
<xsl:template match="itsb:arg">
<xsl:text>--arg '</xsl:text>
<xsl:call-template name="escape">
<xsl:with-param name="text" select="@name" />
</xsl:call-template>
<xsl:text>' '</xsl:text>
<xsl:call-template name="escape">
<xsl:with-param name="text" select="text()" />
</xsl:call-template>
<xsl:text>'</xsl:text>
</xsl:template>
<xsl:template match="itsb:pup">
<xsl:text>pup '</xsl:text>
<xsl:call-template name="escape">
<xsl:with-param name="text" select="text()" />
</xsl:call-template>
<xsl:text> </xsl:text>
<!-- Handles default value for output attribute -->
<xsl:choose>
<xsl:when test="@output">
<xsl:value-of select="@output" />
</xsl:when>
<xsl:otherwise>
<xsl:text>json</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:text>{}'</xsl:text>
</xsl:template>
<xsl:template match="itsb:xml2json">
<xsl:text>xml2json</xsl:text>
</xsl:template>
<xsl:template match="itsb:json2xml">
<xsl:text>json2xml</xsl:text>
<xsl:if test="@short-empty = 'true' or @short-empty = '1'">
<xsl:text> -s</xsl:text>
</xsl:if>
<xsl:for-each select="./itsb:namespace">
<xsl:text> \
</xsl:text>
<xsl:apply-templates select="." />
</xsl:for-each>
</xsl:template>
<xsl:template match="itsb:namespace">
<xsl:text>-ns '</xsl:text>
<xsl:call-template name="escape">
<xsl:with-param name="text" select="text()" />
</xsl:call-template>
<xsl:text>' '</xsl:text>
<xsl:call-template name="escape">
<xsl:with-param name="text" select="@prefix" />
</xsl:call-template>
<xsl:text>'</xsl:text>
</xsl:template>
<xsl:template match="itsb:shell">
<!-- good luck! -->
<xsl:value-of select="text()" />
</xsl:template>
<xsl:template match="itsb:output">
<xsl:text>> $DIR/feeds/</xsl:text>
<xsl:value-of select="text()" />
<xsl:text>.new \
&amp;&amp; mv $DIR/feeds/</xsl:text>
<xsl:value-of select="text()" />
<xsl:text>.new $DIR/feeds/</xsl:text>
<xsl:value-of select="text()" />
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="*">
<xsl:message terminate="yes">
<xsl:text>Unmatched element</xsl:text>
<xsl:value-of select="name()" />
</xsl:message>
</xsl:template>
</xsl:stylesheet>