551 lines
17 KiB
Python
Executable file
551 lines
17 KiB
Python
Executable file
#!/usr/bin/python
|
||
# coding=utf-8
|
||
|
||
# 2010-09-16 move from project cyberknife
|
||
|
||
PASSWORD = 'n122119493'
|
||
|
||
from datetime import date
|
||
|
||
import mechanize
|
||
|
||
from urllib2 import urlopen
|
||
#from ClientForm import ParseResponse
|
||
|
||
import datetime
|
||
import hashlib
|
||
import re
|
||
import urllib
|
||
import urllib2
|
||
|
||
import pdb
|
||
|
||
import math
|
||
|
||
import pprint
|
||
pp = pprint.PrettyPrinter()
|
||
|
||
#br = mechanize.Browser(factory=mechanize.RobustFactory())
|
||
br = mechanize.Browser()
|
||
br.set_handle_robots(False)
|
||
|
||
|
||
def xtrace(R):
|
||
pdb.set_trace()
|
||
|
||
|
||
def remove_space(s):
|
||
return s.replace(' ','').strip()
|
||
|
||
#print remove_space(' 123 ')
|
||
|
||
|
||
def minguo2ce(minguo):
|
||
pattern = '(\d+)\.([ 0-9]{1,2})\.([ 0-9]{1,2})'
|
||
s = re.search(pattern, minguo)
|
||
if s:
|
||
yy = int(s.group(1))+1911
|
||
|
||
try:
|
||
mm = int(s.group(2))
|
||
except:
|
||
mm = 1
|
||
|
||
try:
|
||
dd = int(s.group(3))
|
||
except:
|
||
dd = 1
|
||
|
||
return date( yy, mm , dd )
|
||
|
||
pattern = '(\d+)/([ 0-9]{1,2})/([ 0-9]{1,2})'
|
||
s = re.search(pattern, minguo)
|
||
if s:
|
||
yy = int(s.group(1))+1911
|
||
|
||
try:
|
||
mm = int(s.group(2))
|
||
except:
|
||
mm = 1
|
||
|
||
try:
|
||
dd = int(s.group(3))
|
||
except:
|
||
dd = 1
|
||
|
||
return date( yy, mm , dd )
|
||
|
||
return
|
||
|
||
#print minguo2ce(' 75.01.25')
|
||
|
||
########## Old intra system
|
||
|
||
def Default_Dr(REQUEST):
|
||
if (REQUEST.has_key('ChartNo')) and REQUEST['ChartNo'] != "":
|
||
values = { 'ChartNo' : REQUEST['ChartNo'] }
|
||
elif (REQUEST.has_key('Name')) and REQUEST['Name'] != "":
|
||
values = { 'Name' : REQUEST['Name'].decode('utf_8').encode('big5') }
|
||
elif (REQUEST.has_key('idcode')) and REQUEST['idcode'] != "":
|
||
values = { 'idcode' : REQUEST['idcode'] }
|
||
else:
|
||
return ""
|
||
|
||
url = 'http://intra.mc.ntu.edu.tw/main/ChartNo/Default_Dr.asp'
|
||
|
||
data = urllib.urlencode(values)
|
||
req = urllib2.Request(url, data)
|
||
response = urllib2.urlopen(req)
|
||
the_page = response.read()
|
||
the_page = the_page.decode('big5','ignore').encode('utf_8')
|
||
|
||
pattern = ( '(?s)<td align="center">(.*?)</td>(.*?)'
|
||
+ '<td width="100"><font color="blue">(.*?)</font>(.*?)'
|
||
+ '<td align="center"><font color="blue">(.*?)</font>(.*?)'
|
||
+ '<td align="center">(.*?)</td>(.*?)'
|
||
+ '<td align="center">(.*?)</td>(.*?)'
|
||
+ '<td>(.*?)</td>(.*?)'
|
||
+ '<td>(.*?)</td>(.*?)'
|
||
+ '<td>(.*?)</td>' )
|
||
|
||
matches = re.findall(pattern, the_page)
|
||
|
||
result = []
|
||
for match in matches:
|
||
r = {}
|
||
r['name'] = remove_space(match[2])
|
||
r['medical_records'] = remove_space(match[4])
|
||
r['gender'] = remove_space(match[6])
|
||
r['birthday'] = minguo2ce(match[8])
|
||
r['address'] = remove_space(match[10])
|
||
r['phone'] = remove_space(match[12])
|
||
r['id_cards'] = remove_space(match[14])
|
||
result.append(r)
|
||
|
||
return result
|
||
|
||
|
||
#print Default_Dr({ 'HIS' : '',
|
||
# 'firstname' : '',
|
||
# 'MIS' : 'N122119493' })
|
||
|
||
def percent_encoding(keys, REQUEST):
|
||
data = {}
|
||
for key in keys:
|
||
if REQUEST.__contains__(key):
|
||
data[key] = REQUEST[key]
|
||
|
||
return urllib.urlencode(data)
|
||
|
||
#print percent_encoding(['HIS','MIS'],
|
||
# { 'HIS' : '3009684',
|
||
# 'firstname' : '',
|
||
# 'MIS' : 'N122119493' })
|
||
|
||
def CheckUser():
|
||
|
||
br.open("http://intra.mc.ntu.edu.tw/CheckUser_Ehospital.asp?myurl=default_Ehospital.asp")
|
||
|
||
br.select_form(name="form1")
|
||
br["uid"] = 'dtsurg08'
|
||
br["pwd"] = 'x'
|
||
response = br.submit() # submit current form
|
||
|
||
return response.read()
|
||
|
||
def chinese2date(chinese):
|
||
pattern = '(\d+)(\D+)(\d{1,2})(\D+)(\d{1,2})'
|
||
s = re.search(pattern, chinese)
|
||
if s:
|
||
yy = int(s.group(1))
|
||
mm = int(s.group(3))
|
||
dd = int(s.group(5))
|
||
return date( yy, mm , dd )
|
||
|
||
return
|
||
|
||
|
||
|
||
|
||
def XrayExam(ChartNo):
|
||
url = "http://intra.mc.ntu.edu.tw/DigReport/Xray/XrayExam.asp"
|
||
url = 'http://portal.ntuh.gov.tw/DigReport/Xray/XrayExam.asp'
|
||
response = br.open(url)
|
||
if response.read().decode('big5','ignore').encode('utf_8').find('閒置時間超過六十分鐘'):
|
||
CheckUser()
|
||
response = br.open(url)
|
||
body = {}
|
||
|
||
print response.read().decode('big5','ignore').encode('utf_8')
|
||
|
||
br.select_form(name="FrontPage_Form1")
|
||
br["ChartNo"] = str(ChartNo)
|
||
br["durnum"] = ['12']
|
||
br["reptype"] = ['CT']
|
||
br["dattype"] = ['Y']
|
||
response = br.submit()
|
||
body['CT'] = response.read().decode('big5','ignore').encode('utf_8')
|
||
|
||
br.select_form(name="FrontPage_Form1")
|
||
br["ChartNo"] = str(ChartNo)
|
||
br["durnum"] = ['12']
|
||
br["reptype"] = ['MRI']
|
||
br["dattype"] = ['Y']
|
||
response = br.submit()
|
||
body['MRI'] = response.read().decode('big5','ignore').encode('utf_8')
|
||
|
||
# pattern="<a href='Ximage/XrayReport.asp?reportseqno=A20080629173&ChartNo=4399879&ChineseName=陳建錫 &Sex=M&Birthday=+0451119&ExamDate=2008-06-28&accessno=T0089317804&ReferNo=T0089317804&status=5'>Pelvis: for THR</a>"
|
||
pattern="<a href='(Ximage/XrayReport.asp\\?reportseqno=(.*?)&ChartNo=(.*?)&ChineseName=(.*?)&Sex=(.*?)&Birthday=(.*?)&ExamDate=(.*?)&accessno=(.*?)&ReferNo=(.*?)&status=(.*?))'>(.*?)</a>"
|
||
# pattern="Ximage/XrayReport.asp?reportseqno=(.*?)"
|
||
pattern = pattern.replace("'", "\\'")
|
||
pattern = pattern.replace('&', '\\&')
|
||
results = []
|
||
for m in ['CT', 'MRI']:
|
||
matches = re.findall(pattern, body[m])
|
||
for match in matches:
|
||
r = {}
|
||
r['reportseqno'] = remove_space(match[0])
|
||
r['ChartNo'] = remove_space(match[1])
|
||
r['ChineseName'] = remove_space(match[2])
|
||
r['Sex'] = remove_space(match[3])
|
||
r['Birthday'] = remove_space(match[4])
|
||
r['ExamDate'] = remove_space(match[5])
|
||
r['accessno'] = remove_space(match[6])
|
||
r['ReferNo'] = remove_space(match[7])
|
||
r['status'] = remove_space(match[8])
|
||
r['LinkOrderName'] = remove_space(match[9])
|
||
r['Modality'] = m
|
||
results.append(r)
|
||
pp.pprint(urllib2.unquote(match[0]))
|
||
# pp.pprint(results)
|
||
return results
|
||
|
||
|
||
########################################New portal systemn
|
||
|
||
def Login():
|
||
|
||
br.open("http://portal.ntuh.gov.tw/General/Login.aspx")
|
||
|
||
br.select_form(name="Form1")
|
||
# br["rdblQuickMenu"] = ['O']
|
||
br["txtUserID"] = '004552'
|
||
br["txtPass"] = hashlib.md5(PASSWORD).hexdigest()
|
||
# print br.possible_items("rdblQuickMenu")
|
||
# print br.form
|
||
response = br.submit() # submit current form
|
||
|
||
pattern = "http://hisaw.ntuh.gov.tw/WebApplication/Clinics/OpenClinics.aspx\?SESSION=(\w*)"
|
||
string = str(response.read())
|
||
# print string
|
||
matches = re.findall(pattern, string)
|
||
return matches[0]
|
||
|
||
|
||
|
||
def ReportResult(PersonID):
|
||
SESSION = Login()
|
||
url = "http://ihisaw.ntuh.gov.tw/WebApplication/OtherIndependentProj/PatientBasicInfoEdit/ReportResultQuery.aspx?SESSION=%s&PersonID=%s" % (SESSION,PersonID)
|
||
|
||
response = br.open(url)
|
||
br.select_form(name="Form1")
|
||
response = br.submit() # submit current form
|
||
body = response.read()
|
||
print body
|
||
return
|
||
|
||
response = urlopen(url)
|
||
forms = ParseResponse(response, backwards_compat=False)
|
||
form = forms[0]
|
||
print form
|
||
form.set_all_readonly(False)
|
||
form["__EVENTTARGET"] = "LinkbuttonRadReport"
|
||
|
||
# form.click() returns a urllib2.Request object
|
||
# (see HTMLForm.click.__doc__ if you don't have urllib2)
|
||
print urlopen(form.click()).read()
|
||
|
||
|
||
def icd_query(ChartNo):
|
||
Login()
|
||
|
||
br.select_form(name="Form1")
|
||
br["NTUHWeb1:QueryPersonIDByChartNo2:txbChartNoInput"] = str(ChartNo)
|
||
br["NTUHWeb1:QueryPersonIDByChartNo2:AutoShowRecord"] = True
|
||
response = br.submit() # submit current form
|
||
|
||
return response.read()
|
||
|
||
|
||
################## os.getcwd()##############
|
||
def get_path():
|
||
|
||
import os,sys
|
||
|
||
return os.path.realpath(os.path.dirname(sys.argv[0]))
|
||
###############################
|
||
|
||
vs = {}
|
||
|
||
def unf_byDisDate(deptcode, StartDate, EndDate):
|
||
import csv
|
||
reader = csv.reader(open(get_path()+"/vs.csv", "rb"))
|
||
for row in reader:
|
||
# print row[1], row[0]
|
||
vs[row[1]]=row[0]
|
||
|
||
url = "http://intra.mc.ntu.edu.tw/main/Discharge/unf_byDisDate.asp"
|
||
response = br.open(url)
|
||
br.select_form(nr=0)
|
||
|
||
br["deptcode"] = [deptcode]
|
||
br["StartDate"] = StartDate
|
||
br["EndDate"] = EndDate
|
||
|
||
response = br.submit()
|
||
|
||
body = response.read().decode('big5','ignore').encode('utf_8')
|
||
|
||
pattern = """
|
||
<tr>\s*
|
||
<td align="center" bgcolor="#FFFFFF">(.*?)</td>
|
||
<td align="center" bgcolor="#FFFFFF">(.*?)</td>
|
||
<td align="center" bgcolor="#FFFFFF">(.*?)</td>
|
||
<td align="center" bgcolor="#FFFFFF">(.*?)</td>
|
||
<td align="center" bgcolor="#FFFFFF">
|
||
<p align="left">
|
||
(.*?)
|
||
</td>
|
||
<td align="center" bgcolor="#FFFFFF">
|
||
(.*?)
|
||
</td>
|
||
<td align="center" bgcolor="#FFFFFF">(.*?)</td>
|
||
<td align="center" bgcolor="#FFFFFF">(.*?)</td>
|
||
<td align="center" bgcolor="#FFFFFF">(.*?)</td>
|
||
<td align="center" bgcolor="#FFFFFF">
|
||
(.*?)
|
||
</td>
|
||
<td align="center" bgcolor="#FFFFFF">(.*?)</td>
|
||
<td align="center" bgcolor="#FFFFFF">(.*?)</td>
|
||
</tr>
|
||
"""
|
||
pattern = pattern.replace('"', '\\"')
|
||
pattern = pattern.replace('\n', '\\s*')
|
||
matches = re.findall(pattern, body)
|
||
|
||
result = []
|
||
for match in matches:
|
||
r = {}
|
||
r['no'] = remove_space(match[0])
|
||
r['doctor_code'] = remove_space(match[1])
|
||
r['doctor_name'] = remove_space(match[2])
|
||
r['discharge_date'] = remove_space(match[3])
|
||
r['patients_name'] = remove_space(match[4])
|
||
r['medical_record_number'] = remove_space(match[5])
|
||
r['account'] = remove_space(match[6])
|
||
r['admission_date'] = remove_space(match[7])
|
||
r['hospital_ bed'] = remove_space(match[8])
|
||
r['category'] = remove_space(match[9])
|
||
r['dr'] = remove_space(match[10])
|
||
r['resident'] = remove_space(match[11])
|
||
if vs.has_key(r['dr']):
|
||
r['division'] = vs[r['dr']]
|
||
else:
|
||
r['division'] = 'Others'
|
||
|
||
result.append(r)
|
||
|
||
return result
|
||
|
||
def formatDate(sDate):
|
||
dScrap = sDate
|
||
|
||
iDay = dScrap.day
|
||
iMon = dScrap.month
|
||
iYea = dScrap.year
|
||
|
||
sDay = str(iDay)
|
||
sMon = str(iMon)
|
||
sYea = str(iYea - 1911)
|
||
|
||
if len(sDay) == 1:
|
||
sDay = "0" + sDay
|
||
if len(sMon) == 1:
|
||
sMon = "0" + sMon
|
||
if len(sYea) == 2:
|
||
sYea = "0" + sYea;
|
||
sScrap = sYea + sMon + sDay;
|
||
|
||
return sScrap;
|
||
|
||
|
||
def unf_sort(StartDay, EndDay):
|
||
|
||
StartDate = datetime.date.today() + datetime.timedelta(days=StartDay)
|
||
EndDate = datetime.date.today() + datetime.timedelta(days=EndDay)
|
||
|
||
result = unf_byDisDate('SURG', formatDate(StartDate), formatDate(EndDate))
|
||
|
||
dr = []
|
||
resident = []
|
||
division = []
|
||
for r in result:
|
||
dr.append(r['dr'])
|
||
resident.append(r['resident'])
|
||
division.append(r['division'])
|
||
|
||
# The count is doubled, so we div it by 2
|
||
dr_freq = [(a, dr.count(a)/2) for a in set(dr)]
|
||
dr_sort = sorted(dr_freq, key=lambda x: -x[1])
|
||
resident_freq = [(a, resident.count(a)/2) for a in set(resident)]
|
||
resident_sort = sorted(resident_freq, key=lambda x: -x[1])
|
||
division_freq = [(a, division.count(a)/2) for a in set(division)]
|
||
division_sort = sorted(division_freq, key=lambda x: -x[1])
|
||
|
||
# print "\n¦ᄌᄏ₩ᄇᄏ←ニᆱ¥ᄌᆱ,¦ᄏᄑ₩ユᄌ"
|
||
# for dr in dr_sort:
|
||
# print "%s,%s" % dr
|
||
#
|
||
# print "\n¦ᄑマ←ルᄁ←ニᆱ¥ᄌᆱ,¦ᄏᄑ₩ユᄌ"
|
||
# for resident in resident_sort:
|
||
# print "%s,%s" % resident
|
||
|
||
return {'dr': dr_sort,
|
||
'resident': resident_sort,
|
||
'division': division_sort,
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
def doPostBack(form, eventTarget, eventArgument):
|
||
#Creates a new __EVENTTARGET control and adds the value specified
|
||
#.NET doesn't generate this in mechanize for some reason -- suspect maybe is
|
||
#normally generated by javascript or some useragent thing?
|
||
form.new_control('hidden','__EVENTTARGET',attrs = dict(name='__EVENTTARGET'))
|
||
form.new_control('hidden','__EVENTARGUMENT',attrs = dict(name='__EVENTARGUMENT'))
|
||
form.set_all_readonly(False)
|
||
form["__EVENTTARGET"] = eventTarget
|
||
form["__EVENTARGUMENT"] = eventArgument
|
||
|
||
|
||
|
||
def dischargenotelist(Chart, SESSION = Login()):
|
||
url = "http://ihisaw.ntuh.gov.tw/WebApplication/OtherIndependentProj/PatientBasicInfoEdit/PatientMedicalRecordListQuery.aspx?QueryBySelf=N&SESSION=%s" % SESSION
|
||
br.open(url)
|
||
br.select_form(name="Form1")
|
||
br["NTUHWeb1$ChartInputTextBox"] = Chart
|
||
response = br.submit('NTUHWeb1$ButtonQuery')
|
||
|
||
Notes = re.findall('NTUHWeb1\$.*?ShowDischargeNote',
|
||
response.read())
|
||
|
||
# print Notes
|
||
|
||
|
||
'''
|
||
<form name=dischargenotelist action='http://ihisaw.ntuh.gov.tw/WebApplication/OtherIndependentProj/PatientBasicInfoEdit/SimpleInfoShowUsingPlaceHolder.aspx?SESSION=D32EB731A5CF4262B605EC26D2D232A8' target="dischargenote" method="post" >
|
||
<input type=hidden name="KeyCodeList" value=10T02569131|10T07485265|09T07305932>
|
||
<input type=hidden name="KeyNameList" value=外_2010/10/19|外_2010/01/08|外_2009/12/22>
|
||
<input type=hidden name="AccountIDSE" value=10T02569131>
|
||
<input type=hidden name="Func" value=DischargeSummary>
|
||
</form><script language='javascript'>dischargenotelist.submit();</script>
|
||
'''
|
||
|
||
pattern = 'name="KeyCodeList" value=(.*?)><input type=hidden name="KeyNameList" value=(.*?)><input type=hidden name="AccountIDSE" value=(.*?)>'
|
||
key = []
|
||
for Note in Notes:
|
||
# print Note
|
||
|
||
br.select_form(name="Form1")
|
||
response = br.submit(Note)
|
||
body = response.read()
|
||
matches=re.findall(pattern, body)
|
||
|
||
for match in matches:
|
||
# print match
|
||
key.append(match)
|
||
|
||
return key
|
||
|
||
|
||
def ShowDischargeNote(KeyCodeList, KeyNameList, AccountIDSE, SESSION=Login()):
|
||
url = 'http://ihisaw.ntuh.gov.tw/WebApplication/OtherIndependentProj/PatientBasicInfoEdit/SimpleInfoShowUsingPlaceHolder.aspx?SESSION=%s' % SESSION
|
||
|
||
data = {
|
||
'KeyCodeList': KeyCodeList,
|
||
'KeyNameList': KeyNameList,
|
||
'AccountIDSE': AccountIDSE,
|
||
'Func' : 'DischargeSummary',
|
||
}
|
||
|
||
response = br.open(url, urllib.urlencode(data))
|
||
body = response.read()
|
||
|
||
pattern ='(<div class="reportQuery">.*?</div>)\\s*?</td>'
|
||
matches=re.findall(pattern, body, re.DOTALL)
|
||
return matches[0]
|
||
|
||
def oncrt_query(ChartNo):
|
||
# url = "http://intra.mc.ntu.edu.tw/DigReport/ONC_RT/oncrt_query.asp"
|
||
url = "http://intra.mc.ntu.edu.tw/DigReport/ONC_RT/oncrt_query_only.asp"
|
||
|
||
response = br.open(url)
|
||
if response.read().decode('big5','ignore').encode('utf_8').find('閒置時間超過六十分鐘'):
|
||
CheckUser()
|
||
response = br.open(url)
|
||
|
||
br.select_form(name="FrontPage_Form1")
|
||
br["ChartNo"] = str(ChartNo)
|
||
response = br.submit()
|
||
|
||
body = response.read().decode('big5','ignore').encode('utf_8')
|
||
htmlcomments = re.compile('\<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>')
|
||
body = htmlcomments.sub('', body)
|
||
|
||
# print body
|
||
# body = body[body.find('部位'):]
|
||
|
||
pattern = (
|
||
'(?s)<tr align="center">(\s*?)'
|
||
+'<td>(.*?)</td>(\s*?)'
|
||
+'<td>(.*?)</td>(\s*?)'
|
||
+'<td>(.*?)</td>(\s*?)'
|
||
+'<td>(.*?)</td>(\s*?)'
|
||
+'<td>(.*?)</td>(\s*?)'
|
||
+'<td>(.*?)</td>(\s*?)'
|
||
+'<td>(.*?)</td>(\s*?)'
|
||
+'<td>(.*?)</td>(\s*?)'
|
||
+'<td align="left">(.*?)</td>'
|
||
)
|
||
|
||
matches = re.findall(pattern, body)
|
||
|
||
result = []
|
||
for match in matches:
|
||
r = {}
|
||
r['site'] = remove_space(match[1])
|
||
r['way'] = remove_space(match[3])
|
||
r['radiation_energy'] = remove_space(match[5])
|
||
r['number_of_treatment'] = remove_space(match[7])
|
||
r['total_dose'] = remove_space(match[9])
|
||
r['start_date'] = chinese2date(match[11])
|
||
r['end_date'] = chinese2date(match[13])
|
||
r['the_number_of_treatment'] = remove_space(match[15])
|
||
r['remarks'] = remove_space(match[17])
|
||
result.append(r)
|
||
|
||
return result
|
||
|
||
|
||
|
||
if __name__ == "__main__":
|
||
#PatientMedicalRecordListQuery('A101116124') #已死亡
|
||
#PatientMedicalRecordListQuery('R100260467')
|
||
#PatientMedicalRecordListQuery('L200772263') #已死亡
|
||
#pp.pprint(PatientMedicalRecordListQuery('4582056'))
|
||
XrayExam('5621920')
|
||
pass
|