2022 lines
94 KiB
Plaintext
2022 lines
94 KiB
Plaintext
(:~
|
|
: Job Library.
|
|
:
|
|
: @author Rave Technologies, https://www.rave-tech.com/, 2017
|
|
:)
|
|
|
|
module namespace JOBS = 'http://www.rave-tech.com/bloomsbury/jobs';
|
|
import module namespace config = 'http://www.rave-tech.com/bloomsbury/config' at './module/config.xqm';
|
|
import module namespace contents = 'http://www.rave-tech.com/bloomsbury/contents' at 'content.xqm';
|
|
import module namespace report = 'http://www.rave-tech.com/bloomsbury/report' at 'report.xqm';
|
|
import module namespace blcommon = 'http://www.rave-tech.com/bloomsbury/common' at 'common.xqm';
|
|
import module namespace audit = 'http://www.rave-tech.com/bloomsbury/audit' at './module/manage-audit.xqm';
|
|
declare namespace product = 'http://cms.bloomsbury.com/product-manifest';
|
|
declare namespace pipeline = 'http://cms.bloomsbury.com/pipeline';
|
|
(:~
|
|
: Add Job into the system.
|
|
: Ingest job
|
|
:----------------------------------
|
|
: @param $body Parameters to ingest content into the system <job><ingest><area>Professional</area><ctype>looseleaf</ctype><ignore-validation>true</ignore-validation><mail>true</mail><path>D:\Backup\Projects\bloomsbury\SharedData\Steve\word2xml\small66.zip</path></ingest></job>
|
|
: <job><publish><product>vat-construction-land-property</product><ignore-validation>true</ignore-validation><mail>true</mail></publish></job>
|
|
: @header $authorization Authorization key
|
|
: @return element(result)
|
|
:
|
|
: Checkin job
|
|
:----------------------------------
|
|
: @param $body Parameters to lock content into the system <job><checkin><role>Admin</role><uri></uri><uri></uri><upload-path></upload-path><ignore-validation>true</ignore-validation><mail>true</mail><comment></comment></checkin></job>
|
|
: <role> = Role of the user. Admin user can check-in another user check out files.
|
|
: <uri> = The uri of the files which has been selected to check-in (db uri), separated by '|', no space should present while joining by '|'
|
|
: <upload-path> = Selected content to upload (zip,word,xml)
|
|
: <ignore-validation> = program will ignore validation or not
|
|
: <mail> = mail indicator to send mail after check-in
|
|
: <comment> = check-in comment of the user
|
|
:
|
|
: Publish job
|
|
:----------------------------------
|
|
: @param $body Parameters to lock content into the system <job><publish>id of the product</publish></job>
|
|
|
|
:)
|
|
declare
|
|
%updating
|
|
%rest:path("/jobs")
|
|
%rest:POST("{$body}")
|
|
%rest:header-param("Authorization", "{$authorization}", "none")
|
|
%rest:consumes("application/xml", "text/xml")
|
|
function JOBS:create(
|
|
$body as document-node(),
|
|
$authorization as xs:string
|
|
)
|
|
{
|
|
config:session-check($authorization),
|
|
try{
|
|
if(file:exists(fn:replace($body/job/*/path/text(),'\\','/')))
|
|
then
|
|
(: Ingest Job :)
|
|
if($body/job/ingest/type='bulk' and $body/job/ingest)
|
|
then
|
|
(:let $contentPath := fn:replace($body/job/ingest/path/text(),'\\','/')
|
|
let $archive := file:read-binary($contentPath)
|
|
for $entry in archive:entries($archive)[fn:ends-with(., '.xml')]
|
|
let $rootNode := fn:name(fn:parse-xml(archive:extract-text($archive, $entry))/*)
|
|
(:let $files := fn:parse-xml(archive:extract-text($archive, $entry))/*/@xml:id/string():)
|
|
let $files := fn:parse-xml(archive:extract-text($archive, $entry))/*/@xml:id/string()[$rootNode='TEI']
|
|
return:)
|
|
JOBS:ingest-job($body,$authorization)
|
|
|
|
else
|
|
if($body/job/ingest and not($body/type))
|
|
then JOBS:ingest-job($body,$authorization)
|
|
else
|
|
(: Check-in Job :)
|
|
if($body/job/checkin)
|
|
then JOBS:checkin-job($body,$authorization)
|
|
else
|
|
(: Publish Job :)
|
|
if($body/job/publish)
|
|
then JOBS:publish-job($body,$authorization)
|
|
else update:output(<result><status>Failure</status><message>Currently system supports job type 'ingest', 'check-in' only.</message></result>)
|
|
else update:output(<result><status>Failure</status><message>Uploaded file is unavailable.</message></result>)
|
|
}
|
|
catch *
|
|
{
|
|
admin:write-log("[Job Create][Error: " || $err:description || "]"),
|
|
admin:write-log("[Job Create][Error: " || $err:additional || "]"),
|
|
update:output(<result><status>Error</status><message>Error generated. Please check system log</message></result>)
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
(:~
|
|
: To get information of a specific job
|
|
: @param $jobID ID of the job
|
|
: @header $authorization Authorization key
|
|
: @return element(result)
|
|
:)
|
|
declare
|
|
%rest:path("/job")
|
|
%rest:GET
|
|
%rest:query-param("jobid", "{$jobID}")
|
|
%rest:query-param("supress", "{$supress}")
|
|
%rest:header-param("Authorization", "{$authorization}", "none")
|
|
|
|
function JOBS:info(
|
|
$jobID as xs:string?,
|
|
$supress as xs:string?,
|
|
$authorization as xs:string
|
|
)
|
|
{
|
|
config:session-check($authorization),
|
|
try
|
|
{
|
|
let $jobDoc := db:open($config:CoreDatabase,fn:concat($config:JobDir,$jobID,'.xml'))
|
|
return
|
|
|
|
|
|
if($jobDoc)
|
|
then
|
|
if($jobDoc/job/job-info/job-type='Publish')
|
|
then
|
|
let $id := $jobDoc/job/job-info/id
|
|
let $productid := $jobDoc/job/job-info/product-id
|
|
let $producname := $jobDoc/job/job-info/product-name
|
|
let $pipelineid := $jobDoc/job/job-info/pipeline-id
|
|
let $pipelinename := $jobDoc/job/job-info/pipeline-name
|
|
let $taxonomyid := $jobDoc/job/job-info/taxonomy-id
|
|
let $taxonomyname := $jobDoc/job/job-info/taxonomy-name
|
|
let $jobtype := $jobDoc/job/job-info/job-type
|
|
let $submittedon := $jobDoc/job/job-info/submitted-on
|
|
let $ignorevalidation := $jobDoc/job/job-info/ignore-validation
|
|
let $mailrequired := $jobDoc/job/job-info/mail-required
|
|
let $requesterid := $jobDoc/job/job-info/requester-id
|
|
let $requesteremail := $jobDoc/job/job-info/requester-email
|
|
let $location := $jobDoc/job/job-info/location
|
|
let $status := $jobDoc/job/ingestion-report/status
|
|
let $finished-on := $jobDoc/job/ingestion-report/finished-on
|
|
return <result>
|
|
<status>Success</status>
|
|
<job><job-info>
|
|
{
|
|
$id,
|
|
$productid,
|
|
$producname,
|
|
$pipelineid,
|
|
$pipelinename,
|
|
$taxonomyid,
|
|
$taxonomyname,
|
|
$jobtype,
|
|
$submittedon,
|
|
$ignorevalidation,
|
|
$mailrequired,
|
|
$requesterid,
|
|
$requesteremail,
|
|
$location
|
|
}
|
|
</job-info>
|
|
<ingestion-report><steps></steps>{$status,$finished-on}</ingestion-report>
|
|
</job>
|
|
</result>
|
|
else
|
|
(:<result><status>Success</status>{$jobDoc}</result>:)
|
|
if($supress='yes')
|
|
then
|
|
let $SkipErrorStep := <job>{$jobDoc/job/job-info}
|
|
<ingestion-report>
|
|
<steps>
|
|
{
|
|
for $steps in $jobDoc/job/ingestion-report/steps/step[*:errors!='']
|
|
return
|
|
<step>
|
|
{
|
|
$steps/type,
|
|
|
|
$steps[contains(type,'schema-validation :')]/*:errors,
|
|
if($steps[contains(type,'schematron-validation :')]) then
|
|
<error>
|
|
{
|
|
<report>{
|
|
$steps/*:errors[.!='']/message[not(
|
|
contains(.,'warn:')
|
|
or contains(.,'info:')
|
|
)
|
|
]
|
|
}
|
|
</report>
|
|
}</error>
|
|
else()
|
|
}
|
|
</step>
|
|
}
|
|
</steps>
|
|
</ingestion-report>
|
|
</job>
|
|
|
|
return
|
|
<result><status>Success</status>{$SkipErrorStep}</result>
|
|
else
|
|
<result><status>Success</status>{$jobDoc}</result>
|
|
else
|
|
<result><status>Failure</status><message>Job information is not available</message></result>
|
|
}
|
|
catch *
|
|
{
|
|
admin:write-log("[Job Details][Error: " || $err:description || "]"),
|
|
admin:write-log("[Job Details][Error: " || $err:additional || "]"),
|
|
<result><status>Error</status><message>Error generated. Please check system log</message></result>
|
|
}
|
|
};
|
|
|
|
(:~
|
|
: To Download publish report
|
|
: @param $jobID ID of the job
|
|
: @header $authorization Authorization key
|
|
: @return element(result)
|
|
:)
|
|
declare
|
|
%rest:path("/publishreport/{$jobID=.+}")
|
|
%rest:GET
|
|
%rest:header-param("Authorization", "{$authorization}", "none")
|
|
|
|
function JOBS:publishjobreport(
|
|
$jobID as xs:string?,
|
|
$authorization as xs:string
|
|
)
|
|
{
|
|
config:session-check($authorization),
|
|
try
|
|
{
|
|
|
|
let $jobDoc := db:open($config:CoreDatabase,fn:concat($config:JobDir,$jobID,'.xml'))
|
|
return
|
|
if($jobDoc)
|
|
then
|
|
let $joburi := base-uri($jobDoc)
|
|
let $filename := fn:tokenize($joburi,'/')[fn:last()]
|
|
return
|
|
(
|
|
if(file:is-dir($config:PublishReportDir))
|
|
then
|
|
file:write(fn:concat($config:PublishReportDir,$filename),$jobDoc)
|
|
else
|
|
(
|
|
file:create-dir($config:PublishReportDir),
|
|
file:write(fn:concat($config:PublishReportDir,$filename),$jobDoc))
|
|
,
|
|
let $zipName := fn:concat($jobID,'_',fn:format-dateTime(fn:current-dateTime(), "[Y1,4][M01][D01][H01][m01][s01][f01]"))
|
|
let $filelist := file:list($config:PublishReportDir, true(),fn:concat($jobID,'.xml'))
|
|
let $archive := archive:create($filelist ! element archive:entry { . }, $filelist ! file:read-binary($config:PublishReportDir || .))
|
|
(:let $archive := archive:create-from($config:PublishReportDir):)
|
|
let $ziplocation := fn:concat($config:OutDir,$zipName,'.zip')
|
|
return
|
|
(
|
|
file:write-binary(fn:concat($config:OutDir,$zipName,'.zip'),$archive),
|
|
<result>
|
|
<status>Success</status>
|
|
<path>{$ziplocation}</path>
|
|
</result>
|
|
|
|
)
|
|
)
|
|
else <result><status>Failure</status><message>Job information is not available</message></result>
|
|
}
|
|
catch *
|
|
{
|
|
admin:write-log("[Job Details][Error: " || $err:description || "]"),
|
|
admin:write-log("[Job Details][Error: " || $err:additional || "]"),
|
|
<result><status>Error</status><message>Error generated. Please check system log</message></result>
|
|
}
|
|
};
|
|
|
|
|
|
(:~
|
|
: To get all available user or search users by user name.
|
|
: @param $user Email of the user to get user specific jobs
|
|
: @param $type Job type (Ingest/Publish)
|
|
: @param $status Job status (Success/Failure/In Progress)
|
|
: @param $page integer Page number of the list optional
|
|
: @param $size integer Total number of records to diplay in a page optional
|
|
: @header $authorization Authorization key
|
|
: @return element(result)
|
|
:)
|
|
declare
|
|
%rest:path("/jobs")
|
|
%rest:GET
|
|
%rest:query-param("query", "{$query}","")
|
|
%rest:query-param("user", "{$user}","")
|
|
%rest:query-param("allrecords", "{$allrecords}","")
|
|
%rest:query-param("type", "{$type}","")
|
|
%rest:query-param("status", "{$status}","")
|
|
%rest:query-param("orderby", "{$orderby}","")
|
|
%rest:query-param("page", "{$page}")
|
|
%rest:query-param("size", "{$size}")
|
|
%rest:header-param("Authorization", "{$authorization}", "none")
|
|
|
|
function JOBS:list(
|
|
$query as xs:string?,
|
|
$user as xs:string?,
|
|
$allrecords as xs:string?,
|
|
$type as xs:string,
|
|
$status as xs:string,
|
|
$orderby as xs:string,
|
|
$page as xs:integer?,
|
|
$size as xs:integer?,
|
|
$authorization as xs:string
|
|
)
|
|
{
|
|
config:session-check($authorization),
|
|
try
|
|
{
|
|
let $page := if($page) then $page else $config:page
|
|
let $size := if($size) then $size else $config:size
|
|
|
|
let $jobRecords := <jobs>{
|
|
for $eachJob in db:open($config:CoreDatabase,$config:JobDir)/job[if($type='Publish') then job-info/job-type='Publish' else .]
|
|
[if($type!='Publish') then job-info/job-type!='Publish' else .]
|
|
(:[if($user) then job-info/requester-id=$user else .]:)
|
|
[if($user and $allrecords='true') then (db:open($config:CoreDatabase,$config:UserDir)/user[role='admin'][id=$user]) else job-info/requester-id=$user]
|
|
(:[if($query!='') then fn:matches(job-info/requester-name,$query,'i') else .]:)
|
|
[if($query!='') then let $requesterid := job-info/requester-id/string() return fn:matches((fn:collection(fn:concat('bloomsbury/user/',$requesterid,'.xml'))/user/name/string()),$query,'i' ) else .]
|
|
[if($status) then fn:starts-with(ingestion-report/status,$status) else .]
|
|
let $name := if($type!='Publish') then <upload-file>{fn:tokenize(data($eachJob/job-info/uploaded-file),'/')[fn:last()]}</upload-file> else <product-name>{$eachJob/job-info/product-name/string()}</product-name>
|
|
let $requester-email := $eachJob/job-info/requester-email
|
|
let $requester-id := $eachJob/job-info/requester-id
|
|
let $id := $eachJob/job-info/id
|
|
let $date := $eachJob/job-info/submitted-on
|
|
let $type := $eachJob/job-info/job-type
|
|
let $username := <user>{distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[id=$requester-id][fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))]/name/string())}</user>
|
|
let $status := $eachJob/ingestion-report/status
|
|
let $filename := fn:tokenize($eachJob/job-info/uploaded-file,'/')[fn:last()]
|
|
|
|
order by
|
|
if ($orderby='dateasc') then xs:dateTime($date) else (),
|
|
if ($orderby='datedsc') then xs:dateTime($date) else () descending,
|
|
if ($orderby='userasc') then ($username) else (),
|
|
if ($orderby='userdsc') then ($username) else () descending,
|
|
if ($orderby='filenameasc') then ($filename) else (),
|
|
if ($orderby='filenamedsc') then ($filename) else () descending,
|
|
if ($orderby='productasc') then ($name) else (),
|
|
if ($orderby='productdsc') then ($name) else () descending
|
|
|
|
return <job>{$id,$name,$date,$type,$username,$status,$requester-email,$requester-id}</job>
|
|
}</jobs>
|
|
let $countRecord := count($jobRecords/job)
|
|
let $start := if($page eq 1)
|
|
then $page
|
|
else if($page gt 1)
|
|
then fn:sum(($page * $size)+1) - $size
|
|
else fn:sum(($page * $size)) - $size
|
|
let $end := if($page eq 1)
|
|
then $size
|
|
else if($page gt 1)
|
|
then fn:sum(($start + $size)-1)
|
|
else fn:sum($start + $size)
|
|
return
|
|
if($jobRecords/job)
|
|
then
|
|
(
|
|
<result><status>Success</status><total>{$countRecord}</total><entities>{$jobRecords/job[position() = $start to $end]}</entities></result>,
|
|
|
|
config:non-update-message("[Job List][Job list has been sent successfully]")
|
|
)
|
|
else
|
|
(
|
|
<result><status>Failure</status><message>Job information is unavailable</message></result>,
|
|
config:non-update-message("[Job List][Job list is unavailable]")
|
|
)
|
|
}
|
|
catch *
|
|
{
|
|
admin:write-log("[Job List][Error: " || $err:description || "]"),
|
|
admin:write-log("[Job List][Error: " || $err:additional || "]"),
|
|
<result><status>Error</status><message>Error generated. Please check system log</message></result>
|
|
}
|
|
};
|
|
|
|
(:~
|
|
: To ingest a content
|
|
: @param $body <job><ingest><area>Professional</area><ctype>looseleaf</ctype><ignore-validation>true</ignore-validation><mail>true</mail><path>D:\Backup\Projects\bloomsbury\SharedData\Steve\word2xml\small66.zip</path></ingest></job>
|
|
: @header $authorization Authorization key
|
|
: @return element(result)
|
|
:)
|
|
declare %private %updating function JOBS:ingest-job(
|
|
$body as document-node(),
|
|
$authorization as xs:string
|
|
)
|
|
{
|
|
let $area := $body/job/ingest/area/text()
|
|
let $ctype := $body/job/ingest/ctype/text()
|
|
let $ignoreValidation := $body/job/ingest/ignore-validation/text()
|
|
let $sendMail := $body/job/ingest/mail/text()
|
|
let $contentPath := fn:replace($body/job/ingest/path/text(),'\\','/')
|
|
let $sessionValue := config:session-value($authorization)
|
|
let $UploadFileName := fn:tokenize($contentPath,'\\')[fn:last()]
|
|
let $jobID := fn:concat($config:JobIDPrefix,fn:string(fn:format-dateTime(fn:current-dateTime(), '[Y0001][M01][D01][H01][m01][s01][f01]')))
|
|
return
|
|
<results>
|
|
{
|
|
if(fn:ends-with(fn:lower-case($UploadFileName),'.zip'))
|
|
then
|
|
if(file:exists($UploadFileName))
|
|
then
|
|
if($ctype='looseleaf')
|
|
then
|
|
(: Check header.xml existence. Raise error if not available.:)
|
|
if(archive:entries(file:read-binary($contentPath))[fn:contains(.,$config:HeaderXml)])
|
|
then
|
|
let $cid := try
|
|
{
|
|
let $archive := file:read-binary($contentPath)
|
|
let $entry := archive:entries($archive)[fn:ends-with(., $config:HeaderXml)]
|
|
return fn:parse-xml(archive:extract-text($archive, $entry))/*/@xml:id/string()
|
|
}
|
|
catch *
|
|
{
|
|
let $archive := file:read-binary($contentPath)
|
|
let $entry := archive:entries($archive)[fn:ends-with(.,$config:HeaderXml)]
|
|
let $xml:= archive:extract-text($archive, $entry)
|
|
return fn:substring-before(fn:substring-after($xml,'xml:id="'),'"')
|
|
}
|
|
return
|
|
if($cid)
|
|
then
|
|
if(db:open($config:CoreDatabase,$config:JobDir)/job[job-info/cid/text()=$cid][job-info/job-type='Ingest'][ingestion-report/status='InQueue'])
|
|
then <result><status>Failure</status><message>Job is already in queue.</message></result>
|
|
else
|
|
if(db:open($config:CoreDatabase,$config:JobDir)/job[job-info/cid/text()=$cid][job-info/job-type='Ingest'] and (db:list(blcommon:get-db-name($ctype),fn:concat($config:ContentDir,$cid,'/')))[1])
|
|
then <result><status>Failure</status><message>This is already ingested</message></result>
|
|
else
|
|
let $pid := contents:get-applied-ingest-pipeline($ctype,'zip')
|
|
return
|
|
if(
|
|
db:open($config:CoreDatabase,$config:JobDir)/job[job-info/cid/text()=$cid]
|
|
[job-info/job-type='Ingest']
|
|
[ingestion-report/status='InQueue']
|
|
or (db:list(blcommon:get-db-name($ctype),fn:concat($config:ContentDir,$cid,'/')))[1]
|
|
)
|
|
then
|
|
<result><status>Failure</status><message>The Content Id/s {$cid} is/are already ingested or in queue</message></result>
|
|
else
|
|
if($pid)
|
|
then
|
|
(
|
|
let $jobChunk := <job>
|
|
<job-info>
|
|
<id>{$jobID}</id>
|
|
<cid>{$cid}</cid>
|
|
<pipeline-id>{$pid}</pipeline-id>
|
|
<pipeline-name>{db:open($config:CoreDatabase,$config:PipelineDir)/pipeline:pipeline[@id=$pid]/@name/string()}</pipeline-name>
|
|
<area>{$area}</area>
|
|
<job-type>Ingest</job-type>
|
|
<submitted-on>{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}</submitted-on>
|
|
<uploaded-file>{$contentPath}</uploaded-file>
|
|
<content-type>{$ctype}</content-type>
|
|
<content-format>zip</content-format>
|
|
<ignore-validation>{$ignoreValidation}</ignore-validation>
|
|
<mail-required>{$sendMail}</mail-required>
|
|
<requester-id>{fn:substring-before(config:session-value($authorization),'$$$$')}</requester-id>
|
|
<requester-email>{fn:substring-after(config:session-value($authorization),'$$$$')}</requester-email>
|
|
<requester-name>{distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))][id=fn:substring-before(config:session-value($authorization),'$$$$')]/name)}</requester-name>
|
|
<location>{fn:concat($config:TempPipelineDir,$jobID)}</location>
|
|
</job-info>
|
|
<ingestion-report>
|
|
<steps/>
|
|
<status>InQueue</status>
|
|
<finished-on></finished-on>
|
|
</ingestion-report>
|
|
</job>
|
|
return db:add($config:CoreDatabase,$jobChunk,fn:concat($config:JobDir,$jobID,'.xml'))
|
|
,
|
|
<result><status>Success</status><message>Job created</message><jobid>{$jobID}</jobid></result>
|
|
)
|
|
else <result><status>Failure</status><message>Pipeline is not available.</message></result>
|
|
else <result><status>Failure</status><message>System error</message></result>
|
|
else <result><status>Failure</status><message>Content fails pre-ingestion check. header.xml file is not available</message></result>
|
|
|
|
|
|
else if($ctype='play')
|
|
then
|
|
|
|
( let $startedOn := fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))
|
|
let $archive := file:read-binary($contentPath)
|
|
for $entry in archive:entries($archive)[fn:ends-with(., '.xml')]
|
|
let $validate := validate:dtd-report(archive:extract-text($archive,$entry))
|
|
let $ContentId := fn:replace($entry/text(),'[^0-9]', '')
|
|
(:let $ContentId := fn:parse-xml(archive:extract-text($archive, $entry))/*/@xml:id/string():)
|
|
|
|
let $WellformedReport := <errors>
|
|
{
|
|
for $Message in $validate//message[@level='Fatal']
|
|
return $Message
|
|
}
|
|
</errors>
|
|
let $ModifiedReport := <report>
|
|
{
|
|
<status>{if($WellformedReport//message/@level/string()='Fatal') then 'invalid' else ()}</status>,
|
|
$WellformedReport
|
|
|
|
}
|
|
</report>
|
|
|
|
return
|
|
(:if(not(fn:empty($WellformedReport/*))):)
|
|
if($ModifiedReport//status='invalid')
|
|
then
|
|
|
|
let $jobID := fn:concat($config:JobIDPrefix,$ContentId,'-',fn:string(fn:format-dateTime(fn:current-dateTime(), '[Y0001][M01][D01][H01][m01][s01][f01]')))
|
|
let $jobChunk := <job>
|
|
<job-info>
|
|
<id>{$jobID}</id>
|
|
<cid>{$ContentId}</cid>
|
|
<pipeline-id></pipeline-id>
|
|
<pipeline-name></pipeline-name>
|
|
<area>{$area}</area>
|
|
<job-type>Ingest</job-type>
|
|
<submitted-on>{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}</submitted-on>
|
|
<uploaded-file>{$contentPath}</uploaded-file>
|
|
<content-type>{$ctype}</content-type>
|
|
<content-format>zip</content-format>
|
|
<ignore-validation>{$ignoreValidation}</ignore-validation>
|
|
<mail-required>{$sendMail}</mail-required>
|
|
<requester-id>{fn:substring-before(config:session-value($authorization),'$$$$')}</requester-id>
|
|
<requester-email>{fn:substring-after(config:session-value($authorization),'$$$$')}</requester-email>
|
|
<requester-name>{distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))][id=fn:substring-before(config:session-value($authorization),'$$$$')]/name)}</requester-name>
|
|
<location>{fn:concat($config:TempPipelineDir,$jobID)}</location>
|
|
</job-info>
|
|
<ingestion-report>
|
|
<steps>
|
|
<step>Wellformed:</step>
|
|
<started-on>{$startedOn}</started-on>
|
|
<location></location>
|
|
<completed-on>{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}</completed-on>
|
|
<errors>
|
|
{
|
|
$WellformedReport//message
|
|
}
|
|
</errors>
|
|
</steps>
|
|
<status>Failure</status>
|
|
</ingestion-report>
|
|
</job>
|
|
return
|
|
(
|
|
db:add($config:CoreDatabase,$jobChunk,fn:concat($config:JobDir,$jobID,'.xml'))
|
|
,
|
|
<result><status>Success</status><message>Job created</message><jobid>{$jobID}</jobid></result>
|
|
)
|
|
|
|
else
|
|
let $doc := fn:parse-xml(archive:extract-text($archive, $entry))
|
|
let $RootNode := fn:name($doc/*)
|
|
return
|
|
if($RootNode='TEI')
|
|
then
|
|
(
|
|
|
|
for $cid in try
|
|
{
|
|
let $docId := $doc/*/@xml:id/string()[$RootNode='TEI']
|
|
return $docId
|
|
}
|
|
catch *
|
|
{
|
|
let $docId := $doc/*/@xml:id/string()[$RootNode='TEI']
|
|
return $docId
|
|
}
|
|
let $jobID := fn:concat($config:JobIDPrefix,$cid,'-',fn:string(fn:format-dateTime(fn:current-dateTime(), '[Y0001][M01][D01][H01][m01][s01][f01]')))
|
|
return
|
|
if($cid)
|
|
then
|
|
if(db:open($config:CoreDatabase,$config:JobDir)/job[job-info/cid/text()=$cid][job-info/job-type='Ingest'][ingestion-report/status='InQueue'])
|
|
then <result><status>Failure</status><message>Job is already in queue.</message></result>
|
|
else
|
|
if(db:open($config:CoreDatabase,$config:JobDir)/job[job-info/cid/text()=$cid][job-info/job-type='Ingest'] and (db:list(blcommon:get-db-name($ctype),fn:concat($config:ContentDir,$cid,'/')))[1])
|
|
then <result><status>Failure</status><message>Content ID:{$cid} is/are already ingested</message></result>
|
|
else
|
|
let $pid := contents:get-applied-ingest-pipeline($ctype,'zip')
|
|
return
|
|
if(
|
|
db:open($config:CoreDatabase,$config:JobDir)/job[job-info/cid/text()=$cid]
|
|
[job-info/job-type='Ingest']
|
|
[ingestion-report/status='InQueue']
|
|
(:or (db:list(blcommon:get-db-name($ctype),fn:concat($config:ContentDir,$cid,'/')))[1]:)
|
|
)
|
|
then
|
|
<result><status>Failure</status><message>The Content Id/s {$cid} is/are already ingested or in queue</message></result>
|
|
else
|
|
if($pid)
|
|
then
|
|
(
|
|
let $jobChunk := <job>
|
|
<job-info>
|
|
<id>{$jobID}</id>
|
|
<cid>{$cid}</cid>
|
|
<pipeline-id>{$pid}</pipeline-id>
|
|
<pipeline-name>{db:open($config:CoreDatabase,$config:PipelineDir)/pipeline:pipeline[@id=$pid]/@name/string()}</pipeline-name>
|
|
<area>{$area}</area>
|
|
<job-type>Ingest</job-type>
|
|
<submitted-on>{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}</submitted-on>
|
|
<uploaded-file>{$contentPath}</uploaded-file>
|
|
<content-type>{$ctype}</content-type>
|
|
<content-format>zip</content-format>
|
|
<ignore-validation>{$ignoreValidation}</ignore-validation>
|
|
<mail-required>{$sendMail}</mail-required>
|
|
<requester-id>{fn:substring-before(config:session-value($authorization),'$$$$')}</requester-id>
|
|
<requester-email>{fn:substring-after(config:session-value($authorization),'$$$$')}</requester-email>
|
|
<requester-name>{distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))][id=fn:substring-before(config:session-value($authorization),'$$$$')]/name)}</requester-name>
|
|
<location>{fn:concat($config:TempPipelineDir,$jobID)}</location>
|
|
</job-info>
|
|
<ingestion-report>
|
|
<steps/>
|
|
<status>InQueue</status>
|
|
<finished-on></finished-on>
|
|
</ingestion-report>
|
|
</job>
|
|
return db:add($config:CoreDatabase,$jobChunk,fn:concat($config:JobDir,$jobID,'.xml'))
|
|
,
|
|
<result><status>Success</status><message>Job created</message><jobid>{$jobID}</jobid></result>
|
|
)
|
|
else <result><status>Failure</status><message>Pipeline is not available.</message></result>
|
|
|
|
else <result><status>Failure</status><message>System error</message></result>
|
|
)
|
|
else <result><status>Failure</status><message>Content fails pre-ingestion check. TEI format required only for content type play.</message></result>
|
|
)
|
|
else if($ctype='monograph')
|
|
then
|
|
let $startedOn := fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))
|
|
let $archive := file:read-binary($contentPath)
|
|
for $entry in archive:entries($archive)[fn:ends-with(., '.xml')]
|
|
let $validate := validate:dtd-report(archive:extract-text($archive,$entry))
|
|
let $ContentId := fn:replace($entry/text(),'[^0-9]', '')
|
|
let $WellformedReport := <errors>
|
|
{
|
|
for $Message in $validate//message[@level='Fatal']
|
|
return $Message
|
|
}
|
|
</errors>
|
|
let $ModifiedReport := <report>
|
|
{
|
|
<status>{if($WellformedReport//message/@level/string()='Fatal') then 'invalid' else ()}</status>,
|
|
$WellformedReport
|
|
|
|
}
|
|
</report>
|
|
|
|
return
|
|
if($ModifiedReport//status='invalid')
|
|
then
|
|
let $jobID := fn:concat($config:JobIDPrefix,$ContentId,'-',fn:string(fn:format-dateTime(fn:current-dateTime(), '[Y0001][M01][D01][H01][m01][s01][f01]')))
|
|
let $jobChunk := <job>
|
|
<job-info>
|
|
<id>{$jobID}</id>
|
|
<cid>{$ContentId}</cid>
|
|
<pipeline-id></pipeline-id>
|
|
<pipeline-name></pipeline-name>
|
|
<area>{$area}</area>
|
|
<job-type>Ingest</job-type>
|
|
<submitted-on>{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}</submitted-on>
|
|
<uploaded-file>{$contentPath}</uploaded-file>
|
|
<content-type>{$ctype}</content-type>
|
|
<content-format>zip</content-format>
|
|
<ignore-validation>{$ignoreValidation}</ignore-validation>
|
|
<mail-required>{$sendMail}</mail-required>
|
|
<requester-id>{fn:substring-before(config:session-value($authorization),'$$$$')}</requester-id>
|
|
<requester-email>{fn:substring-after(config:session-value($authorization),'$$$$')}</requester-email>
|
|
<requester-name>{distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))][id=fn:substring-before(config:session-value($authorization),'$$$$')]/name)}</requester-name>
|
|
<location>{fn:concat($config:TempPipelineDir,$jobID)}</location>
|
|
</job-info>
|
|
<ingestion-report>
|
|
<steps>
|
|
<step>Wellformed:</step>
|
|
<started-on>{$startedOn}</started-on>
|
|
<location></location>
|
|
<completed-on>{{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}}</completed-on>
|
|
<errors>
|
|
{
|
|
$WellformedReport//message
|
|
}
|
|
</errors>
|
|
</steps>
|
|
<status>Failure</status>
|
|
</ingestion-report>
|
|
</job>
|
|
return
|
|
(
|
|
db:add($config:CoreDatabase,$jobChunk,fn:concat($config:JobDir,$jobID,'.xml'))
|
|
,
|
|
<result><status>Success</status><message>Job created</message><jobid>{$jobID}</jobid></result>
|
|
)
|
|
else
|
|
let $doc := fn:parse-xml(archive:extract-text($archive, $entry))
|
|
let $RootNode := fn:name($doc/*)
|
|
return
|
|
if($RootNode='book')
|
|
then
|
|
(
|
|
|
|
for $cid in try
|
|
{
|
|
let $docId := $doc/*/@xml:id/string()
|
|
return $docId
|
|
}
|
|
catch *
|
|
{
|
|
let $docId := $doc/*/@xml:id/string()
|
|
return $docId
|
|
}
|
|
let $jobID := fn:concat($config:JobIDPrefix,$cid,'-',fn:string(fn:format-dateTime(fn:current-dateTime(), '[Y0001][M01][D01][H01][m01][s01][f01]')))
|
|
return
|
|
if($cid)
|
|
then
|
|
if(db:open($config:CoreDatabase,$config:JobDir)/job[job-info/cid/text()=$cid][job-info/job-type='Ingest'][ingestion-report/status='InQueue'])
|
|
then <result><status>Failure</status><message>Job is already in queue.</message></result>
|
|
else
|
|
if(db:open($config:CoreDatabase,$config:JobDir)/job[job-info/cid/text()=$cid][job-info/job-type='Ingest'] and (db:list(blcommon:get-db-name($ctype),fn:concat($config:ContentDir,$cid,'/')))[1])
|
|
then <result><status>Failure</status><message>Content ID:{$cid} is/are already ingested</message></result>
|
|
else
|
|
let $pid := contents:get-applied-ingest-pipeline($ctype,'zip')
|
|
return
|
|
if(
|
|
db:open($config:CoreDatabase,$config:JobDir)/job[job-info/cid/text()=$cid]
|
|
[job-info/job-type='Ingest']
|
|
[ingestion-report/status='InQueue']
|
|
(:or (db:list(blcommon:get-db-name($ctype),fn:concat($config:ContentDir,$cid,'/')))[1]:)
|
|
)
|
|
then
|
|
<result><status>Failure</status><message>The Content Id/s {$cid} is/are already ingested or in queue</message></result>
|
|
else
|
|
if($pid)
|
|
then
|
|
(
|
|
let $jobChunk := <job>
|
|
<job-info>
|
|
<id>{$jobID}</id>
|
|
<cid>{$cid}</cid>
|
|
<pipeline-id>{$pid}</pipeline-id>
|
|
<pipeline-name>{db:open($config:CoreDatabase,$config:PipelineDir)/pipeline:pipeline[@id=$pid]/@name/string()}</pipeline-name>
|
|
<area>{$area}</area>
|
|
<job-type>Ingest</job-type>
|
|
<submitted-on>{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}</submitted-on>
|
|
<uploaded-file>{$contentPath}</uploaded-file>
|
|
<content-type>{$ctype}</content-type>
|
|
<content-format>zip</content-format>
|
|
<ignore-validation>{$ignoreValidation}</ignore-validation>
|
|
<mail-required>{$sendMail}</mail-required>
|
|
<requester-id>{fn:substring-before(config:session-value($authorization),'$$$$')}</requester-id>
|
|
<requester-email>{fn:substring-after(config:session-value($authorization),'$$$$')}</requester-email>
|
|
<requester-name>{distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))][id=fn:substring-before(config:session-value($authorization),'$$$$')]/name)}</requester-name>
|
|
<location>{fn:concat($config:TempPipelineDir,$jobID)}</location>
|
|
</job-info>
|
|
<ingestion-report>
|
|
<steps/>
|
|
<status>InQueue</status>
|
|
<finished-on></finished-on>
|
|
</ingestion-report>
|
|
</job>
|
|
return db:add($config:CoreDatabase,$jobChunk,fn:concat($config:JobDir,$jobID,'.xml'))
|
|
,
|
|
<result><status>Success</status><message>Job created</message><jobid>{$jobID}</jobid></result>
|
|
)
|
|
else <result><status>Failure</status><message>Pipeline is not available.</message></result>
|
|
|
|
else <result><status>Failure</status><message>System error</message></result>
|
|
)
|
|
else <result><status>Failure</status><message>Content fails pre-ingestion check. Book format required only for content type play.</message></result>
|
|
else<result><status>Failure</status><message>Zip is not allowed for this content type {$ctype}.</message></result>
|
|
|
|
else <result><status>Failure</status><message>Content is not available or accessible from this location</message></result>
|
|
else
|
|
if(fn:ends-with(fn:lower-case($UploadFileName),'.xml') or fn:ends-with(fn:lower-case($UploadFileName),'.docx'))
|
|
|
|
then
|
|
if(file:exists($UploadFileName))
|
|
then
|
|
let $startedOn := fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))
|
|
let $CheckWelformed := let $ValidateDoc := validate:dtd-report($UploadFileName)
|
|
let $Report := <erros>
|
|
{
|
|
for $Message in $ValidateDoc/message[@level='Fatal']
|
|
return $Message
|
|
}
|
|
</erros>
|
|
return
|
|
<report>
|
|
{
|
|
<status>{if($Report//message/@level/string()='Fatal') then 'invalid' else ()}</status>,
|
|
$Report
|
|
}
|
|
</report>
|
|
|
|
|
|
return
|
|
if($CheckWelformed//status='invalid')
|
|
then
|
|
let $jobChunk := <job>
|
|
<job-info>
|
|
<id>{$jobID}</id>
|
|
<cid>{fn:replace(fn:tokenize(fn:replace($UploadFileName,'\\','/'),'/')[fn:last()],'[^0-9]', '')}</cid>
|
|
<pipeline-id></pipeline-id>
|
|
<pipeline-name></pipeline-name>
|
|
<area>{$area}</area>
|
|
<job-type>Ingest</job-type>
|
|
<submitted-on>{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}</submitted-on>
|
|
<uploaded-file>{$contentPath}</uploaded-file>
|
|
<content-type>{$ctype}</content-type>
|
|
<content-format>
|
|
{
|
|
if(fn:ends-with(fn:lower-case($UploadFileName),'.xml'))
|
|
then 'xml'
|
|
else 'docx'
|
|
}
|
|
</content-format>
|
|
<ignore-validation>{$ignoreValidation}</ignore-validation>
|
|
<mail-required>{$sendMail}</mail-required>
|
|
<requester-id>{fn:substring-before(config:session-value($authorization),'$$$$')}</requester-id>
|
|
<requester-email>{fn:substring-after(config:session-value($authorization),'$$$$')}</requester-email>
|
|
<requester-name>{distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))][id=fn:substring-before(config:session-value($authorization),'$$$$')]/name)}</requester-name>
|
|
<location>{fn:concat($config:TempPipelineDir,$jobID)}</location>
|
|
</job-info>
|
|
<ingestion-report>
|
|
<steps>
|
|
<step>Wellformed:</step>
|
|
<started-on>{$startedOn}</started-on>
|
|
<location></location>
|
|
<completed-on>{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}</completed-on>
|
|
<errors>
|
|
{
|
|
$CheckWelformed
|
|
}
|
|
</errors>
|
|
</steps>
|
|
<status>Failure</status>
|
|
</ingestion-report>
|
|
</job>
|
|
return
|
|
(
|
|
db:add($config:CoreDatabase,$jobChunk,fn:concat($config:JobDir,$jobID,'.xml'))
|
|
,
|
|
<result><status>Success</status><message>Job created</message><jobid>{$jobID}</jobid></result>
|
|
)
|
|
|
|
else
|
|
if($ctype='play')
|
|
then
|
|
let $doc := fetch:xml($contentPath,map { 'xinclude': false() })
|
|
let $rootNode := fn:name($doc/*)
|
|
return
|
|
if($rootNode!='TEI')
|
|
then <result><status>Failure</status><message>Content fails pre-ingestion check. TEI format required only for content type play.</message></result>
|
|
else
|
|
(:let $cid := if( fn:matches(fn:doc($contentPath)/*/@xml:id/string(),'[a-zA-z-]'))
|
|
then fn:replace(fn:doc($contentPath)/*/@xml:id/string(),'[a-zA-z-]','')
|
|
else fn:doc($contentPath)/*/@xml:id/string():)
|
|
let $cid := fn:doc($contentPath)/*/@xml:id/string()
|
|
|
|
return
|
|
if($cid)
|
|
then
|
|
if (
|
|
db:open($config:CoreDatabase,$config:JobDir)/job[job-info/cid/text()=$cid]
|
|
[job-info/job-type='Ingest']
|
|
[ingestion-report/status='InQueue']
|
|
or (db:list( blcommon:get-db-name($ctype),fn:concat($config:ContentDir,$cid,'/')))[1]
|
|
)
|
|
then
|
|
<result><status>Failure</status><message>The Content Id/s {$cid} is/are already ingested or in queue</message></result>
|
|
else
|
|
let $pid := contents:get-applied-ingest-pipeline($ctype,if(fn:ends-with(fn:lower-case($UploadFileName),'.xml')) then 'xml' else ())
|
|
return
|
|
if($pid)
|
|
then
|
|
(
|
|
let $jobChunk := <job>
|
|
<job-info>
|
|
<id>{$jobID}</id>
|
|
<cid>{$cid}</cid>
|
|
<pipeline-id>{$pid}</pipeline-id>
|
|
<pipeline-name>{db:open($config:CoreDatabase,$config:PipelineDir)/pipeline:pipeline[@id=$pid]/@name/string()}</pipeline-name>
|
|
<area>{$area}</area>
|
|
<job-type>Ingest</job-type>
|
|
<submitted-on>{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}</submitted-on>
|
|
<uploaded-file>{$contentPath}</uploaded-file>
|
|
<content-type>{$ctype}</content-type>
|
|
<content-format>
|
|
{
|
|
if(fn:ends-with(fn:lower-case($UploadFileName),'.xml'))
|
|
then 'xml'
|
|
else 'docx'
|
|
}
|
|
</content-format>
|
|
<ignore-validation>{$ignoreValidation}</ignore-validation>
|
|
<mail-required>{$sendMail}</mail-required>
|
|
<requester-id>{fn:substring-before(config:session-value($authorization),'$$$$')}</requester-id>
|
|
<requester-email>{fn:substring-after(config:session-value($authorization),'$$$$')}</requester-email>
|
|
<requester-name>{distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))][id=fn:substring-before(config:session-value($authorization),'$$$$')]/name)}</requester-name>
|
|
<location>{fn:concat($config:TempPipelineDir,$jobID)}</location>
|
|
</job-info>
|
|
<ingestion-report>
|
|
<steps/>
|
|
<status>InQueue</status>
|
|
<finished-on></finished-on>
|
|
</ingestion-report>
|
|
</job>
|
|
return db:add($config:CoreDatabase,$jobChunk,fn:concat($config:JobDir,$jobID,'.xml'))
|
|
,
|
|
<result><status>Success</status><message>Job created</message><jobid>{$jobID}</jobid></result>
|
|
)
|
|
else <result><status>Failure</status><message>Pipeline is not available.</message></result>
|
|
else <result><status>Failure</status><message>System error</message></result>
|
|
|
|
else if($ctype='monograph')
|
|
then
|
|
let $doc := fetch:xml($contentPath,map { 'xinclude': false() })
|
|
let $rootNode := fn:name($doc/*)
|
|
return
|
|
if($rootNode!='book')
|
|
then <result><status>Failure</status><message>Content fails pre-ingestion check. DocBook format required only for content type {$ctype}.</message></result>
|
|
else
|
|
(:let $cid := if( fn:matches(fetch:xml($contentPath,map { 'xinclude': false() })/*/@xml:id/string(),'[a-zA-z-]'))
|
|
then fn:replace(fetch:xml($contentPath,map { 'xinclude': false() })/*/@xml:id/string(),'[a-zA-z-]','')
|
|
else fn:doc($contentPath)/*/@xml:id/string():)
|
|
let $cid := fn:doc($contentPath)/*/@xml:id/string()
|
|
|
|
return
|
|
if($cid)
|
|
then
|
|
if (
|
|
db:open($config:CoreDatabase,$config:JobDir)/job[job-info/cid/text()=$cid]
|
|
[job-info/job-type='Ingest']
|
|
[ingestion-report/status='InQueue']
|
|
or (db:list( blcommon:get-db-name($ctype),fn:concat($config:ContentDir,$cid,'/')))[1]
|
|
)
|
|
then
|
|
<result><status>Failure</status><message>The Content Id/s {$cid} is/are already ingested or in queue</message></result>
|
|
else
|
|
let $pid := contents:get-applied-ingest-pipeline($ctype,if(fn:ends-with(fn:lower-case($UploadFileName),'.xml')) then 'xml' else ())
|
|
return
|
|
if($pid)
|
|
then
|
|
(
|
|
let $jobChunk := <job>
|
|
<job-info>
|
|
<id>{$jobID}</id>
|
|
<cid>{$cid}</cid>
|
|
<pipeline-id>{$pid}</pipeline-id>
|
|
<pipeline-name>{db:open($config:CoreDatabase,$config:PipelineDir)/pipeline:pipeline[@id=$pid]/@name/string()}</pipeline-name>
|
|
<area>{$area}</area>
|
|
<job-type>Ingest</job-type>
|
|
<submitted-on>{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}</submitted-on>
|
|
<uploaded-file>{$contentPath}</uploaded-file>
|
|
<content-type>{$ctype}</content-type>
|
|
<content-format>
|
|
{
|
|
if(fn:ends-with(fn:lower-case($UploadFileName),'.xml'))
|
|
then 'xml'
|
|
else 'docx'
|
|
}
|
|
</content-format>
|
|
<ignore-validation>{$ignoreValidation}</ignore-validation>
|
|
<mail-required>{$sendMail}</mail-required>
|
|
<requester-id>{fn:substring-before(config:session-value($authorization),'$$$$')}</requester-id>
|
|
<requester-email>{fn:substring-after(config:session-value($authorization),'$$$$')}</requester-email>
|
|
<requester-name>{distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))][id=fn:substring-before(config:session-value($authorization),'$$$$')]/name)}</requester-name>
|
|
<location>{fn:concat($config:TempPipelineDir,$jobID)}</location>
|
|
</job-info>
|
|
<ingestion-report>
|
|
<steps/>
|
|
<status>InQueue</status>
|
|
<finished-on></finished-on>
|
|
</ingestion-report>
|
|
</job>
|
|
return db:add($config:CoreDatabase,$jobChunk,fn:concat($config:JobDir,$jobID,'.xml'))
|
|
,
|
|
<result><status>Success</status><message>Job created</message><jobid>{$jobID}</jobid></result>
|
|
)
|
|
else <result><status>Failure</status><message>Pipeline is not available.</message></result>
|
|
else <result><status>Failure</status><message>System error</message></result>
|
|
|
|
|
|
else if($ctype='screenplay')
|
|
then
|
|
if(fn:not(fn:ends-with($contentPath, '.docx')))
|
|
then <result><status>Failure</status><message>Content fails pre-ingestion check. docx format allowed only.</message></result>
|
|
else
|
|
let $cid := if(fn:ends-with(fn:lower-case($UploadFileName),'.docx'))
|
|
then fn:substring-before(fn:tokenize($UploadFileName,'/')[fn:last()],'.docx')
|
|
else ()
|
|
return
|
|
if($cid)
|
|
then
|
|
if (
|
|
db:open($config:CoreDatabase,$config:JobDir)/job[job-info/cid/text()=$cid]
|
|
[job-info/job-type='Ingest']
|
|
[ingestion-report/status='InQueue']
|
|
or (db:list( blcommon:get-db-name($ctype),fn:concat($config:ContentDir,$cid,'/')))[1]
|
|
)
|
|
then
|
|
<result><status>Failure</status><message>The Content Id/s {$cid} is/are already ingested or in queue</message></result>
|
|
else
|
|
let $pid := contents:get-applied-ingest-pipeline($ctype,if(fn:ends-with(fn:lower-case($UploadFileName),'.docx')) then 'docx' else ())
|
|
return
|
|
if($pid)
|
|
then
|
|
(
|
|
let $jobChunk := <job>
|
|
<job-info>
|
|
<id>{$jobID}</id>
|
|
<cid>{$cid}</cid>
|
|
<pipeline-id>{$pid}</pipeline-id>
|
|
<pipeline-name>{db:open($config:CoreDatabase,$config:PipelineDir)/pipeline:pipeline[@id=$pid]/@name/string()}</pipeline-name>
|
|
<area>{$area}</area>
|
|
<job-type>Ingest</job-type>
|
|
<submitted-on>{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}</submitted-on>
|
|
<uploaded-file>{$contentPath}</uploaded-file>
|
|
<content-type>{$ctype}</content-type>
|
|
<content-format>
|
|
{
|
|
if(fn:ends-with(fn:lower-case($UploadFileName),'.xml'))
|
|
then 'xml'
|
|
else 'docx'
|
|
}
|
|
</content-format>
|
|
<ignore-validation>{$ignoreValidation}</ignore-validation>
|
|
<mail-required>{$sendMail}</mail-required>
|
|
<requester-id>{fn:substring-before(config:session-value($authorization),'$$$$')}</requester-id>
|
|
<requester-email>{fn:substring-after(config:session-value($authorization),'$$$$')}</requester-email>
|
|
<requester-name>{distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))][id=fn:substring-before(config:session-value($authorization),'$$$$')]/name)}</requester-name>
|
|
<location>{fn:concat($config:TempPipelineDir,$jobID)}</location>
|
|
</job-info>
|
|
<ingestion-report>
|
|
<steps/>
|
|
<status>InQueue</status>
|
|
<finished-on></finished-on>
|
|
</ingestion-report>
|
|
</job>
|
|
return db:add($config:CoreDatabase,$jobChunk,fn:concat($config:JobDir,$jobID,'.xml'))
|
|
,
|
|
<result><status>Success</status><message>Job created</message><jobid>{$jobID}</jobid></result>
|
|
)
|
|
else <result><status>Failure</status><message>Pipeline is not available.</message></result>
|
|
else <result><status>Failure</status><message>System error</message></result>
|
|
else if($ctype='looseleaf')
|
|
then <result><status>Failure</status><message>Zip format required only for content type {$ctype}.</message></result>
|
|
else()
|
|
else <result><status>Failure</status><message>Content is not available or accessible from this location</message></result>
|
|
else <result><status>Failure</status><message>Uploaded content format is not supported. Please supply ZIP, DOCX or XML only</message></result>
|
|
}
|
|
</results>
|
|
};
|
|
(:~
|
|
: To schedule check-in job
|
|
: @param $body Paremeters to lock content into the system <checkin><role>Admin</role><uri></uri><uri></uri><upload-path></upload-path><ignore-validation>true</ignore-validation><mail>true</mail><comment></comment></checkin>
|
|
: <role> = Role of the user. Admin user can check-in another user check out files.
|
|
: <uri> = The uri of the files which has been selected to check-in (db uri), separated by '|', no space should present while joining by '|'
|
|
: <upload-path> = Selected content to upload (zip,word,xml)
|
|
: <ignore-validation> = program will ignore validation or not
|
|
: <mail> = mail indicator to send mail after check-in
|
|
: <comment> = check-in comment of the user
|
|
: @header $authorization Authorization key
|
|
: @return boolean
|
|
:)
|
|
declare %private %updating function JOBS:checkin-job(
|
|
$body as document-node(),
|
|
$authorization as xs:string
|
|
)
|
|
{
|
|
let $uri := $body/job/checkin/uri/text()
|
|
let $countUri := fn:count($body/job/checkin/uri)
|
|
let $ctype := $body/job/checkin/ctype/text()
|
|
let $allUri := fn:string-join(for $uri in $body/job/checkin/uri/text() return $uri, '|')
|
|
let $contentPath := fn:replace($body/job/checkin/upload-path/text(),'\\','/')
|
|
let $sendMail := $body/job/checkin/mail/text()
|
|
let $comment := $body/job/checkin/comment/text()
|
|
let $requesterRole := $body/job/checkin/role/text()
|
|
let $ignoreValidation := $body/job/checkin/ignore-validation/text()
|
|
let $sessionValue := config:session-value($authorization)
|
|
let $userID := fn:substring-before($sessionValue,'$$$$')
|
|
let $userEmail := fn:substring-after($sessionValue,'$$$$')
|
|
let $jobID := fn:concat($config:JobIDPrefix,fn:string(fn:format-dateTime(fn:current-dateTime(), '[Y0001][M01][D01][H01][m01][s01][f01]')))
|
|
let $checkoutVerify := JOBS:is-any-checkout($allUri,$userID)
|
|
let $checkUpload := JOBS:selected-vs-uploaded($checkoutVerify,$contentPath,$userID,$allUri,$ctype)
|
|
let $allUri := if(fn:contains($allUri,'|')) then fn:concat('(',$allUri,')') else $allUri
|
|
let $verfyzip := if(fn:ends-with($contentPath,'.zip'))
|
|
then
|
|
let $archive := file:read-binary($contentPath)
|
|
for $entries in archive:entries($archive)
|
|
let $filename := substring-before($entries/text(),'.xml')
|
|
return (if(fn:not(fn:contains($allUri,$filename)))
|
|
then 'false'
|
|
else ()
|
|
)
|
|
else()
|
|
return
|
|
try
|
|
{ (: verify the empty parameter :)
|
|
if($body/job//*[.=''])
|
|
then update:output(<result><status>Failure</status><message>Some parameter is empty. Please supply all the parameters.</message></result>)
|
|
else (: if selected content is multiple, user must supply zip folder to check-in :)
|
|
if(($ctype='play' or $ctype='monograph' or $ctype='screenplay') and (fn:ends-with($contentPath,'.zip') or fn:ends-with($contentPath,'.ZIP')) )
|
|
then update:output(<result><status>Failure</status><message>Zip not allowed for single check-in.</message></result>)
|
|
else
|
|
if(($countUri gt 1) and fn:not(fn:ends-with($contentPath,'.zip') or fn:ends-with($contentPath,'.ZIP')))
|
|
then update:output(<result><status>Failure</status><message>For multiple check-in send ZIP format only</message></result>)
|
|
else (: to verify uploaded content existence :)
|
|
if(file:exists($contentPath))
|
|
then (: verify the selected content is checked out or not by requester user, Admin user can perform action :)
|
|
if(($checkoutVerify/file[locked='yes'][locked-by/requester-id=$userID]) or (($requesterRole='Admin') and ($checkoutVerify/file[locked='yes'])))
|
|
then (: verify, is uploaded content has already checked-out content, if checked-out by other and user is Admin :)
|
|
if(($checkUpload/file[exist='yes'][locked-by/requester-id=$userID]) or (($requesterRole='Admin') and ($checkUpload/file[exist='yes'][locked-by])))
|
|
then
|
|
if(fn:ends-with($contentPath,'.zip') or fn:ends-with($contentPath,'.ZIP'))
|
|
then
|
|
if($verfyzip='false') then update:output(<result><status>Failure</status><message>some files are not part of this content please check zip.</message></result>)
|
|
(: header.xml not locked and available in zip to check-in :)
|
|
else if(fn:not(fn:contains($allUri,$config:HeaderXml)) and archive:entries(file:read-binary($contentPath))[fn:contains(.,$config:HeaderXml)])
|
|
then update:output(<result><status>Failure</status><message>header.xml is not checked-out/selected to check-in, but available in zip to check-in.</message></result>)
|
|
else
|
|
if(
|
|
(: Check header.xml locked :)
|
|
fn:contains($allUri,$config:HeaderXml)
|
|
or
|
|
(: Check header.xml not locked and not available in zip :)
|
|
(fn:not(fn:contains($allUri,$config:HeaderXml)) and archive:entries(file:read-binary($contentPath))[fn:not(fn:contains(.,$config:HeaderXml))])
|
|
)
|
|
then
|
|
let $cid := (: header.xml exists in zip :)
|
|
if(fn:contains($allUri,$config:HeaderXml) and archive:entries(file:read-binary($contentPath))[fn:contains(.,$config:HeaderXml)])
|
|
then
|
|
try
|
|
{
|
|
let $archive := file:read-binary($contentPath)
|
|
let $entry := archive:entries($archive)[fn:ends-with(., $config:HeaderXml)]
|
|
return fn:parse-xml(archive:extract-text($archive, $entry))/*/@xml:id/string()
|
|
}
|
|
catch *
|
|
{
|
|
let $archive := file:read-binary($contentPath)
|
|
let $entry := archive:entries($archive)[fn:ends-with(.,$config:HeaderXml)]
|
|
let $xml:= archive:extract-text($archive, $entry)
|
|
return fn:substring-before(fn:substring-after($xml,'xml:id="'),'"')
|
|
}
|
|
else
|
|
let $cid := fn:distinct-values
|
|
(
|
|
for $x in $body/job/checkin/uri/text()
|
|
return fn:tokenize($x,'/')[fn:position()=4]
|
|
)
|
|
return
|
|
if(fn:count($cid) eq 1) then $cid else 'ERROR'
|
|
return
|
|
if($cid!='ERROR')
|
|
then
|
|
let $coid := fn:concat($cid,'_',$cid)
|
|
let $infoXml := fn:doc(fn:concat(blcommon:get-db-name($ctype),$config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml))
|
|
let $area := $infoXml/info/area/text()
|
|
let $ctype := $infoXml/info/ctype/text()
|
|
let $sessionValue := config:session-value($authorization)
|
|
let $pid := contents:get-applied-ingest-pipeline($ctype,'zip')
|
|
return
|
|
if(db:list(blcommon:get-db-name($ctype),fn:concat($config:ContentDir,$cid))[1])
|
|
then
|
|
if($cid)
|
|
then
|
|
if(
|
|
db:open($config:CoreDatabase,$config:JobDir)/job[job-info/cid/text()=$cid]
|
|
[job-info/job-type='Checkin']
|
|
[ingestion-report/status='InQueue' or ingestion-report/status='InProgress']
|
|
[job-info/lock[some $uri in file/uri satisfies fn:matches(.,$allUri)]]
|
|
and (db:list(blcommon:get-db-name($ctype),fn:concat($config:ContentDir,$cid,'/')))[1]
|
|
)
|
|
then update:output(<result><status>Failure</status><message>This is already ingested or in queue</message></result>)
|
|
else
|
|
if($pid)
|
|
then
|
|
(
|
|
let $jobChunk := <job>
|
|
<job-info>
|
|
<id>{$jobID}</id>
|
|
<cid>{$cid}</cid>
|
|
<pipeline-id>{$pid}</pipeline-id>
|
|
<pipeline-name>{db:open($config:CoreDatabase,$config:PipelineDir)/pipeline:pipeline[@id=$pid]/@name/string()}</pipeline-name>
|
|
<area>{$area}</area>
|
|
<job-type>Checkin</job-type>
|
|
<comment>{$comment}</comment>
|
|
<submitted-on>{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}</submitted-on>
|
|
<uploaded-file>{$contentPath}</uploaded-file>
|
|
<content-type>{$ctype}</content-type>
|
|
<content-format>zip</content-format>
|
|
<ignore-validation>{$ignoreValidation}</ignore-validation>
|
|
<mail-required>{$sendMail}</mail-required>
|
|
<requester-id>{fn:substring-before(config:session-value($authorization),'$$$$')}</requester-id>
|
|
|
|
<requester-email>{distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))][id=fn:substring-before(config:session-value($authorization),'$$$$')]/email)}</requester-email>
|
|
<requester-name>{distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))][id=fn:substring-before(config:session-value($authorization),'$$$$')]/name)}</requester-name>
|
|
<location>{fn:concat($config:TempPipelineDir,$jobID)}</location>
|
|
{$checkUpload}
|
|
</job-info>
|
|
<ingestion-report>
|
|
<steps/>
|
|
<status>InQueue</status>
|
|
<finished-on></finished-on>
|
|
</ingestion-report>
|
|
</job>
|
|
return db:add($config:CoreDatabase,$jobChunk,fn:concat($config:JobDir,$jobID,'.xml'))
|
|
,
|
|
update:output(<result><status>Success</status><message>Job created</message><jobid>{$jobID}</jobid></result>)
|
|
)
|
|
else update:output(<result><status>Failure</status><message>Related pipeline is not available</message></result>)
|
|
else update:output(<result><status>Failure</status><message>System error</message></result>)
|
|
else update:output(<result><status>Failure</status><message>Please ingest this content before check-in</message></result>)
|
|
else update:output(<result><status>Failure</status><message>Multiple CID found to check-in.</message></result>)
|
|
else ()
|
|
else
|
|
if(fn:ends-with(fn:lower-case($contentPath),'.xml') or fn:ends-with(fn:lower-case($contentPath),'.docx'))
|
|
then
|
|
let $startedOn := fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))
|
|
let $CheckWelformed := let $ValidateDoc := validate:dtd-report($contentPath)
|
|
let $Report := <erros>
|
|
{
|
|
for $Message in $ValidateDoc/message[@level='Fatal']
|
|
return $Message
|
|
}
|
|
</erros>
|
|
return
|
|
<report>
|
|
{
|
|
<status>{if($Report//message/@level/string()='Fatal') then 'invalid' else ()}</status>,
|
|
$Report
|
|
}
|
|
</report>
|
|
|
|
|
|
return
|
|
if($CheckWelformed//status='invalid')
|
|
then
|
|
let $jobChunk := <job>
|
|
<job-info>
|
|
<id>{$jobID}</id>
|
|
<cid>{fn:replace(fn:tokenize(fn:replace($contentPath,'\\','/'),'/')[fn:last()],'[^0-9]', '')}</cid>
|
|
<pipeline-id></pipeline-id>
|
|
<pipeline-name></pipeline-name>
|
|
<area></area>
|
|
<job-type>Check-in</job-type>
|
|
<submitted-on>{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}</submitted-on>
|
|
<uploaded-file>{$contentPath}</uploaded-file>
|
|
<content-type>{$ctype}</content-type>
|
|
<content-format>
|
|
{
|
|
if(fn:ends-with(fn:lower-case($contentPath),'.xml'))
|
|
then 'xml'
|
|
else 'docx'
|
|
}
|
|
</content-format>
|
|
<ignore-validation>{$ignoreValidation}</ignore-validation>
|
|
<mail-required>{$sendMail}</mail-required>
|
|
<requester-id>{fn:substring-before(config:session-value($authorization),'$$$$')}</requester-id>
|
|
<requester-email>{fn:substring-after(config:session-value($authorization),'$$$$')}</requester-email>
|
|
<requester-name>{distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))][id=fn:substring-before(config:session-value($authorization),'$$$$')]/name)}</requester-name>
|
|
<location>{fn:concat($config:TempPipelineDir,$jobID)}</location>
|
|
</job-info>
|
|
<ingestion-report>
|
|
<steps>
|
|
<step>Wellformed:</step>
|
|
<started-on>{$startedOn}</started-on>
|
|
<location></location>
|
|
<completed-on>{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}</completed-on>
|
|
<errors>
|
|
{
|
|
$CheckWelformed//message
|
|
}
|
|
</errors>
|
|
</steps>
|
|
<status>Failure</status>
|
|
</ingestion-report>
|
|
</job>
|
|
return
|
|
(
|
|
db:add($config:CoreDatabase,$jobChunk,fn:concat($config:JobDir,$jobID,'.xml'))
|
|
,
|
|
<result><status>Success</status><message>Job created</message><jobid>{$jobID}</jobid></result>
|
|
)
|
|
else
|
|
let $coid := if(fn:ends-with(fn:lower-case($contentPath),$config:HeaderXml))
|
|
then
|
|
let $cid := try
|
|
{
|
|
fn:doc($contentPath)/*/@xml:id/string()
|
|
}
|
|
catch *
|
|
{
|
|
fetch:xml($contentPath,map { 'xinclude': false() })/*/@xml:id/string()
|
|
}
|
|
return fn:concat($cid,'_',$cid)
|
|
else
|
|
if(fn:ends-with(fn:lower-case($contentPath),'.docx'))
|
|
then
|
|
let $fileName := fn:replace(fn:tokenize($contentPath,'/')[fn:last()],'.docx','')
|
|
return fn:concat($fileName,'_',$fileName)
|
|
else
|
|
(:let $fileName := if (fn:contains(fn:substring-before(fn:tokenize($contentPath,'/')[fn:last()],'.xml'),'_txt_xml'))
|
|
then fn:replace( fn:substring-before(fn:tokenize($contentPath,'/')[fn:last()],'.xml') ,'_txt_xml','')
|
|
else fn:substring-before(fn:tokenize($contentPath,'/')[fn:last()],'.xml')
|
|
return fn:concat($fileName,'_',$fileName):)
|
|
if(($ctype='play') or ($ctype='monograph'))
|
|
then
|
|
|
|
let $cid := fn:doc($contentPath)/*/@xml:id/string()
|
|
return
|
|
fn:concat($cid,'_',$cid)
|
|
else
|
|
let $fileName := fn:replace(fn:tokenize($contentPath,'/')[fn:last()],'.xml','')
|
|
return fn:concat($fileName,'_',$fileName)
|
|
|
|
let $cid := if(fn:ends-with(fn:lower-case($contentPath),$config:HeaderXml))
|
|
then
|
|
try
|
|
{
|
|
fn:doc($contentPath)/*/@xml:id/string()
|
|
}
|
|
catch *
|
|
{
|
|
fetch:xml($contentPath,map { 'xinclude': false() })/*/@xml:id/string()
|
|
}
|
|
else if(fn:ends-with(fn:lower-case($contentPath),'.docx'))
|
|
then fn:tokenize((db:list( blcommon:get-db-name($ctype))[fn:contains(.,$coid)])[1],'/')[2]
|
|
else
|
|
try
|
|
{
|
|
fn:doc($contentPath)/*/@xml:id/string()
|
|
(:if( fn:matches(fn:doc($contentPath)/*/@xml:id/string(),'[a-zA-z-]'))
|
|
then fn:replace(fn:doc($contentPath)/*/@xml:id/string(),'[a-zA-z-]','')
|
|
else fn:doc($contentPath)/*/@xml:id/string():)
|
|
}
|
|
catch *
|
|
{
|
|
fetch:xml($contentPath,map { 'xinclude': false() })/*/@xml:id/string()
|
|
}
|
|
let $area := (db:open($config:CoreDatabase,$config:JobDir)/job/job-info[cid=$cid][job-type='Ingest']/area/text())[1]
|
|
let $ctype := (db:open($config:CoreDatabase,$config:JobDir)/job/job-info[cid=$cid][job-type='Ingest']/content-type/text())[1]
|
|
let $sessionValue := config:session-value($authorization)
|
|
let $pid := if(fn:ends-with(fn:lower-case($contentPath),'.docx'))
|
|
then contents:get-applied-ingest-pipeline($ctype,'docx')
|
|
else
|
|
if(fn:ends-with(fn:lower-case($contentPath),'.xml'))
|
|
then contents:get-applied-ingest-pipeline($ctype,'xml')
|
|
else ()
|
|
return
|
|
if(($cid and $coid) and (db:list(blcommon:get-db-name($ctype),fn:concat($config:ContentDir,$cid,'/',$coid))[1]))
|
|
then
|
|
if($pid)
|
|
then
|
|
if(
|
|
db:open($config:CoreDatabase,$config:JobDir)/job[job-info/cid/text()=$cid]
|
|
[job-info/job-type='Checkin']
|
|
[ingestion-report/status='InQueue' or ingestion-report/status='InProgress']
|
|
[job-info/lock[some $uri in file/uri satisfies fn:matches(.,$allUri)]]
|
|
and (db:list( blcommon:get-db-name($ctype),fn:concat($config:ContentDir,$cid,'/')))[1]
|
|
)
|
|
then update:output(<result><status>Failure</status><message>This is already ingested or in queue</message></result>)
|
|
else
|
|
if($cid)
|
|
then
|
|
(
|
|
let $jobChunk := <job>
|
|
<job-info>
|
|
<id>{$jobID}</id>
|
|
<cid>{$cid}</cid>
|
|
<pipeline-id>{$pid}</pipeline-id>
|
|
<pipeline-name>{db:open($config:CoreDatabase,$config:PipelineDir)/pipeline:pipeline[@id=$pid]/@name/string()}</pipeline-name>
|
|
<area>{$area}</area>
|
|
<job-type>Checkin</job-type>
|
|
<comment>{$comment}</comment>
|
|
<submitted-on>{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}</submitted-on>
|
|
<uploaded-file>{$contentPath}</uploaded-file>
|
|
<content-type>{$ctype}</content-type>
|
|
<content-format>
|
|
{
|
|
if(fn:ends-with(fn:lower-case($contentPath),'.xml'))
|
|
then 'xml'
|
|
else 'docx'
|
|
}
|
|
</content-format>
|
|
<ignore-validation>{$ignoreValidation}</ignore-validation>
|
|
<mail-required>{$sendMail}</mail-required>
|
|
<requester-id>{fn:substring-before(config:session-value($authorization),'$$$$')}</requester-id>
|
|
<requester-email>{distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))][id=fn:substring-before(config:session-value($authorization),'$$$$')]/email)}</requester-email>
|
|
<requester-name>{distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))][id=fn:substring-before(config:session-value($authorization),'$$$$')]/name)}</requester-name>
|
|
<location>{fn:concat($config:TempPipelineDir,$jobID)}</location>
|
|
{$checkUpload}
|
|
</job-info>
|
|
<ingestion-report>
|
|
<steps/>
|
|
<status>InQueue</status>
|
|
<finished-on></finished-on>
|
|
</ingestion-report>
|
|
</job>
|
|
return db:add($config:CoreDatabase,$jobChunk,fn:concat($config:JobDir,$jobID,'.xml'))
|
|
,
|
|
update:output(<result><status>Success</status><message>Job created</message><jobid>{$jobID}</jobid></result>)
|
|
)
|
|
else update:output(<result><status>Failure</status><message>System error</message></result>)
|
|
else update:output(<result><status>Failure</status><message>Related pipeline is not available</message></result>)
|
|
else
|
|
(
|
|
update:output(<result><status>Failure</status><message>Please ingest this content before checkin</message></result>)
|
|
)
|
|
else update:output(<result><status>Failure</status><message>Uploaded content format is not supported. Please supply ZIP, DOCX or XML only</message></result>)
|
|
else update:output(<result><status>Failure</status><message>Uploaded content do not have any checked-out content to check-in</message></result>)
|
|
else update:output(<result><status>Failure</status><message>Selected files are not checked-out or checked-out by others.</message></result>)
|
|
else update:output(<result><status>Failure</status><message>Content is not available or accessible from this location</message></result>)
|
|
}
|
|
catch *
|
|
{
|
|
|
|
admin:write-log("[Content Checkin][Error: " || $err:description || "]"),
|
|
admin:write-log("[Content Checkin][Error: " || $err:additional || "]"),
|
|
update:output(<result><status>Error</status><message>Error generated. Please check system log</message></result>)
|
|
}
|
|
|
|
};
|
|
|
|
(:~
|
|
: To publish a product
|
|
: @param $body <job><publish><product>$pid</product><ignore-validation>true</ignore-validation><mail>true</mail></publish></job>
|
|
: @header $authorization Authorization key
|
|
: @return element(result)
|
|
:)
|
|
declare %private %updating function JOBS:publish-job(
|
|
$body as document-node(),
|
|
$authorization as xs:string
|
|
)
|
|
{
|
|
let $productID := $body/job/publish/product/text()
|
|
let $ignoreValidation := $body/job/publish/ignore-validation/text()
|
|
let $sendMail := $body/job/publish/mail/text()
|
|
let $productXML := db:open($config:CoreDatabase,fn:concat($config:ProductDir,$productID,$config:LatestDir,$productID,'.xml'))
|
|
let $productTitle := $productXML/product:product/@name/string()
|
|
let $sessionValue := config:session-value($authorization)
|
|
let $userID := fn:substring-before($sessionValue,'$$$$')
|
|
let $userRole := db:open($config:CoreDatabase,fn:concat($config:UserDir,$userID,'.xml'))/user/role/text()
|
|
let $userEmail := fn:substring-after($sessionValue,'$$$$')
|
|
(:let $pipelineID := $productXML/product:product/@pipelineRef/string():)
|
|
let $taxonomyID := $productXML/product:product/@taxonomyRef/string()
|
|
let $assiginedManagers := let $managers := fn:string-join(
|
|
for $user in $productXML/product:product/product:managers/product:user/@id/string()
|
|
return $user
|
|
,'|')
|
|
return if(fn:contains($managers,'|')) then fn:concat('(',$managers,')') else $managers
|
|
(:let $jobID := fn:concat($config:JobIDPrefix,fn:string(fn:format-dateTime(fn:current-dateTime(), '[Y0001][M01][D01][H01][m01][s01][f01]'))):)
|
|
return
|
|
try
|
|
{ (: verify the empty parameter :)
|
|
if($body/job//*[.=''])
|
|
then update:output(<result><status>Failure</status><message>Some parameter is empty. Please supply all the parameters.</message></result>)
|
|
else (: verify the delete product :)
|
|
if($productXML/product:product[@delete])
|
|
then update:output(<result><status>Success</status><message>Product is deleted. You cannot publish it.</message></result>)
|
|
else (: check the requester has authority to publish :)
|
|
if(fn:not(fn:matches($userID,$assiginedManagers)) and $userRole!='admin')
|
|
then update:output(<result><status>Failure</status><message>You are not authorized to publish this product.</message></result>)
|
|
else
|
|
<results>
|
|
{
|
|
for $Content at $pos in $productXML/product:product/product:contents/product:content
|
|
let $PipelineID := $Content/@pipelineRef/string()
|
|
let $jobID := fn:concat($config:JobIDPrefix,fn:string(fn:format-dateTime(fn:current-dateTime(), '[Y0001][M01][D01][H01][m01][s01][f01]')),'-',$pos)
|
|
let $PipelineXML := db:open($config:CoreDatabase,$config:PipelineDir||$PipelineID||'.xml')
|
|
let $TaxonomyXML := fn:doc($config:CoreDatabase||$config:TaxonomyDir||$taxonomyID||'.xml')
|
|
let $TaxonomyName := $TaxonomyXML/*:taxonomy/@name/string()
|
|
let $CType := $Content/@sourceContentType/string()
|
|
let $CopyContent := (
|
|
|
|
let $steps := for $eachStep in $PipelineXML/*:pipeline/child::*/local-name()
|
|
return $eachStep
|
|
let $normalizedsteps := string-join($steps,'|')
|
|
return
|
|
if(fn:contains($normalizedsteps,'xquery'))
|
|
then
|
|
for $XquerySteps at $pos in $PipelineXML/*:pipeline/*:xquery
|
|
let $templocation := fn:concat($config:TempPipelineDir,$jobID,'/step-',$pos,'/')
|
|
return
|
|
if($pos eq 1)
|
|
then
|
|
(
|
|
file:create-dir($templocation)
|
|
,
|
|
file:create-dir(fn:concat($config:TempPipelineDir,$jobID,'/Publish/') )
|
|
,
|
|
JOBS:Copy-Content($Content,$templocation)
|
|
,
|
|
JOBS:Copy-Metadata($Content,$templocation)
|
|
,
|
|
JOBS:Copy-MetadataOnlyContent-metadata($Content,$templocation)
|
|
,
|
|
JOBS:Copy-MetaContent($PipelineXML,$templocation)
|
|
,
|
|
JOBS:Copy-Content-Management($Content,$templocation)
|
|
,
|
|
JOBS:Copy-Manifest($productID,$Content,$templocation)
|
|
,
|
|
JOBS:Copy-Taxonomy($TaxonomyXML,$templocation)
|
|
|
|
)
|
|
else if ($pos gt 1)
|
|
then
|
|
let $templocation := fn:concat($config:TempPipelineDir,$jobID,'/step-',$pos,'/input/')
|
|
return
|
|
file:create-dir($templocation)
|
|
else()
|
|
|
|
else
|
|
(
|
|
let $templocation := fn:concat($config:TempPipelineDir,$jobID,'/')
|
|
return
|
|
(
|
|
file:create-dir(fn:concat($config:TempPipelineDir,$jobID,'/Publish/') )
|
|
,
|
|
JOBS:Copy-Content($Content,$templocation)
|
|
,
|
|
JOBS:Copy-Metadata($Content,$templocation)
|
|
)
|
|
)
|
|
)
|
|
|
|
return
|
|
(
|
|
let $jobChunk := <job>
|
|
<job-info>
|
|
<id>{$jobID}</id>
|
|
<product-id>{$productID}</product-id>
|
|
<product-name>{$productTitle}</product-name>
|
|
<pipeline-id>{if($Content/@pipelineRef) then $Content/@pipelineRef/string() else 'Pipeline is not available'}</pipeline-id>
|
|
<pipeline-name>{db:open($config:CoreDatabase,$config:PipelineDir)/pipeline:pipeline[@id=$Content/@pipelineRef/string()]/@name/string()}</pipeline-name>
|
|
<taxonomy-id>{if($taxonomyID) then $taxonomyID else 'Taxonomy is not available'}</taxonomy-id>
|
|
<taxonomy-name>{db:open($config:CoreDatabase,$config:TaxonomyDir)/taxonomy[@id=$taxonomyID]/@name/string()}</taxonomy-name>
|
|
<job-type>Publish</job-type>
|
|
<submitted-on>{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}</submitted-on>
|
|
<ignore-validation>{$ignoreValidation}</ignore-validation>
|
|
<mail-required>{$sendMail}</mail-required>
|
|
<requester-id>{fn:substring-before($sessionValue,'$$$$')}</requester-id>
|
|
<requester-email>{fn:substring-after($sessionValue,'$$$$')}</requester-email>
|
|
<requester-name>{distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))][id=fn:substring-before(config:session-value($authorization),'$$$$')]/name)}</requester-name>
|
|
<location></location>
|
|
{JOBS:publish-info($Content)}
|
|
</job-info>
|
|
<ingestion-report>
|
|
<steps/>
|
|
<status>InQueue</status>
|
|
<finished-on></finished-on>
|
|
</ingestion-report>
|
|
</job>
|
|
return db:add($config:CoreDatabase,$jobChunk,fn:concat($config:JobDir,$jobID,'.xml'))
|
|
,
|
|
<result><status>Success</status><message>Job created</message><jobid>{$jobID}</jobid></result>
|
|
)
|
|
}</results>
|
|
}
|
|
catch *
|
|
{
|
|
admin:write-log("[Content Publish][Error: " || $err:description || "]"),
|
|
admin:write-log("[Content Publish][Error: " || $err:additional || "]"),
|
|
update:output(<result><status>Error</status><message>Error generated. Please check system log</message></result>)
|
|
}
|
|
};
|
|
|
|
(:~
|
|
: To collect publishable content information
|
|
: @param $productXML Product XML
|
|
: @return element(items)
|
|
:)
|
|
declare function JOBS:publish-info(
|
|
$ContentXML as node ()
|
|
) as element(items)
|
|
{
|
|
<items>
|
|
{
|
|
let $ContentTypeXML := fn:doc(fn:concat($config:CoreDatabase,$config:ContentType))
|
|
for $item in $ContentXML/*:item
|
|
let $itemTitle := $item/@title/string()
|
|
let $itemID := $item/@id/string()
|
|
let $ProductSourceCType := $ContentXML//@sourceContentType/string()
|
|
let $sourceCType := if($ContentTypeXML/*:controlledList/*:name[@xml:id/string()=$ProductSourceCType]/@referenceid)
|
|
then $ContentTypeXML/*:controlledList/*:name[@xml:id/string()=$ProductSourceCType]/@referenceid/string()
|
|
else $ContentTypeXML/*:controlledList/*:name[@xml:id/string()=$ProductSourceCType]/@xml:id/string()
|
|
|
|
|
|
let $itemInfo := for $uri in fn:uri-collection(fn:concat(blcommon:get-db-name($sourceCType),$config:ContentDir))[fn:contains(.,$itemID)]
|
|
[fn:contains(.,'/content/latest')]
|
|
[fn:not(fn:contains(.,$config:AuditFileName)
|
|
or fn:contains(.,$config:VersionControlFileName)
|
|
or fn:contains(.,$config:InfoXml)
|
|
or fn:contains(.,$config:VersionDir)
|
|
or fn:contains(.,$config:Metadata)
|
|
)]
|
|
let $isCheckedOut := db:open(blcommon:get-db-name($sourceCType),$config:LockDir)/locks/lock/files/file[uri=$uri]
|
|
let $cid := fn:substring-before(fn:substring-before(fn:substring-after($uri,$config:ContentDir),$config:ContentDir),'/')
|
|
let $coid := fn:substring-after(fn:substring-before(fn:substring-after($uri,$config:ContentDir),$config:ContentDir),'/')
|
|
let $auditUri := fn:concat(blcommon:get-db-name($sourceCType),$config:ContentDir,$cid,'/',$coid,'/',$config:AuditFileName)
|
|
let $version := let $versionUri := fn:replace($auditUri,$config:AuditFileName,$config:VersionControlFileName)
|
|
return
|
|
if(fn:doc-available($versionUri))
|
|
then
|
|
let $versionXml := fn:doc($versionUri)
|
|
let $version := $versionXml/versions/version[@uri=$uri]/@number/string()
|
|
return
|
|
if($version)
|
|
then $version
|
|
else fn:sum(fn:max($versionXml/versions/version/@number) + 1)
|
|
else 1
|
|
return
|
|
<item>
|
|
<source-type>{$sourceCType}</source-type>
|
|
<uri>{$uri}</uri>
|
|
<checkout>{if($isCheckedOut) then 'true' else 'false'}</checkout>
|
|
<version>{$version}</version>
|
|
</item>
|
|
return $itemInfo
|
|
}
|
|
</items>
|
|
};
|
|
|
|
(:~
|
|
: To check from supplied anything is checked-out
|
|
: @param $uri The uri of the files which has been selected to check-in (db uri)
|
|
: @param $userID Current User ID who wants to check-in
|
|
: @return element(lock)
|
|
:)
|
|
declare %private function JOBS:is-any-checkout(
|
|
$uri as xs:string,
|
|
$userID as xs:string
|
|
) as element(lock)
|
|
{
|
|
<lock>
|
|
{
|
|
let $lockDoc := db:open($config:CoreDatabase,fn:concat($config:LockDir,$userID,'.xml'))
|
|
for $eachUri in fn:tokenize($uri,'\|')
|
|
return
|
|
<file>
|
|
{ (: check in same user lock first :)
|
|
if($lockDoc/locks/lock/files[file/uri=$eachUri])
|
|
then
|
|
(
|
|
<locked>yes</locked>,
|
|
<uri>{$lockDoc/locks/lock/files/file[uri=$eachUri]/uri/text()}</uri>,
|
|
<previous-version>{$lockDoc/locks/lock/files/file[uri=$eachUri]/version/text()}</previous-version>,
|
|
<latest-version>{fn:sum($lockDoc/locks/lock/files/file[uri=$eachUri]/version/text()+1)}</latest-version>,
|
|
<locked-by>
|
|
<requester-id>{$userID}</requester-id>
|
|
<requester-email>{$lockDoc/locks/lock[files/file/uri=$eachUri]/requester-email/string()}</requester-email>
|
|
<locked-by>Self</locked-by>
|
|
</locked-by>
|
|
)
|
|
else (: if not available, check with other user lock :)
|
|
let $lockDoc := db:open($config:CoreDatabase,$config:LockDir)/locks[lock/files/file/uri=$eachUri]
|
|
return
|
|
if($lockDoc)
|
|
then
|
|
(
|
|
<locked>yes</locked>,
|
|
<uri>{$lockDoc/lock/files/file[uri=$eachUri]/uri/text()}</uri>,
|
|
<previous-version>{$lockDoc/lock/files/file[uri=$eachUri]/version/text()}</previous-version>,
|
|
<latest-version>{fn:sum($lockDoc/lock/files/file[uri=$eachUri]/version/text()+1)}</latest-version>,
|
|
<locked-by>
|
|
<requester-id>{$lockDoc/lock[files/file/uri=$eachUri]/requester-id/text()}</requester-id>
|
|
<requester-email>{$lockDoc/locks/lock[files/file/uri=$eachUri]/requester-email/string()}</requester-email>
|
|
<locked-by>Other</locked-by>
|
|
</locked-by>
|
|
)
|
|
else
|
|
(
|
|
<locked>no</locked>,
|
|
<uri>{$eachUri}</uri>
|
|
)
|
|
}
|
|
</file>
|
|
}
|
|
</lock>
|
|
};
|
|
|
|
|
|
|
|
(:~
|
|
: To check checked-out is in the attached (zip,word,xml) or not
|
|
: @param $checkOutInfo locking information chunk
|
|
: @param $contentPath Upload path (zip,word,xml)
|
|
: @param $userID Current User ID who wants to check-in
|
|
: @@param $allUri The uri of the files which has been selected to check-in
|
|
: @return element(lock)
|
|
:)
|
|
declare %private function JOBS:selected-vs-uploaded(
|
|
$checkOutInfo as element(lock),
|
|
$contentPath as xs:string,
|
|
$userID as xs:string,
|
|
$allUri as xs:string,
|
|
$ctype as xs:string
|
|
) as element(lock)
|
|
{
|
|
<lock>
|
|
{
|
|
if(fn:ends-with($contentPath,'.zip') or fn:ends-with($contentPath,'.ZIP'))
|
|
then
|
|
for $entry in archive:entries(file:read-binary($contentPath))
|
|
let $checkoutFiles := let $join := fn:string-join(for $chckoutFile in $checkOutInfo/file[locked='yes']/uri
|
|
return fn:tokenize($chckoutFile,'/')[fn:last()], '|')
|
|
return if(fn:contains($join,'|')) then fn:concat('(',$join,')') else if($join) then $join else 'NONE'
|
|
return
|
|
if(fn:matches(fn:replace($entry/text(),'.docx','.xml'),$checkoutFiles))
|
|
then
|
|
<file>
|
|
<exist>yes</exist>
|
|
<selected-to-checkin>yes</selected-to-checkin>
|
|
{
|
|
let $checkoutInfo := $checkOutInfo/file[locked='yes']
|
|
[fn:tokenize(uri,'/')[fn:last()]=fn:replace($entry/text(),'.docx','.xml')]
|
|
return
|
|
(
|
|
$checkoutInfo/locked-by,
|
|
$checkoutInfo/uri,
|
|
$checkoutInfo/previous-version,
|
|
$checkoutInfo/latest-version
|
|
)
|
|
}
|
|
</file>
|
|
else
|
|
(: to find out new content into the zip to upload into the system :)
|
|
let $cid := (: header.xml exists in zip :)
|
|
if(fn:contains($allUri,$config:HeaderXml) and archive:entries(file:read-binary($contentPath))[fn:contains(.,$config:HeaderXml)])
|
|
then
|
|
try
|
|
{
|
|
let $archive := file:read-binary($contentPath)
|
|
let $entry := archive:entries($archive)[fn:ends-with(., $config:HeaderXml)]
|
|
return fn:parse-xml(archive:extract-text($archive, $entry))/*/@xml:id/string()
|
|
}
|
|
catch *
|
|
{
|
|
let $archive := file:read-binary($contentPath)
|
|
let $entry := archive:entries($archive)[fn:ends-with(.,$config:HeaderXml)]
|
|
let $xml:= archive:extract-text($archive, $entry)
|
|
return fn:substring-before(fn:substring-after($xml,'xml:id="'),'"')
|
|
}
|
|
else
|
|
let $cid := fn:distinct-values
|
|
(
|
|
for $x in fn:tokenize($allUri,'\|')
|
|
return fn:tokenize($x,'/')[fn:position()=4]
|
|
)
|
|
return
|
|
if(fn:count($cid) eq 1) then $cid else 'ERROR'
|
|
return
|
|
(:if((fn:uri-collection($config:Database)[fn:contains(.,fn:replace($entry/text(),'.docx','.xml'))])[1]):)
|
|
if(
|
|
db:list(blcommon:get-db-name($ctype),fn:concat($config:ContentDir,$cid))[fn:contains(.,'/content/latest/')]
|
|
[fn:not(fn:contains(.,$config:WordDir))]
|
|
[fn:ends-with(.,fn:replace($entry/text(),'.docx','.xml'))]
|
|
)
|
|
then
|
|
<file>
|
|
<exist>yes</exist>
|
|
<selected-to-checkin>no</selected-to-checkin>
|
|
<uri>{$entry/text()}</uri>
|
|
</file>
|
|
else
|
|
<file>
|
|
<exist>yes</exist>
|
|
<selected-to-checkin>New Content</selected-to-checkin>
|
|
<locked-by><locked-by>None</locked-by></locked-by>
|
|
<uri>{$entry/text()}</uri>
|
|
<latest-version>1</latest-version>
|
|
</file>
|
|
else
|
|
if(fn:ends-with($contentPath,'.xml'))
|
|
then
|
|
let $uploadedFileName := fn:tokenize($contentPath,'/')[fn:last()]
|
|
return
|
|
if($checkOutInfo/file[locked='yes'][fn:contains(uri,$uploadedFileName)])
|
|
then
|
|
<file>
|
|
<exist>yes</exist>
|
|
<selected-to-checkin>yes</selected-to-checkin>
|
|
<uri>{$checkOutInfo/file[locked='yes'][fn:contains(uri,$uploadedFileName)]/uri/text()}</uri>
|
|
{
|
|
let $checkoutInfo := $checkOutInfo/file[locked='yes']
|
|
[fn:tokenize(uri,'/')[fn:last()]=$uploadedFileName]
|
|
return
|
|
(
|
|
$checkoutInfo/locked-by,
|
|
$checkoutInfo/previous-version,
|
|
$checkoutInfo/latest-version
|
|
)
|
|
}
|
|
</file>
|
|
else ()
|
|
else
|
|
if(fn:ends-with($contentPath,'.docx'))
|
|
then
|
|
let $uploadedFileName := fn:replace(fn:tokenize($contentPath,'/')[fn:last()],'.docx','.xml')
|
|
return
|
|
if($checkOutInfo/file[locked='yes'][fn:contains(uri,$uploadedFileName)])
|
|
then
|
|
<file>
|
|
<exist>yes</exist>
|
|
<selected-to-checkin>yes</selected-to-checkin>
|
|
<uri>{$checkOutInfo/file[locked='yes'][fn:contains(uri,$uploadedFileName)]/uri/text()}</uri>
|
|
{
|
|
let $checkoutInfo := $checkOutInfo/file[locked='yes']
|
|
[fn:tokenize(uri,'/')[fn:last()]=fn:replace($uploadedFileName,'.docx','.xml')]
|
|
return
|
|
(
|
|
$checkoutInfo/locked-by,
|
|
$checkoutInfo/previous-version,
|
|
$checkoutInfo/latest-version
|
|
)
|
|
}
|
|
</file>
|
|
else ()
|
|
else ()
|
|
}
|
|
</lock>
|
|
};
|
|
|
|
declare %updating function JOBS:Copy-MetaContent(
|
|
$PipelineXml as document-node(),
|
|
$XQuerySteptempLocation as xs:string
|
|
)
|
|
{
|
|
for $MetadataType in $PipelineXml/*:pipeline/*:xquery/*:requires/@metadataType/string()
|
|
|
|
return
|
|
(
|
|
if($MetadataType='onix')
|
|
then
|
|
let $templocation := fn:concat($XQuerySteptempLocation,$MetadataType)
|
|
for $Uri in fn:uri-collection(fn:concat($config:OnixDB,'/',$MetadataType))
|
|
let $filename := fn:tokenize($Uri,'/')[fn:last()]
|
|
let $modifiedFilename := if( fn:ends-with($filename,'.xml')) then $filename else fn:concat($filename,'.xml')
|
|
return
|
|
(
|
|
file:create-dir($templocation),
|
|
file:write(fn:concat($templocation,'/',$modifiedFilename),fn:doc($Uri))
|
|
)
|
|
else
|
|
let $templocation := fn:concat($XQuerySteptempLocation,$MetadataType)
|
|
for $Uri in fn:uri-collection(fn:concat($config:MetadataOnlyContentDatabase,'/',$MetadataType))
|
|
let $filename := fn:tokenize($Uri,'/')[fn:last()]
|
|
return
|
|
(
|
|
file:create-dir($templocation),
|
|
file:write(fn:concat($templocation,'/',$filename),fn:doc($Uri))
|
|
)
|
|
)
|
|
};
|
|
|
|
|
|
declare %updating function JOBS:Copy-Content(
|
|
$Content as node(),
|
|
$XQuerySteptempLocation as xs:string
|
|
)
|
|
{
|
|
let $ContentType := $Content/@sourceContentType/string()
|
|
let $DbCollection := if (
|
|
$ContentType = "person" or $ContentType = "audio" or
|
|
$ContentType = "video" or $ContentType = "organisation" or
|
|
$ContentType = "image" or $ContentType = "series" or
|
|
$ContentType = "publisher"
|
|
)
|
|
then ($config:MetadataOnlyContentDatabase||'/'||$ContentType)
|
|
else if($ContentType = "reference" or $ContentType = "monograph")
|
|
then ($config:MonographDatabase||'/content/')
|
|
else if($ContentType = "play")
|
|
then ($config:playDatabase||'/content/')
|
|
else $ContentType
|
|
for $cid in $Content/*:item/@id/string()
|
|
for $DocUri in fn:uri-collection($DbCollection)[fn:contains(.,$cid)][fn:not(contains(.,$config:InfoXml) or contains(.,'version.xml'))]
|
|
[if($ContentType = 'play' or $ContentType = 'monograph' or $ContentType = 'reference')
|
|
then fn:contains(.,'/latest/')
|
|
else .
|
|
]
|
|
let $filename := fn:tokenize($DocUri,'/')[fn:last()]
|
|
let $templocation := fn:concat($XQuerySteptempLocation,'content/',$ContentType,'/',$cid)
|
|
return
|
|
(
|
|
file:create-dir($templocation),
|
|
file:write(fn:concat($templocation,'/',$filename),fn:doc($DocUri))
|
|
(:,
|
|
file:create-dir(fn:concat($XQuerySteptempLocation,'Publish/') ):)
|
|
)
|
|
|
|
|
|
};
|
|
|
|
declare %updating function JOBS:Copy-Manifest(
|
|
$ProductID as xs:string,
|
|
$Content as node(),
|
|
$XQuerySteptempLocation as xs:string
|
|
)
|
|
{
|
|
let $templocation := fn:concat($XQuerySteptempLocation,'manifest/')
|
|
return
|
|
(
|
|
file:create-dir($templocation),
|
|
file:write(fn:concat($templocation,'/',$ProductID,'.xml'),$Content)
|
|
)
|
|
};
|
|
|
|
|
|
declare %updating function JOBS:Copy-Content-Management(
|
|
$Content as node(),
|
|
$XQuerySteptempLocation as xs:string
|
|
)
|
|
{
|
|
for $cid in $Content/*:item/@id/string()
|
|
for $ContentManagementUri in fn:uri-collection(fn:concat($config:ContentManagementDatabase,$config:ContentManagementCollection))[contains(.,$cid)]
|
|
let $DocId := fn:doc($ContentManagementUri)/*/@id/string()
|
|
let $filename := fn:tokenize($ContentManagementUri,'/')[fn:last()]
|
|
let $templocation := fn:concat($XQuerySteptempLocation,$config:ContentManagementDatabase,'/',$DocId)
|
|
return
|
|
(
|
|
file:create-dir($templocation),
|
|
file:write(fn:concat($templocation,'/',$filename),fn:doc($ContentManagementUri))
|
|
)
|
|
};
|
|
|
|
declare %updating function JOBS:Copy-Taxonomy(
|
|
$TaxonomyXML as document-node(),
|
|
$XQuerySteptempLocation as xs:string
|
|
)
|
|
{
|
|
let $TaxonomyName := $TaxonomyXML/*:taxonomy/@name/string()
|
|
let $templocation := fn:concat($XQuerySteptempLocation,'taxonomy/')
|
|
return
|
|
(
|
|
file:create-dir($templocation),
|
|
file:write($templocation||$TaxonomyName||'.xml',$TaxonomyXML)
|
|
)
|
|
};
|
|
|
|
declare %updating function JOBS:Copy-Metadata(
|
|
$Content as element(product:content),
|
|
$TempLocation as xs:string
|
|
)
|
|
{
|
|
let $ctype := $Content/@sourceContentType/string()
|
|
let $MetaDataCollection := if ($ctype = 'monograph' or $ctype = 'reference')
|
|
then
|
|
($config:ContentMetadataDatabse||'/'||$config:MonographDatabase||$config:ContentDir)
|
|
else if ($ctype = 'play')
|
|
then
|
|
($config:ContentMetadataDatabse||'/'||$config:playDatabase||$config:ContentDir)
|
|
else if (
|
|
$ctype = "person" or $ctype = "audio" or
|
|
$ctype = "video" or $ctype = "organisation" or
|
|
$ctype = "image" or $ctype = "series" or
|
|
$ctype = "publisher"
|
|
)
|
|
then
|
|
($config:ContentMetadataDatabse||'/'||$ctype)
|
|
|
|
let $PipelineId := $Content/@pipelineRef/string()
|
|
for $cid in $Content/*:item/@id/string()
|
|
for $MetaUri in fn:uri-collection($MetaDataCollection)[contains(.,$cid)][fn:contains(.,'latest')][if(
|
|
$ctype = "person" or $ctype = "audio" or
|
|
$ctype = "video" or $ctype = "organisation" or
|
|
$ctype = "image" or $ctype = "series" or
|
|
$ctype = "publisher"
|
|
) then fn:contains(.,'classify.xml') else .]
|
|
let $filename := fn:tokenize($MetaUri,'/')[fn:last()]
|
|
let $templocation := fn:concat($TempLocation,'metadata/')
|
|
return
|
|
if(file:is-dir($templocation))
|
|
then
|
|
(
|
|
file:write(fn:concat($templocation,'/',$filename),fn:doc($MetaUri))
|
|
)
|
|
else
|
|
(
|
|
file:create-dir($templocation),
|
|
file:write(fn:concat($templocation,'/',$filename),fn:doc($MetaUri))
|
|
|
|
)
|
|
};
|
|
|
|
declare %updating function JOBS:Copy-MetadataOnlyContent-metadata(
|
|
$Content as element(product:content),
|
|
$TempLocation as xs:string
|
|
)
|
|
{
|
|
let $PipelineId := $Content/@pipelineRef/string()
|
|
let $PipelineXml := db:open($config:CoreDatabase,$config:PipelineDir||'/'||$PipelineId||'.xml')
|
|
for $RequiresContentType in $PipelineXml/*:pipeline/*:xquery/*:requires/@metadataType/string()
|
|
return
|
|
if($RequiresContentType!='')
|
|
then
|
|
let $DbCollection := db:open($config:MetadataOnlyContentDatabase,$RequiresContentType)/*
|
|
for $Docid in $DbCollection/@id/string()
|
|
for $ClassifyUrl in db:open($config:ContentMetadataDatabse,$RequiresContentType)/*:taxonomies[@cid/string()=$Docid]/base-uri()[fn:contains(.,$config:ClassifyXml)]
|
|
[fn:contains(.,'/latest/')]
|
|
let $filename := fn:tokenize($ClassifyUrl,'/')[fn:last()]
|
|
let $templocation := fn:concat($TempLocation,'metadata/')
|
|
return
|
|
if(file:is-dir($templocation))
|
|
then
|
|
(
|
|
file:write(fn:concat($templocation,'/',$filename),fn:doc($ClassifyUrl))
|
|
)
|
|
else
|
|
(
|
|
file:create-dir($templocation),
|
|
file:write(fn:concat($templocation,'/',$filename),fn:doc($ClassifyUrl))
|
|
)
|
|
else()
|
|
|
|
};
|
|
|
|
(:~ Return error message to the UI if authentication fails :)
|
|
declare
|
|
%rest:error("JOBS:job-error")
|
|
%rest:error-param("description", "{$message}")
|
|
function JOBS:job-error($message)
|
|
{
|
|
fn:error()
|
|
}; |