Skip to content

Instantly share code, notes, and snippets.

@pinus
Created May 18, 2020 04:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pinus/ed34977438db048721f9e79d34f91b5a to your computer and use it in GitHub Desktop.
Save pinus/ed34977438db048721f9e79d34f91b5a to your computer and use it in GitHub Desktop.

dzd100

Ruby script to periodically download newly added images from DZ-D100.

#!/usr/bin/ruby
# frozen_string_literal: true
require 'net/http'
require 'rexml/document'
require 'fileutils'
require 'logger'
@logger = Logger.new(STDOUT)
@logger.level = Logger::DEBUG
HOST = 'http://dzd100-address'
HOME = '/pub'
DZD100_ROOT = HOME + '/dzd100'
DOCUMENTS_ROOT = HOME + '/documents'
EXIFTOOL_COMMAND = 'exiftool -MakerNotes:Casio_Type2_0x311f -s -s -s -u -'
SLEEP = 10 # wait seconds to retry
#
# DZ-D100 api
#
SESSION_OPEN = '/casio_dc.cgi?cmd=SessionOpen&arg=0'
SESSION_CLOSE = '/casio_dc.cgi?cmd=SessionClose'
CHECK_CONNECTION = '/casio_dc.cgi?cmd=CheckConnection'
GET_FILE_LIST = '/casio_dc.cgi?cmd=GetFileList&arg=All'
GET_FILE_INFO = '/casio_dc.cgi?cmd=GetFileInfo&arg=%s' # %s = file name
GET_IMAGE = '/casio_dc.cgi?data=%s&arg=Original' # %s = file name
#
# open dzd100 session
#
def open_session
Net::HTTP.get(URI.parse(HOST + SESSION_OPEN))
end
#
# get image from dzd100
#
def get_image(file)
Net::HTTP.get(URI.parse(HOST + GET_IMAGE % file))
end
#
# get concatenated xml from dzd100 and slplit it into array of xmls
#
def file_list_xmls
concatenated_xml = Net::HTTP.get(URI.parse(HOST + GET_FILE_LIST))
concatenated_xml.split(/<\?xml .*\?>/)
end
#
# returns array of file paths
#
def filepath_list
filepath_list = []
file_list_xmls.each do |xml|
doc = REXML::Document.new(xml)
result = doc.elements['//ccma/output/result']
next if result.nil? || result.text != 'OK'
doc.elements.each('//ccma/output/operation/argument/value') do |val|
filepath_list << val.text
end
end
filepath_list
end
#
# get patient number by exif
#
def get_patient_number(image)
IO.popen(EXIFTOOL_COMMAND, 'r+') do |io|
io.puts image
io.close_write
io.gets.chomp!
end
end
#
# get corresponding document directory for pt_num
#
def get_document_dir(pt_num)
# decrement pt_num to make the job easy
tmp_num = format('%06d', pt_num.to_i - 1)
# 1st branch
d4 = tmp_num[0, 2].to_i
br1 = format('%02d0001-%02d0000', d4, d4 + 1)
# 2nd branch
d3 = tmp_num[0, 3].to_i
br2 = format('%03d001-%03d000', d3, d3 + 1)
# path
[DOCUMENTS_ROOT, br1, br2, pt_num].join('/')
end
#
# save image to designated file
#
def save_image_to_file(filepath, image)
dirname = File.dirname(filepath)
FileUtils.mkdir_p(dirname) unless File.exist?(dirname)
File.open(filepath, 'wb').write(image)
@logger.info('write ' + filepath)
end
#
# download image to local HOME
#
def download(filepath)
# download image from dzd100
image = get_image(filepath)
# save image to local HOME
save_image_to_file(DZD100_ROOT + filepath, image)
# save image also to documents folder
pt_num = get_patient_number(image)
return if pt_num.nil?
doc_dir = get_document_dir(pt_num)
filename = doc_dir + '/' + File.basename(filepath)
save_image_to_file(filename, image)
end
#
# main
#
@logger.info("start #{__FILE__}")
Net::HTTP.version_1_2
loop do
begin
open_session
filepath_list.each do |filepath|
# skip if locally present
next if File.exist?(DZD100_ROOT + filepath)
download(filepath)
end
rescue => e
@logger.debug(e.message)
end
@logger.info(format('sleep %<sec>d sec', sec: SLEEP))
sleep SLEEP
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment