WiP! XSLT actor
This commit is contained in:
parent
1827c91da0
commit
2c61d144d0
|
@ -8,3 +8,7 @@ FileSystemUsage = <file-system-usage @path string @size int>.
|
|||
Pulse = <pulse @periodSec float @proxy #:any>.
|
||||
|
||||
XmlTranslation = <xml-translation @xml string @pr any>.
|
||||
|
||||
XsltTransform = <xslt-transform @stylesheet string @input string @output string>.
|
||||
XsltItems = [XsltItem ...].
|
||||
XsltItem = string.
|
||||
|
|
|
@ -51,5 +51,9 @@ XmlTranslatorArguments = <xml-translator {
|
|||
dataspace: #:any
|
||||
}>.
|
||||
|
||||
XsltArguments = <xslt {
|
||||
dataspace: #:any
|
||||
}>.
|
||||
|
||||
# Reused from syndicate-protocols/transportAddress
|
||||
Tcp = <tcp @host string @port int>.
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{ pkgs ? import <nixpkgs> { } }:
|
||||
|
||||
pkgs.buildNimPackage {
|
||||
name = "dummy";
|
||||
name = "syndicate_utils";
|
||||
propagatedNativeBuildInputs = [ pkgs.pkg-config ];
|
||||
propagatedBuildInputs = [ pkgs.postgresql pkgs.sqlite ];
|
||||
propagatedBuildInputs = [ pkgs.postgresql pkgs.sqlite pkgs.libxml2 pkgs.libxslt ];
|
||||
lockFile = ./lock.json;
|
||||
}
|
||||
|
|
|
@ -3,10 +3,12 @@ import
|
|||
preserves
|
||||
|
||||
type
|
||||
XsltItems* = seq[XsltItem]
|
||||
Pulse* {.preservesRecord: "pulse".} = object
|
||||
`periodSec`*: float
|
||||
`proxy`* {.preservesEmbedded.}: Value
|
||||
|
||||
XsltItem* = string
|
||||
XmlTranslation* {.preservesRecord: "xml-translation".} = object
|
||||
`xml`*: string
|
||||
`pr`*: Value
|
||||
|
@ -15,8 +17,15 @@ type
|
|||
`path`*: string
|
||||
`size`*: BiggestInt
|
||||
|
||||
proc `$`*(x: Pulse | XmlTranslation | FileSystemUsage): string =
|
||||
XsltTransform* {.preservesRecord: "xslt-transform".} = object
|
||||
`stylesheet`*: string
|
||||
`input`*: string
|
||||
`output`*: string
|
||||
|
||||
proc `$`*(x: XsltItems | Pulse | XsltItem | XmlTranslation | FileSystemUsage |
|
||||
XsltTransform): string =
|
||||
`$`(toPreserves(x))
|
||||
|
||||
proc encode*(x: Pulse | XmlTranslation | FileSystemUsage): seq[byte] =
|
||||
proc encode*(x: XsltItems | Pulse | XsltItem | XmlTranslation | FileSystemUsage |
|
||||
XsltTransform): seq[byte] =
|
||||
encode(toPreserves(x))
|
||||
|
|
|
@ -27,6 +27,12 @@ type
|
|||
JsonSocketTranslatorArguments* {.preservesRecord: "json-socket-translator".} = object
|
||||
`field0`*: JsonSocketTranslatorArgumentsField0
|
||||
|
||||
XsltArgumentsField0* {.preservesDictionary.} = object
|
||||
`dataspace`* {.preservesEmbedded.}: EmbeddedRef
|
||||
|
||||
XsltArguments* {.preservesRecord: "xslt".} = object
|
||||
`field0`*: XsltArgumentsField0
|
||||
|
||||
WebhooksArgumentsField0* {.preservesDictionary.} = object
|
||||
`endpoints`*: Table[seq[string], EmbeddedRef]
|
||||
`listen`*: Tcp
|
||||
|
@ -84,6 +90,7 @@ type
|
|||
proc `$`*(x: WebsocketArguments | JsonTranslatorArguments |
|
||||
JsonTranslatorConnected |
|
||||
JsonSocketTranslatorArguments |
|
||||
XsltArguments |
|
||||
WebhooksArguments |
|
||||
FileSystemUsageArguments |
|
||||
SqliteArguments |
|
||||
|
@ -98,6 +105,7 @@ proc `$`*(x: WebsocketArguments | JsonTranslatorArguments |
|
|||
proc encode*(x: WebsocketArguments | JsonTranslatorArguments |
|
||||
JsonTranslatorConnected |
|
||||
JsonSocketTranslatorArguments |
|
||||
XsltArguments |
|
||||
WebhooksArguments |
|
||||
FileSystemUsageArguments |
|
||||
SqliteArguments |
|
||||
|
|
|
@ -17,7 +17,8 @@ import ./syndesizer/[
|
|||
pulses,
|
||||
webhooks,
|
||||
websockets,
|
||||
xml_translator]
|
||||
xml_translator,
|
||||
xslt_actor]
|
||||
|
||||
when withPostgre:
|
||||
import ./syndesizer/postgre_actor
|
||||
|
@ -36,6 +37,7 @@ runActor("syndesizer") do (turn: var Turn; root: Cap):
|
|||
discard spawnWebhookActor(turn, root)
|
||||
discard spawnWebsocketActor(turn, root)
|
||||
discard spawnXmlTranslator(turn, root)
|
||||
discard spawnXsltActor(turn, root)
|
||||
when withPostgre:
|
||||
discard spawnPostgreActor(turn, root)
|
||||
when withSqlite:
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
include_rules
|
||||
: foreach *.nim | $(SYNDICATE_PROTOCOL) ../<schema> |> !nim_check |> | ./<checks>
|
||||
: xslt_actor.nim | $(SYNDICATE_PROTOCOL) ../<schema> |> !nim |> {bin}
|
||||
: foreach {bin} |> !assert_built |> ../../tests/built-%b.pr
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||
# SPDX-License-Identifier: Unlicense
|
||||
|
||||
import preserves, syndicate
|
||||
import ../schema/[assertions, config]
|
||||
|
||||
{.passC: staticExec("pkg-config --cflags libxslt").}
|
||||
{.passL: staticExec("pkg-config --libs libxslt").}
|
||||
|
||||
{.pragma: libxslt, header: "libxslt/xslt.h", importc.}
|
||||
|
||||
type
|
||||
xmlDocPtr {.libxslt.} = distinct pointer
|
||||
xsltStylesheetPtr {.libxslt.} = distinct pointer
|
||||
|
||||
proc xmlParseFile(filename: cstring): xmlDocPtr {.libxslt.}
|
||||
proc xmlFreeDoc(p: xmlDocPtr) {.libxslt.}
|
||||
|
||||
proc xsltParseStylesheetFile(filename: cstring): xsltStylesheetPtr {.libxslt.}
|
||||
|
||||
proc xsltApplyStylesheet(
|
||||
style: xsltStylesheetPtr, doc: xmlDocPtr, params: cstringArray): xmlDocPtr {.libxslt.}
|
||||
|
||||
proc xsltFreeStylesheet(style: xsltStylesheetPtr) {.libxslt.}
|
||||
|
||||
proc xsltSaveResultToString(txt: ptr pointer; len: ptr cint; res: xmlDocPtr; style: xsltStylesheetPtr): cint {.libxslt.}
|
||||
|
||||
proc c_free*(p: pointer) {.importc: "free", header: "<stdlib.h>".}
|
||||
|
||||
proc xsltSaveResultToString(res: xmlDocPtr; style: xsltStylesheetPtr): string =
|
||||
var
|
||||
txt: pointer
|
||||
len: cint
|
||||
if xsltSaveResultToString(addr txt, addr len, res, style) < 0:
|
||||
raise newException(CatchableError, "xsltSaveResultToString failed")
|
||||
if len > 0:
|
||||
result = newString(int len)
|
||||
copyMem(result[0].addr, txt, len)
|
||||
c_free(txt)
|
||||
|
||||
proc initLibXml =
|
||||
discard
|
||||
|
||||
proc spawnXsltActor*(turn: var Turn; root: Cap): Actor {.discardable.} =
|
||||
spawn("xslt", turn) do (turn: var Turn):
|
||||
initLibXml()
|
||||
during(turn, root, ?:XsltArguments) do (ds: Cap):
|
||||
let sheetsPat = ?Observe(pattern: !XsltTransform) ?? {0: grab(), 1: grab()}
|
||||
during(turn, ds, sheetsPat) do (stylesheet: Literal[string], input: Literal[string]):
|
||||
let
|
||||
cur = xsltParseStylesheetFile(stylesheet.value)
|
||||
doc = xmlParseFile(input.value)
|
||||
params = allocCStringArray([])
|
||||
res = xsltApplyStylesheet(cur, doc, params)
|
||||
output = xsltSaveResultToString(res, cur)
|
||||
xmlFreeDoc(res)
|
||||
xmlFreeDoc(doc)
|
||||
deallocCStringArray(params)
|
||||
xsltFreeStylesheet(cur)
|
||||
publish(turn, ds, XsltTransform(
|
||||
stylesheet: stylesheet.value,
|
||||
input: input.value,
|
||||
output: output,
|
||||
))
|
||||
|
||||
when isMainModule:
|
||||
import syndicate/relays
|
||||
runActor("main") do (turn: var Turn; root: Cap):
|
||||
connectStdio(turn, root)
|
||||
spawnXsltActor(turn, root)
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0"?>
|
||||
<persons>
|
||||
<person username="JS1">
|
||||
<name>John</name>
|
||||
<family-name>Smith</family-name>
|
||||
</person>
|
||||
<person username="MI1">
|
||||
<name>Morka</name>
|
||||
<family-name>Ismincius</family-name>
|
||||
</person>
|
||||
</persons>
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" version="1.0">
|
||||
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
|
||||
<xsl:template match="/persons">
|
||||
<html>
|
||||
<head>
|
||||
<title>Testing XML Example</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Persons</h1>
|
||||
<ul>
|
||||
<xsl:apply-templates select="person">
|
||||
<xsl:sort select="family-name"/>
|
||||
</xsl:apply-templates>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
<xsl:template match="person">
|
||||
<li>
|
||||
<xsl:value-of select="family-name"/>
|
||||
<xsl:text>, </xsl:text>
|
||||
<xsl:value-of select="name"/>
|
||||
</li>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
|
@ -0,0 +1,19 @@
|
|||
<require-service <daemon xslt_actor>>
|
||||
? <built xslt_actor ?path ?sum> [
|
||||
<daemon xslt_actor {
|
||||
argv: [$path]
|
||||
protocol: application/syndicate
|
||||
env: { BUILD_SUM: $sum }
|
||||
}>
|
||||
]
|
||||
|
||||
let ?ds = dataspace
|
||||
? <service-object <daemon xslt_actor> ?cap> $cap [
|
||||
<xslt { dataspace: $ds }>
|
||||
]
|
||||
|
||||
$ds [
|
||||
? <xslt-transform "/home/emery/src/syndicate_utils/tests/stylesheet.xslt" "/home/emery/src/syndicate_utils/tests/input.xml" ?outputs> [
|
||||
$log ! <log "-" { xslt-outputs: $outputs }>
|
||||
]
|
||||
]
|
Loading…
Reference in New Issue