I think i’ve answered my own question here…
Here is an LUA script that queries a RIS to see if an accessionnumber exsits before passing the images on.
- Obviously, the query function and query itself would need to be adjusted for each RIS.
-It creates a temporary cache (with timeout) of prior queries to prevent multiple RIS queries in the event of CT’s etc
-Any images NOT passed on are held and can be viewed/resent in Orthanc, but are deleted if RIS is sorted out and images re-sent.
- i’ve left a lot of the logging in for now so that i can work out what functions are being called etc etc.
No guarantee on the quality of this code, but it works for me. Hope this helps someone.
`
—Set location of Cache text file to hold RIS query results
cachefile=“c:/Orthanc/Plug/CheckRIS/CheckRIS_CacheFile.txt”
–Set a timeout for subsequent image send events (prevents multiple RIS queries in the event of things like CT slices etc)
querytimeout=60
function OnStoredInstance(instanceId, tags, metadata, remoteAet, calledAet)
function file_check(file_name)
local file_found=io.open(file_name, “r”)
if file_found==nil then
io.open(cachefile,“w”)
io.close()
else
end
end
function sleep(sec)
local ntime = os.time() + sec
repeat until os.time() > ntime
end
function writetocache(accn,status)
ts = os.date(‘%Y%m%d %H%M%S’, os.time())
fh,err = io.open(cachefile,“a”)
fh:write(“\n”)
fh:write(accn …" " … status … " " … ts)
end
function updatecache(accn,status)
s=‘’
newfile=‘’
newline=‘’
tm = os.date(‘%Y%m%d %H%M%S’, os.time())
f = io.open (cachefile,“r”)
repeat
s = f:read (“*l”) – read one line
if s then – if not end of file (EOF)
if string.find(s,accn…" “) then
newline = string.gsub(s, s, accn…” “…status…” “…tm)
else
newline = s
end
newfile = newfile…newline…”\n"
end
until not s
f:close ()
f = io.open (cachefile,“w+”)
f:write(newfile:sub(1,#newfile-1))
sleep(2)
io.close(f)
end
function queryRIS(accn)
–Create and execute an SQL query on RIS to check if placeholder exists down stream. SQL query should return Passthrough1 if yes, Passthrough0 if no.
qry,err = io.open(“c:/orthanc/plug/CheckRIS/CheckRIS_Query.sql”,“w “)
qry:write(“SET HEADING OFF \nSET TRIMOUT ON \nSET HEADING OFF \n SET PAGESIZE 0 \nSET TRIMSPOOL ON \nSET NEWPAGE NONE \nSELECT ‘Passthrough’ || TRIM(COUNT(ACCESSIONNUMBER)) AS T FROM USER.EXAMRECORD WHERE ACCESSIONNUMBER LIKE '”…accn…”';”)
qry:close()
n = os.tmpname ()
os.execute (“echo EXIT | C:\oracleinstantclient\sqlplus -s USERNAME/PASSWORD@DATASOURCE @c:/orthanc/plug/CheckRIS/CheckRIS_Query.sql >” … n)
status=‘’
–Check SQL query result
for sqlline in io.lines(n) do
if string.find(sqlline,‘Passthrough1’) then
status=‘allowed’
print(“queryRIS says SEND SOMEIMAGES”)
return(status)
elseif string.find(sqlline,‘Passthrough0’) then
status=‘deny’
print(“queryRIS says DONT SEND SOMEIMAGES”)
return(status)
else
status=‘deny’
print(“SQLPLUS Query is not happening”)
return(status)
end
end
os.remove (n)
end
function sendimages(accn)
print("sendimages says SEND THIS IMAGE - "…instanceId)
Delete(SendToModality(instanceId, ‘TestDestination’, remoteAet))
end
function deleteimages(accn)
print(“Holding Images - goto WebViewer to view - http://orthancserver:8042”)
end
function checkRIS(accn)
if queryRIS(accn) == ‘allowed’ then
print(‘checkRIS found something - SEND SOME IMAGES’)
writetocache(accn,‘allowed’)
sendimages(accn)
else
print(‘checkRIS didnt find anything - DONT SEND SOME IMAGES’)
writetocache(accn,‘deny’)
sleep(3)
deleteimages(accn)
end
end
function recheckRIS(accn)
if queryRIS(accn) ==‘allowed’ then
print(‘reckeckRIS found something - SEND SOME IMAGES’)
updatecache(accn,‘allowed’)
sendimages(accn)
else
print(‘recheckRIS didnt find anything - DONT SEND SOME IMAGES’)
updatecache(accn,‘deny’)
deleteimages(accn)
end
end
function foundallowed(accn)
print(“found in cache and allowed - send some images (foundandallowed)”)
sendimages(accn)
end
function foundnotallowed(accn)
print(“found and denied - dont send images (foundandnotallowed)”)
deleteimages(accn)
end
function secdiff(line)
local lineyr=string.sub(line,-15,-12)
local linemt=string.sub(line,-11,-10)
local linedy=string.sub(line,-9,-7)
local linehh=string.sub(line,-6,-5)
local linemm=string.sub(line,-4,-3)
local liness=string.sub(line,-2)
local convertedTimestamp = os.time({year = lineyr, month = linemt, day = linedy, hour = linehh, min = linemm, sec = liness})
now = os.time()
timeDifference = now - convertedTimestamp
return (timeDifference)
end
function search(accn)
file_check(cachefile)
status = ‘’
fh,err = io.open(cachefile)
if err then print(“Cant open cache file”); return; end
while true do
line = fh:read()
if line == nil then
print(“Not found in cached log - goto checkRIS”)
checkRIS(accn)
break end
if string.find(line,accn…" “) and string.find(line,“allowed”) then
print(“Found in cached log and allowed - goto foundallowed”)
foundallowed(accn)
break
elseif string.find(line,accn…” “) and string.find(line,“deny”) and secdiff(line) > querytimeout then
print(“Denied in cache log, but old, re-check - goto recheckRIS”)
recheckRIS(accn)
break
elseif string.find(line,accn…” “) and string.find(line,“deny”) and secdiff(line) < querytimeout then
print(“Denied in cache log not long ago - goto foundnotallowed”)
foundnotallowed(accn)
break
elseif string.find(line,accn…” ") and not (string.find(line,“deny”) or string.find(line,“allowed”)) then
print(“Partially found in cache log, re-check - goto recheckRIS”)
recheckRIS(accn)
break
end
end
fh:close()
end
if tags[‘AccessionNumber’] == ‘’ or tags[‘AccessionNumber’] == nil then
accn = ‘empty’ else
accn = tags[‘AccessionNumber’]
end
print(“________________________________________START INSTANCE “…accn…”___________________________________”)
search(accn)
end
`
Ultimately i’d like to do something similar to prevent Orthanc accepting the images in the first place (so the user knows they’ve been rejected), but haven’t worked that bit out yet.