Commit d3aaadc0 authored by mmarkus1's avatar mmarkus1
Browse files

Merge branch 'imprint-templating' into 'develop'

Imprint and Privacy Importing from Confluence Wiki

See merge request !93
parents fa77b3db f510493d
...@@ -5,19 +5,20 @@ xquery version "3.1"; ...@@ -5,19 +5,20 @@ xquery version "3.1";
: @author Johannes Biermann : @author Johannes Biermann
: @author Mathias Göbel : @author Mathias Göbel
: @author Stefan Hynek : @author Stefan Hynek
: @version 0.2 : @version 0.3
:) :)
module namespace confluence="https://sade.textgrid.de/ns/wiki-confluence"; module namespace confluence="https://sade.textgrid.de/ns/wiki-confluence";
import module namespace config="https://sade.textgrid.de/ns/config" at "../config.xqm"; import module namespace config="https://sade.textgrid.de/ns/config" at "../config.xqm";
import module namespace app="https://sade.textgrid.de/ns/app" at "../app.xqm"; import module namespace app="https://sade.textgrid.de/ns/app" at "../app.xqm";
import module namespace functx="http://www.functx.com";
import module namespace console="http://exist-db.org/xquery/console";
declare namespace cf="https://sade.textgrid.de/ns/configfile"; declare namespace cf="https://sade.textgrid.de/ns/configfile";
declare namespace http="http://expath.org/ns/http-client"; declare namespace http="http://expath.org/ns/http-client";
declare namespace xhtml="http://www.w3.org/1999/xhtml"; declare namespace xhtml="http://www.w3.org/1999/xhtml";
declare variable $confluence:collection := $config:app-root || '/docs'; declare variable $confluence:collection := $config:app-root || '/docs';
declare variable $confluence:httprequestget := "<http:request method='get' />";
declare function confluence:confluence($node as node(), $model as map(*), $id as xs:string) as node()* { declare function confluence:confluence($node as node(), $model as map(*), $id as xs:string) as node()* {
...@@ -26,6 +27,9 @@ let $lastRevinDb := confluence:getLastRevInDb($id) ...@@ -26,6 +27,9 @@ let $lastRevinDb := confluence:getLastRevInDb($id)
let $revisionInWiki := confluence:getLastRevInWiki($id) let $revisionInWiki := confluence:getLastRevInWiki($id)
let $revisionInWiki := if ($revisionInWiki=-1) then ($lastRevinDb) else ($revisionInWiki) let $revisionInWiki := if ($revisionInWiki=-1) then ($lastRevinDb) else ($revisionInWiki)
(: Only for debugging, needs to be commented out for productive state :)
(:let $lastRevinDb := 0:)
let $config-lang := string(config:get("lang.default", "multilanguage")), let $config-lang := string(config:get("lang.default", "multilanguage")),
$lang := if($config-lang = "") then "" else app:getLanguage() $lang := if($config-lang = "") then "" else app:getLanguage()
...@@ -71,145 +75,134 @@ if( $revisionInWiki = $lastRevinDb ) ...@@ -71,145 +75,134 @@ if( $revisionInWiki = $lastRevinDb )
: @param $nodes – confluence node(s) : @param $nodes – confluence node(s)
: @param $lang – the target language : @param $lang – the target language
: :) : :)
declare function local:confluenceparseLanguage($nodes as node()*, $lang) declare function local:confluenceparseLanguage($nodes as node()*, $lang){
{
for $node in $nodes return for $node in $nodes return
typeswitch($node) typeswitch($node)
case element ( structured-macro ) return case element ( structured-macro ) return
if( string($node/@name) = (config:get("confluence.lang", "wiki")[@code=$lang]/string(@name))) if( string($node/@name) = (config:get("confluence.lang", "wiki")[@code=$lang]/string(@name)))
then then
element xhtml:div { element xhtml:div {
local:confluenceparseLanguage($node/rich-text-body/node(), $lang) local:confluenceparseLanguage($node/rich-text-body/node(), $lang)
} }
else () else ()
(: error( QName("https://sade.textgrid.de/ns/wiki", "CONF02"), "Language ("|| $lang ||") not supported. Request was: "||$node/@name):) (: error( QName("https://sade.textgrid.de/ns/wiki", "CONF02"), "Language ("|| $lang ||") not supported. Request was: "||$node/@name):)
case element( * ) return case element( * ) return
element {local-name($node)} { element {local-name($node)} {
$node/@*, $node/@*,
local:confluenceparseLanguage($node/node(), $lang) local:confluenceparseLanguage($node/node(), $lang)
} }
case text() return $node case text() return $node
default return local:confluenceparseLanguage($node/node(), $lang) default return local:confluenceparseLanguage($node/node(), $lang)
}; };
declare function local:confluenceparser($nodes as node()*, $id) declare function local:confluenceparser($nodes as node()*, $id){
{ for $node in $nodes return
for $node in $nodes return typeswitch($node)
typeswitch($node)
(:Confluence often returns an empty p element at the beginning:) (:Confluence often returns an empty p element at the beginning:)
case element (p) return case element (p) return
switch ($node/@class) switch ($node/@class)
case "auto-cursor-target" case "auto-cursor-target"
return () return ()
default default
return return
element {local-name($node)} {
$node/@*,
local:confluenceparser($node/node(), $id)
}
(:
case element (p) return
element xhtml:p {
attribute class {"lead"},
for $att in $node/@*
let $att-name := name($att)
return if ($att-name != "class") then attribute {$att-name} {$att}
else (),
local:confluenceparser($node/node(), $id)
}:)
case element ( image ) return
element xhtml:img {
attribute src { "https://wiki.de.dariah.eu/download/attachments/" || $id || "/" || ($node/attachment/@filename) },
attribute alt { ($node/@title) },
attribute height { ($node/@height) }
(: attribute width { ($node/@width) } ---->: Width can't be set in Confluence! :)
}
(:Transform heading h1 to the theme specific style:)
case element ( h1 ) return
element xhtml:h1 {
attribute class {"block-header"},
<span>{ $node/text() }</span>
}
case element ( h2 ) return
element xhtml:h2 {
attribute class {"block-header alt"},
<span>{ $node/text() }</span>
}
(: Structured Macros of Confluence needs to be transformed :)
case element ( structured-macro ) return
if(matches($node/@name, "^[a-zA-Z]"))
then (
switch ($node/@name)
case "info"
return
element xhtml:div {
attribute class {"info-board info-board-primary"},
local:confluenceparser($node/rich-text-body/node(), $id)
}
case "warning"
return
element xhtml:div {
attribute class {"alert alert-danger"},
local:confluenceparser($node/rich-text-body/node(), $id)
}
case "tip"
return
element xhtml:div {
attribute class {"alert alert-success"},
local:confluenceparser($node/rich-text-body/node(), $id)
}
case "code"
return
element xhtml:pre {
element xhtml:code {
local:confluenceparser($node/plain-text-body/node(), $id)
}
}
case "pagetitle"
return
(util:log-system-out($node),
element xhtml:h2 {
attribute class {"block-header"},
element xhtml:span {
attribute class {"title"}
}
})
default
return
element xhtml:span {
attribute class {"unprocessed-structured-macro"}
}
)
else error( QName("https://sade.textgrid.de/ns/wiki", "CONF01"), "Structured Macro has no valid name.")
case element ( table ) return
element table {
if($node/@class) then
attribute class {$node/@class || " table table-responsive"}
else
attribute class {"table table-responsive"},
$node/(@* except @class),
local:confluenceparser($node/node(), $id)
}
(: Edit links to open external ones in a new tab :)
case element ( a ) return
element a {
if (starts-with($node/@href,"/")) then (
attribute href {$node/@href},
$node/text())
else (
(:attribute href {$node/@href},:)
attribute target {"_blank"},
$node/@*,
local:confluenceparser($node/node(), $id))
}
case element( * ) return
element {local-name($node)} { element {local-name($node)} {
attribute test { $node/parent::*/child::*[1] = $node },
$node/@*, $node/@*,
local:confluenceparser($node/node(), $id) local:confluenceparser($node/node(), $id)
} }
case text() return $node (:
default return local:confluenceparser($node/node(), $id) case element (p) return
element xhtml:p {
attribute class {"lead"},
for $att in $node/@*
let $att-name := name($att)
return if ($att-name != "class") then attribute {$att-name} {$att}
else (),
local:confluenceparser($node/node(), $id)
}:)
case element ( image ) return
element xhtml:img {
attribute src { "https://wiki.de.dariah.eu/download/attachments/" || $id || "/" || ($node/attachment/@filename) },
attribute alt { ($node/@title) },
attribute height { ($node/@height) }
(: attribute width { ($node/@width) } ---->: Width can't be set in Confluence! :)
}
(:Transform heading h1 to the theme specific style:)
case element ( h1 ) return
element xhtml:h1 {
attribute class {"block-header"},
local:confluenceparser($node/node(), $id)
}
case element ( h2 ) return
element xhtml:h2 {
attribute class {"block-header alt"},
local:confluenceparser($node/node(), $id)
}
(: Structured Macros of Confluence needs to be transformed :)
case element ( structured-macro ) return
if(matches($node/@name, "^[a-zA-Z]"))
then (
switch ($node/@name)
case "info"
return
element xhtml:div {
attribute class {"info-board info-board-primary"},
local:confluenceparser($node/rich-text-body/node(), $id)
}
case "warning"
return
element xhtml:div {
attribute class {"alert alert-danger"},
local:confluenceparser($node/rich-text-body/node(), $id)
}
case "tip"
return
element xhtml:div {
attribute class {"alert alert-success"},
local:confluenceparser($node/rich-text-body/node(), $id)
}
case "code"
return
element xhtml:code {
local:confluenceparser($node/plain-text-body/node(), $id)
}
default
return
if( string($node/@name) = (config:get("confluence.lang", "wiki")/string(@name))[.!=""])
then
element {local-name($node)} {
$node/@*,
local:confluenceparser($node/node(), $id)
}
else error( QName("https://sade.textgrid.de/ns/wiki", "CONF03"), "Structured macro ("|| string($node/@name) ||") unknown to the parser.")
)
else error( QName("https://sade.textgrid.de/ns/wiki", "CONF01"), "Structured Macro has no valid name.")
case element ( table ) return
element table {
attribute class {"table table-responsive"},
$node/(@* except @class),
local:confluenceparser($node/node(), $id)
}
(: Edit links to open external ones in a new tab :)
case element ( a ) return
element a {
if (starts-with($node/@href,"https://wiki.de.dariah.eu/")) then (
attribute href {functx:substring-after-if-contains($node/@href,"https://wiki.de.dariah.eu/")},
$node/text())
else (
(:attribute href {$node/@href},:)
attribute target {"_blank"},
$node/@*,
local:confluenceparser($node/node(), $id))
}
case element( * ) return
element {local-name($node)} {
$node/@*,
local:confluenceparser($node/node(), $id)
}
case text() return $node
default return local:confluenceparser($node/node(), $id)
}; };
declare function local:passthru($node as node()*, $id) as item()* { declare function local:passthru($node as node()*, $id) as item()* {
...@@ -219,62 +212,58 @@ declare function local:passthru($node as node()*, $id) as item()* { ...@@ -219,62 +212,58 @@ declare function local:passthru($node as node()*, $id) as item()* {
(: not needed anymore, but could be handy for further usage :) (: not needed anymore, but could be handy for further usage :)
(: httpclient-syntax deprecated (: httpclient-syntax deprecated
declare function local:retrieveImageUrl($pageId, $imageName) { declare function local:retrieveImageUrl($pageId, $imageName) {
let $url:= xs:anyURI('https://wiki.de.dariah.eu/rest/api/content/' || $pageId || '/child/attachment?filename=' || encode-for-uri($imageName)) let $url:= xs:anyURI('https://wiki.de.dariah.eu/rest/api/content/' || $pageId || '/child/attachment?filename=' || encode-for-uri($imageName)),
let $persist := false() $persist := false(),
let $request-headers:= <headers></headers> $request-headers:= <headers></headers>,
let $export := httpclient:get(xs:anyURI($url), false(), $request-headers) $export := httpclient:get(xs:anyURI($url), false(), $request-headers),
let $map := parse-json( $map := parse-json ( util:base64-decode(
util:base64-decode( string(xs:base64Binary($export//httpclient:body/text())) ) ),
string(xs:base64Binary($export//httpclient:body/text())))) $imageurl := $map("results")(1)("_links")("download")
let $imageurl := $map("results")(1)("_links")("download") return 'https://wiki.de.dariah.eu/' || $imageurl
return 'https://wiki.de.dariah.eu/' || $imageurl
}; };
:) :)
declare function confluence:getLastRevInDb($id) as xs:integer declare function confluence:getLastRevInDb($id) as xs:integer {
{ let $num := xmldb:get-child-resources( $confluence:collection )[contains(., $id)][1]
let $num := xmldb:get-child-resources( $confluence:collection )[contains(., $id)][1] => substring-after('.rev')
=> substring-after('.rev') => substring-before('.xml')
=> substring-before('.xml')
return return
if($num = "") if($num = "")
then 0 then 0
else $num else $num
}; };
(:~ (:~
: Returns the last revision number we get from Confluence : Returns the last revision number we get from Confluence
: @param $id – the ID of a Confluence page : @param $id – the ID of a Confluence page
: :) : :)
declare function confluence:getLastRevInWiki($id as xs:string) as xs:integer { declare function confluence:getLastRevInWiki($id as xs:string) as xs:integer {
let $url := config:get("confluence.url", "wiki")||$id||"/history?expand=lastUpdated" let $url := config:get("confluence.url", "wiki")||$id||"/history?expand=lastUpdated"
let $httprequestget := <http:request href="{ $url }" method="get" /> let $httprequestget := <http:request href="{ $url }" method="get" />
let $rest := http:send-request($httprequestget) let $rest := http:send-request($httprequestget)
let $statuscode := $rest[1]/@status let $statuscode := $rest[1]/@status
let $map := if ($statuscode = 200) then (
parse-json(util:base64-decode($rest[2]))
)
else ()
let $revision := if ($statuscode = 200) then ( let $map := if ($statuscode = 200) then (
string(map:get (map:get($map, "lastUpdated"), "number")) parse-json(util:base64-decode($rest[2]))
) )
else (-1) else ()
return
$revision
};
declare function local:HTML2html($node) let $revision := if ($statuscode = 200) then (
{ string(map:get (map:get($map, "lastUpdated"), "number"))
for $node in $node )
else (-1)
return return
typeswitch ( $node ) $revision
case element() return element { lower-case($node/local-name()) } { $node/@*, local:HTML2html($node/node()) } };
default return $node
declare function local:HTML2html($node) {
for $node in $node
return
typeswitch ( $node )
case element() return element { lower-case($node/local-name()) } { $node/@*, local:HTML2html($node/node()) }
default return $node
}; };
declare function local:remove-element-ns-deep( $nodes as node()*) as node()* { declare function local:remove-element-ns-deep( $nodes as node()*) as node()* {
...@@ -339,11 +328,26 @@ declare function local:replaceParsingErrors($result) { ...@@ -339,11 +328,26 @@ declare function local:replaceParsingErrors($result) {
$temp := replace($temp, "&amp;aelig;","æ"), $temp := replace($temp, "&amp;aelig;","æ"),
$temp := replace($temp, "&amp;Ccedil;","Ç"), $temp := replace($temp, "&amp;Ccedil;","Ç"),
$temp := replace($temp, "&amp;ccedil;","ç"), $temp := replace($temp, "&amp;ccedil;","ç"),
$temp := replace($temp, "&amp;Oacute;","Ó"),
$temp := replace($temp, "&amp;oacute;","ó"),
$temp := replace($temp, "&amp;aacute;","á"),
$temp := replace($temp, "&amp;Aacute;","Á"),
$temp := replace($temp, "&amp;Eacute;","É"),
$temp := replace($temp, "&amp;eacute;","é"),
$temp := replace($temp, "&amp;Uacute;","Ú"),
$temp := replace($temp, "&amp;uacute;","ú"),
$temp := replace($temp, "&amp;Iacute;","Í"),
$temp := replace($temp, "&amp;iacute;","í"),
$temp := replace($temp, "&amp;aring;","å"),
$temp := replace($temp, "&amp;Aring;","Å"),
(:Other special characters:) (:Other special characters:)
$temp := replace($temp, "&amp;deg;","°"),
$temp := replace($temp, "&amp;rsaquo;","›"),
$temp := replace($temp, "&amp;lsaquo;","‹"),
$temp := replace($temp, "&amp;rsquo;","’"), $temp := replace($temp, "&amp;rsquo;","’"),
$temp := replace($temp, "&amp;lsquo;","‘"), $temp := replace($temp, "&amp;lsquo;","‘"),
$temp := replace($temp, "&amp;ndash;","-"), $temp := replace($temp, "&amp;ndash;",""),
$temp := replace($temp, "&amp;mdash;","—"), $temp := replace($temp, "&amp;mdash;","—"),
$temp := replace($temp, "&amp;laquo;","«"), $temp := replace($temp, "&amp;laquo;","«"),
$temp := replace($temp, "&amp;raquo;","»"), $temp := replace($temp, "&amp;raquo;","»"),
...@@ -351,7 +355,22 @@ declare function local:replaceParsingErrors($result) { ...@@ -351,7 +355,22 @@ declare function local:replaceParsingErrors($result) {
$temp := replace($temp, "&amp;rdquo;","”"), $temp := replace($temp, "&amp;rdquo;","”"),
$temp := replace($temp, "&amp;bdquo;","„"), $temp := replace($temp, "&amp;bdquo;","„"),
$temp := replace($temp, "&amp;hellip;","..."), $temp := replace($temp, "&amp;hellip;","..."),
$temp := replace($temp, "&amp;sect;","§") $temp := replace($temp, "&amp;times;","x"),
$temp := replace($temp, "&amp;sect;","§"),
$temp := replace($temp, "&amp;acute;","´"),
$temp := replace($temp, "&amp;sbquo;","‚"),
$temp := replace($temp, "&amp;dagger;","†"),
$temp := replace($temp, "&amp;euro;","€"),
$temp := replace($temp, "&amp;shy;","–")
return $temp return $temp
}; };
declare function functx:substring-after-if-contains
( $arg as xs:string? ,
$delim as xs:string ) as xs:string? {
if (contains($arg,$delim))
then substring-after($arg,$delim)
else $arg
};
<div data-template="templates:surround" data-template-with="templates/page_index.html" data-template-at="content-container">
<div class="container">
<div data-template="confluence:confluence" data-template-id="128652700" />
</div>
</div>
...@@ -87,10 +87,10 @@ ...@@ -87,10 +87,10 @@
<br/> 37073 Göttingen, Germany <br/> anfragen@textgrid.de <br/> 37073 Göttingen, Germany <br/> anfragen@textgrid.de
</p> </p>
<div> <div>
<a href="https://de.dariah.eu/en_US/impressum" target="_blank">Imprint</a> <a href="imprint.html" target="_blank">Imprint</a>
</div> </div>
<div> <div>
<a href="https://de.dariah.eu/en_US/privacy-policy" target="_blank">Privacy Policy</a> <a href="privacy.html" target="_blank">Privacy Policy</a>
</div> </div>
</div> </div>
</div> </div>
......
<div data-template="templates:surround" data-template-with="templates/page_index.html" data-template-at="content-container">
<div class="container">
<div data-template="confluence:confluence" data-template-id="136217359" />
</div>
</div>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment