-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtg-connect.xql
182 lines (155 loc) · 7.96 KB
/
tg-connect.xql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
xquery version "3.0";
module namespace tgconnect="http://textgrid.info/namespaces/xquery/tgconnect";
import module namespace templates="http://exist-db.org/xquery/templates";
import module namespace tgclient="http://textgrid.info/namespaces/xquery/tgclient" at "tgclient.xqm";
import module namespace req="http://exquery.org/ns/request";
import module namespace tgmenu="http://textgrid.info/namespaces/xquery/tgmenu" at "/db/apps/textgrid-connect/tgmenu.xqm";
declare namespace rest="http://exquery.org/ns/restxq";
declare namespace output="http://www.w3.org/2010/xslt-xquery-serialization";
declare namespace http="http://expath.org/ns/http-client";
declare namespace tgmd="http://textgrid.info/namespaces/metadata/core/2010";
declare variable $tgconnect:websiteDataPath := "/data/website";
declare variable $tgconnect:editionDataPath := "/data/xml";
(:~
: show html.
:)
declare
%rest:GET
%rest:path("/publish/{$project}/")
%output:media-type("text/html")
%output:method("html5")
function tgconnect:page($project as xs:string*) {
let $content := doc("publish-gui.html")
let $config := map {
(: The following function will be called to look up template parameters :)
$templates:CONFIG_PARAM_RESOLVER := function($param as xs:string) as xs:string* {
req:parameter($param)
}
}
let $lookup := function($functionName as xs:string, $arity as xs:int) {
try {
function-lookup(xs:QName($functionName), $arity)
} catch * {
()
}
}
return
templates:apply($content, $lookup, (), $config)
};
(:
: publish data to project
:)
declare
%rest:POST
%rest:path("/publish/{$project}/process/")
%rest:form-param("sid", "{$sid}", "")
%rest:form-param("uri", "{$uri}", "")
%rest:form-param("target", "{$target}", "data")
%rest:form-param("user", "{$user}", "")
%rest:form-param("password", "{$password}", "")
(: %rest:produces("text/plain"):)
function tgconnect:publish( $uri as xs:string,
$sid as xs:string,
$target as xs:string,
$user as xs:string,
$password as xs:string,
$project as xs:string) {
let $config := tgclient:getConfig($project)
let $targetPath :=
if($target eq "website") then
"/sade-projects/" || $project || $tgconnect:websiteDataPath
else
"/sade-projects/" || $project || $tgconnect:editionDataPath
return if (xmldb:login($targetPath, $user, $password )) then
let $tgcrudUrl := tgclient:config-param-value($config, "textgrid.tgcrud")
(: work around strange bug with publish from public repo
where a .0 to much is added.
TODO: research
:)
let $tguri := if(ends-with($uri, ".0.0")) then
substring-before($uri, ".") || ".0"
else
$uri
let $mp := tgclient:getMeta($tguri, $sid, $tgcrudUrl)
let $rdfstoreUrl :=
if ($mp//tgmd:generated/tgmd:availability = "public") then
tgclient:config-param-value($config, "textgrid.public-triplestore")
else
tgclient:config-param-value($config, "textgrid.nonpublic-triplestore")
let $egal := tgconnect:createEntryPoint($tguri, concat($targetPath, "/meta")),
$oks :=
for $pubUri in tgclient:getAggregatedUris($tguri, $rdfstoreUrl)
let $meta := tgclient:getMeta($pubUri, $sid, $tgcrudUrl),
$targetUri := concat(tgclient:remove-prefix($meta//tgmd:textgridUri/text()), ".xml"),
$egal := xmldb:store(concat($targetPath, "/meta"), $targetUri, $meta, "text/xml")
let $egal :=
(:
since the warning metadate is used for different purposes,
we should go back to try/catchif ($meta//tgmd:warning) then ()
else
:)
if ($meta//tgmd:format[not(contains(base-uri(), $uri))]/text() eq "text/xml")
then let $data := try {tgclient:getData($pubUri, $sid, $tgcrudUrl) }
catch * { <error>{concat($err:code, ": ", $err:description)}</error> }
return try { xmldb:store(concat($targetPath, "/data"), $targetUri, $data, "text/xml") }
catch * { concat($err:code, ": ", $err:description) }
else if($meta//tgmd:format/text() eq "text/xml+xslt") then
let $data := tgclient:getData($pubUri, $sid, $tgcrudUrl)
return xmldb:store(concat($targetPath, "/data"), $targetUri, $data, "text/xml")
else if($meta//tgmd:format/text() eq "text/linkeditorlinkedfile") then
let $data := tgclient:getData($pubUri, $sid, $tgcrudUrl)
return xmldb:store(concat($targetPath, "/tile"), $targetUri, $data, "text/xml")
else if($meta//tgmd:format/text() eq "text/tg.inputform+rdf+xml") then
let $data := tgclient:getData($pubUri, $sid, $tgcrudUrl)
return xmldb:store(concat($targetPath, "/rdf"), $targetUri, $data, "text/xml")
else if(starts-with($meta//tgmd:format/text(), "image")) then ' '
else if (contains($meta//tgmd:format[not(contains(base-uri(), $tguri))]/text(), "tg.aggregation")) then
let $data := tgclient:getData($pubUri, $sid, $tgcrudUrl)
return xmldb:store(concat($targetPath, "/agg"), $targetUri, $data, "text/xml")
else
()
return "ok"
return <ok>published: {$uri} to {$targetPath || ' menu: ' || tgconnect:buildmenu($project, $targetPath, tgclient:config-param-value($config, "template")) || ' stats: ' || tgconnect:buildstats($project) || ' reindex: '}; reindex: {xmldb:reindex('/db' || $targetPath)}</ok>
else
<error>error authenticating for {$user} - {$password} on {$targetPath}</error>
(: tgconnect:error401:)
};
(: does not work with restxq-xquery impl :)
(: declare function tgconnect:error401() {
<rest:response>
<http:response status="401" message="wrong user or password">
<http:header name="Content-Language" value="en"/>
<http:header name="Content-Type" value="text/html; charset=utf-8"/>
</http:response>
</rest:response>
};:)
declare function tgconnect:createEntryPoint($uri as xs:string, $path as xs:string) {
let $epUri := concat(tgclient:remove-prefix($uri), ".ep.xml")
return xmldb:store($path, $epUri, <entrypoint>{$uri}</entrypoint>, "text/xml")
};
declare function tgconnect:buildmenu($project as xs:string, $targetPath as xs:string, $template as xs:string) {
let $nav := tgmenu:init($project, $targetPath),
$egal := xmldb:store('/sade-projects/' || $project, '/navigation-tg.xml', $nav, "text/xml"),
$last := transform:transform($nav, doc('/sade-projects/' || $project || '/xslt/tg-menu.xslt'), ()),
$egal := xmldb:store('/sade-projects/' || $project, '/navigation-' || $template || '.xml', $last, "text/xml")
return " menu: ok"
};
declare function tgconnect:buildstats($project as xs:string) {
let $path := '/sade-projects/' || $project
let $coll := collection($path || '/data/xml/data')
let $doc := doc($path || '/stats.xml')
let $date := current-dateTime()
let $words :=
sum(for $doc in $coll
return count(tokenize(string($doc), '\W+')[. != '']))
let $doc :=
<stats>
{$doc/stats/publ}
<publ>
<date>{$date}</date>
<words>{$words}</words>
</publ>
</stats>
let $tmp := xmldb:store($path, 'stats.xml', $doc, 'text/xml')
return ' stats: ok'
};