python による dicom サーバー — クライアント側

ubuntu 18.04 desktop 上で python によって dicom ファイルを処理し、そのタグ情報によって自前のディレクトリ構造を作成して、それを NAS 上に配置してあります。

ここで、linux mint の flask から ubuntu の mysql にアクセスして必要な情報を取得し、閲覧したい dicom ファイルを NAS から linux mint にダウンロードして weasis を起動してその dicom ファイルを閲覧します。
面倒なようですが、これまでで最も簡単な dicom 閲覧システムです。

前提条件

  1. ubuntu 上の python によってタグ情報がきちんと mysql に記録され、その情報と NAS 上のディレクトリ構造が一致していること。
  2. linux mint の /var/www/html に weasis が設置されていてそれが起動すること
  3. flask がインストールされていること

1 の条件は、ubuntu 上の python がエラーなく稼働していれば、問題はありません。

2 も他の記事で書きましたが簡単です。

flask

python のフレームワークで flask が最も簡単なようなので導入してみました。
~/ に flask というディレクトリを作成してあり、以下のような構造になっています。


flask
├── dcm.py
├── dcmtemp
├── flask.sh
├── ftpdn.sh
├── startWeasis.py
├── static
│   ├── css
│   └── js
└── templates
    ├── detail.html
    ├── layout.html
    └── select.html
dcm.py

from flask import Flask, render_template, redirect
import pymysql
import startWeasis

app = Flask(__name__)

@app.route('/')
def hello():
    db = pymysql.connect(
            host='192.168.0.99',
            user='heno',
            password='moheno',
            db='pydcmdb',
            charset='utf8',
            cursorclass=pymysql.cursors.DictCursor,
        )
    cur = db.cursor()
    sql = "SELECT * FROM taginfo;";
    cur.execute(sql)
    mbrs = cur.fetchall()
    cur.close()
    db.close()
    return render_template('select.html', title='flask test', mbrs=mbrs) 
    
@app.route('/detail/<int:studyID>')
def detail(studyID):	
	return redirect('/'), startWeasis.weasis(studyID)

if __name__ == "__main__":
    app.run(debug=True)
startWeasis.py

import os
import pymysql

def weasis(studyID):
	targetDir = 'pDICOM/' + getPath( studyID )
	os.system('./ftpdn.sh '+ targetDir)

def getPath( studyID ):
    conn = pymysql.connect( host='192.168.0.99',
        user='heno',
        db='pydcmdb',
        password='moheno',
        cursorclass=pymysql.cursors.DictCursor)
    try:
        with conn.cursor() as cursor:
            cursor.execute( "SELECT path FROM taginfo WHERE studyID = %s", (studyID), )
            res = cursor.fetchone()
            return res['path']  
    finally:
        conn.close()  
        
if __name__ == '__main__':
	weasis()
flask.sh

#!/bin/bash

cd ~/flask
python dcm.py

xdg-open http://localhost:5000
ftpdn.sh

#!/bin/bash

source ./.conf/ftp.conf
cd ~/flask/dcmtemp
rm *.dcm

ftp -n <<END
open $SERVER
user $USER $PASS
passive
cd $1
binary
prompt
mget *.dcm
END

javaws /var/www/html/weasis/weasisStart.jnlp
layout.html

<!doctype html>
<html>
<head>
<title>{{ title }}</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='css/mystyle.css') }}">
<script src="{{ url_for('static', filename='js/jquery-3.2.1.min.js') }}"></script>
<script type="text/javascript">
$(function(){
	$('td').click(function() { 
		var studyID = $(this).closest('tr').children('td').eq(0).text();	
		location.href = "/detail/" + studyID ;
	});
	$('table.datashow tr').hover(function() {
		$(this).addClass('hover');
	},function() {
		$(this).removeClass('hover');
	})
});
</script>
</head>
<body>
<div id="container">
	<div id="main">
		{% block content %}
		<!-- ここにメインコンテンツを書く -->
		{% endblock %}
	</div>	
</div>
</body>
</html>
select.html

{% extends "layout.html" %}
{% block content %}
<h2>dicom 検査一覧</h2>
<table class="datashow">
	<tr><th>検査ID</th><th>日付</th><th>カルテ番号</th><th>氏名</th><th>生年月日</th><th>年齢</th><th>性別</th><th>モダリティ</th><th>部位</th></tr>
	{% for mbr in mbrs %}
		<tr><td>{{ mbr.studyID}}</td><td>{{ mbr.studyDate}}</td><td>{{ mbr.karteNo }}</td><td>{{ mbr.ptName }}</td><td>{{ mbr.birthday }}</td><td>{{ mbr.age }}</td>
		<td>{{ mbr.sex }}</td><td>{{ mbr.modality }}</td><td>{{ mbr.studyDscr }}</td></tr>
	{% endfor %}
</table>
{% endblock %}

これで動くのですが、ftp 接続情報は .conf という通常では表示されないディレクトリに保存されているものの、簡単にアクセスされてしまうので、その気になれば NAS 上のすべてのファイルを削除することもできます。

院内に悪意ある誰かがいなければこれでいいのですが、やはりセキュリティはこのままではまずいと思います。