ntuhgov/portal.py
2024-12-11 13:19:30 +08:00

990 lines
37 KiB
Python
Executable file
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
from .settings import USER_ID, PASSWORD
DefaultUserID = USER_ID
DefaultPassword = PASSWORD
# from datetime import *
# from urllib2 import *
try:
# For Python 3.0 and later
from urllib.request import urlopen
except ImportError:
# Fall back to Python 2's urllib2
from urllib2 import urlopen
from bs4 import BeautifulSoup
# from BeautifulSoup import *
import datetime
import hashlib
import math
import pdb
import re
import time
import urllib
# import urllib2
# import mechanize
# print mechanize._sockettimeout._GLOBAL_DEFAULT_TIMEOUT
# mechanize._sockettimeout._GLOBAL_DEFAULT_TIMEOUT = 100
# print mechanize._sockettimeout._GLOBAL_DEFAULT_TIMEOUT
import mechanicalsoup
#from ClientForm import ParseResponse
# br = mechanize.Browser(
# # factory=mechanize.RobustFactory()
# )
br = mechanicalsoup.StatefulBrowser()
# br.set_handle_robots(False)
def xtrace(R):
pdb.set_trace()
def remove_space(s):
return s.replace(' ','').strip()
def remove_tags(s):
return remove_space(re.sub('<[^<]+?>', '', s))
#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')
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
def percent_encoding(keys, REQUEST):
data = {}
for key in keys:
if REQUEST.__contains__(key):
data[key] = REQUEST[key]
return urllib.urlencode(data)
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
########################################New portal system
SESSION = False
SESSION_TIME = time.time()
def Login():
global SESSION, SESSION_TIME
if SESSION and time.time() - SESSION_TIME < 600: # seconds
# print SESSION, time.time() - SESSION_TIME
SESSION_TIME = time.time()
return SESSION
# br.open("http://portal.ntuh.gov.tw/General/Login.aspx")
try:
br.open("http://portal.ntuh.gov.tw/General/Login.aspx", timeout=1)
except:
return None
# br._factory.encoding = enc
# br._factory._forms_factory.encoding = enc
# br._factory._links_factory._encoding = enc
# print br._factory.encoding
# print br._factory._forms_factory.encoding
# print br._factory._links_factory._encoding
# br.open("http://portal.ntuh.gov.tw/General/Login.aspx")
# print br.response().read()
br.select_form(name="Form1")
# print br
# br["rdblQuickMenu"] = ['O']
br["txtUserID"] = DefaultUserID
br["txtPass"] = hashlib.md5(DefaultPassword).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)
SESSION = matches[0]
SESSION_TIME = time.time()
return SESSION
def HeightWeight(PersonID): #身高體重
SESSION = Login()
url = "http://ihisaw.ntuh.gov.tw/WebApplication/OtherIndependentProj/PatientBasicInfoEdit/QueryHeightWeightByPersonID.aspx?SESSION=%s&PersonID=%s" % (SESSION,PersonID)
response = br.open(url)
body = response.read()
'''
<span id="ctl13_RecordTabPanel_PatientHeightWeightGrid_ctl07_HeightLabel">151.7</span>
</font></td><td align="left"><font color="#333333">
<span id="ctl13_RecordTabPanel_PatientHeightWeightGrid_ctl07_HeightPerLabel"></span>
</font></td><td align="left"><font color="#333333">
<span id="ctl13_RecordTabPanel_PatientHeightWeightGrid_ctl07_WeightLabel">40.8</span>
</font></td><td align="left"><font color="#333333">
<span id="ctl13_RecordTabPanel_PatientHeightWeightGrid_ctl07_WeightPerLabel"></span>
'''
pattern = '''
_HeightLabel">(?P<HeightLabel>.*?)</span>
(.*?)_WeightLabel">(?P<WeightLabel>.*?)</span>
'''.replace('\n', '').replace('"', '\\"')
# matches = re.findall(pattern, body, re.DOTALL)
matches = [m.groupdict() for m in re.finditer(pattern, body, re.DOTALL)]
# print matches[0]
h = 0
w = 0
bsa = 0
if matches:
try:
h = float(matches[0]['HeightLabel'])
w = float(matches[0]['WeightLabel'])
bsa = math.sqrt(h * w / 3600) #Mosteller formula
except:
pass
return {'Height': h, 'Weight': w, 'BSA': bsa}
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(CharNo)
br["NTUHWeb1:QueryPersonIDByChartNo2:AutoShowRecord"] = True
response = br.submit() # submit current form
return response.read()
def WardQueryUncompletedChart_QueryByOutDate(Start, End):
SESSION = Login()
url = "http://ihisaw.ntuh.gov.tw/WebApplication/MedicalRecordManagement/WardQueryUncompletedChart.aspx?SESSION=%s" % SESSION
response = br.open(url)
br.select_form(name="form1")
# print br.form
br['NTUHWeb1$A']=['RBOutDate']
response = br.submit() # submit current form
body = response.read()
br.select_form(name="form1")
# print br.form
br['NTUHWeb1$ddlDeptCode']=['SURG']
br['NTUHWeb1$txtQStartDate']=Start
br['NTUHWeb1$txtQEndDate']=End
# response = br.submit(name='NTUHWeb1$btn_QueryByDeptListAll') # submit current form
response = br.submit(name='NTUHWeb1$btn_QueryByOutDate') # submit current form
body = response.read()
# print body
# exit()
'''
<span id="NTUHWeb1_DeptDataList_ctl01_DrName" style="display:inline-block;">邱英世</span>
</td>
<td>
<span id="NTUHWeb1_DeptDataList_ctl01_Count" style="display:inline-block;">1</span>
'''
pattern = '''<span id=(.*?)DrName(.*?)>(.*?)</span>(\s*?)\
</td>(\s*?)\
<td>(\s*?)\
<span id=(.*?)Count(.*?)>(.*?)</span>(\s*?)\
'''
matches = re.findall(pattern, body,re.DOTALL)
# print matches
# exit()
q = {}
r = []
POS_DrName = 2
POS_Count = 8
UNF_LIST = []
for match in matches:
DrName = match[POS_DrName]
Count = int(match[POS_Count])
# print DrName, Count
r.append((DrName, Count))
return r
#def WardQueryUncompletedChart_QueryByDeptListAll(Start, End):
def WardQueryUncompletedChart(Start, End):
SESSION = Login()
url = "http://ihisaw.ntuh.gov.tw/WebApplication/MedicalRecordManagement/WardQueryUncompletedChart.aspx?SESSION=%s" % SESSION
response = br.open(url)
br.select_form(name="form1")
# print br.form
br['NTUHWeb1$A']=['RBOutDate']
# TIMEOUT = mechanize._sockettimeout._GLOBAL_DEFAULT_TIMEOUT
# mechanize._sockettimeout._GLOBAL_DEFAULT_TIMEOUT = 100
response = br.submit() # submit current form
# mechanize._sockettimeout._GLOBAL_DEFAULT_TIMEOUT = TIMEOUT
body = response.read()
br.select_form(name="form1")
# print br.form
br['NTUHWeb1$ddlDeptCode']=['SURG']
br['NTUHWeb1$txtQStartDate']=Start
br['NTUHWeb1$txtQEndDate']=End
response = br.submit(name='NTUHWeb1$btn_QueryByDeptListAll') # submit current form
body = response.read()
# print body
# exit()
'''
<tr>
<td>1</td><td>5042857</td><td>10T02491675</td><td>SURG</td><td>2010/10/12</td><td>2010/10/13</td><td>邱淑美</td><td>09D 0901</td><td>病摘</td><td>簡雄飛</td><td>黃柏誠</td><td>admission note vs未蓋章</td><td>&nbsp;</td>
</tr>
'''
pattern = '''\
<tr>(\s*?)\
<td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td>(\s*?)\
</tr>\
'''
'''
<tr>
<td>1</td><td>5749509</td><td>
<a id="NTUHWeb1_dgRecordData_ctl02_AccountIDSELinkButton" title="點選彈跳病人主畫面" href="javascript:__doPostBack('NTUHWeb1$dgRecordData$ctl02$AccountIDSELinkButton','')">11T06202260</a>
</td><td>SURG</td><td>2011/08/30</td><td>2011/08/31</td><td>黃寶蓮</td><td>13PE0801</td><td>
<a id="NTUHWeb1_dgRecordData_ctl02_TypeLinkButton" href="javascript:__doPostBack('NTUHWeb1$dgRecordData$ctl02$TypeLinkButton','')">入院</a>
</td><td>王水深</td><td>莊民楷</td><td>&nbsp;</td><td>4</td>
</tr>
'''
pattern = '''<tr>(\s*?)\
<td>(.*?)</td><td>(.*?)</td><td>(\s*?)\
(.*?)TypeLinkButton',''\)">(.*?)</a>(\s*?)\
</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td>(\s*?)\
'''
matches = re.findall(pattern, body,re.DOTALL)
# print matches
# exit()
q = {}
r = []
POS_C = 2 # Chart#
POS_T = 5 # Type
POS_V = 7 # VS
POS_R = 8 # R
POS_O = 10 # Over
UNF_LIST = []
for match in matches:
# print match[10], match[11], match[13]
# print match[0], match[2], match[3], match[4], match[5]
if 'Y' in match[POS_C]:
# print match[POS_C], 'discarded(雲林)'
continue
else:
print (match[POS_C], match[POS_T], match[POS_V], match[POS_R], match[POS_O])
# print match
# continue
try:
Overdue = int(match[POS_O])
M_CHART = match[POS_C]
M_TYPE = match[POS_T]
M_VS = match[POS_V]
M_R = match[POS_R]
if M_TYPE != '手術':
M_KEY = M_CHART+M_VS+M_R
if M_KEY in UNF_LIST:
continue
else:
UNF_LIST.append(M_KEY)
if not q.has_key(M_VS):
q[M_VS] = 1
else:
q[M_VS] += 1
if not q.has_key(M_R):
q[M_R] = 1
else:
q[M_R] += 1
except:
pass
# print q.iteritems()
# exit()
for key,value in q.iteritems():
r.append((key,value))
# print r
# exit()
return r
################## 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 SimpleQueryOpScheduleByChartNo(ChartNo, SESSION=None):
if SESSION is None:
SESSION = Login()
url = 'http://ihisaw.ntuh.gov.tw/WebApplication/InPatient/OPManagement/SimpleQueryOpSchedule.aspx?SESSION=%s' % SESSION
response = br.open(url)
br.select_form(name="Form1")
br['NTUHWeb1$QueryOPPatListCommon1$QueryPersonIDByChartNo1$txbChartNoInput']=ChartNo
response = br.submit('NTUHWeb1$QueryOPPatListCommon1$QueryPersonIDByChartNo1$btnQuery') # submit current form
body = response.read()
pattern = '''
_OPDateString">(?P<OPDateString>.*?)</span>
(.*?)_OpRoomNoShow">(?P<OpRoomNoShow>.*?)</span>
(.*?)_OpSeqNoshow">(?P<OpSeqNoshow>.*?)</span>
(.*?)_LinkPatName(.*?)<font color="Black">(?P<LinkPatName>.*?)</font></a>
(.*?)_PopupPatWardInfoWindow(.*?)<font color="Black">(?P<PopupPatWardInfoWindow>.*?)</font></a>
(.*?)_PatChartNo(.*?)<font color="Black">(?P<PatChartNo>.*?)</font></a>
(.*?)_PatSex">(?P<PatSex>.*?)</span>
(.*?)_PatAge" title="(?P<PatAgeTitle>.*?)">(?P<PatAge>.*?)</span>
(.*?)_PatDignosis" title="(?P<PatDignosis>.*?)">(.*?)</span>
(.*?)_MainOpMode" title="(?P<MainOpModeTitle>.*?)">(?P<MainOpMode>.*?)</span>
(.*?)_OpDoctorName">(?P<OpDoctorName>.*?)</span>
(.*?)_OpTypeName">(?P<OpTypeName>.*?)</span>
(.*?)_CompleteStatueName">(?P<CompleteStatueName>.*?)</span>
(.*?)_lbtPrint" title="(?P<lbtPrint>.*?)"
(.*?)_EstStartTimeShortString">(?P<EstStartTimeShortString>.*?)</span>
(.*?)_EstSpendTime">(?P<EstSpendTime>.*?)</span>
'''
pattern = pattern.replace('"', '\\"')
pattern = pattern.replace('\n', '')
pattern0 = '<tr(.*?)</tr>'
matches0 = re.findall(pattern0, body, re.DOTALL)
matches = []
reco = re.compile(pattern, re.DOTALL)
for match0 in matches0:
matches1 = [m.groupdict() for m in reco.finditer(match0)]
matches.extend(matches1)
result = []
for match in matches:
r = {}
r['OPDate'] = remove_space(match['OPDateString'])
r['OpRoomNo'] = remove_tags(match['OpRoomNoShow'])
r['OpSeqNo'] = remove_tags(match['OpSeqNoshow'])
r['PatName'] = remove_space(match['LinkPatName'])
r['PatWard'] = remove_space(match['PopupPatWardInfoWindow'])
r['PatChartNo'] = remove_space(match['PatChartNo'])
r['PatSex'] = remove_space(match['PatSex'])
r['PatAgeTitle'] = remove_space(match['PatAgeTitle'])
r['PatAge'] = remove_space(match['PatAge'])
r['PatDignosis'] = remove_space(match['PatDignosis'])
r['MainOpModeTitle'] = remove_space(match['MainOpModeTitle'])
r['MainOpMode'] = remove_space(match['MainOpMode'])
r['OpDoctorName'] = remove_space(match['OpDoctorName'])
r['OpTypeName'] = remove_space(match['OpTypeName'])
r['Complete'] = remove_space(match['CompleteStatueName'])
r['Anes'] = remove_space(match['lbtPrint'])
r['StartTime'] = remove_space(match['EstStartTimeShortString'])
r['SpendTime'] = remove_space(match['EstSpendTime'])
result.append(r)
return result
def SimpleQueryOpSchedule(DrCode, StartDate, EndDate):
SESSION = Login()
url = 'http://ihisaw.ntuh.gov.tw/WebApplication/InPatient/OPManagement/SimpleQueryOpSchedule.aspx?SESSION=%s' % SESSION
response = br.open(url)
br.select_form(name="Form1")
br['NTUHWeb1$QueryOPPatListCommon1$QueryDrIDInfoByDrName1$EmpNoQueryInput']=DrCode
br['NTUHWeb1$QueryOPPatListCommon1$txbStartDate']= StartDate
br['NTUHWeb1$QueryOPPatListCommon1$txbEndDate'] = EndDate
response = br.submit('NTUHWeb1$QueryOPPatListCommon1$QueryByMainDrCode') # submit current form
body = response.read()
# body = body[40000:50000]
# print body
# exit()
'''
<span id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_OPDateString">11/07</span>
</font></td><td><font size="2">
<span id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_OpRoomNoShow"><font color="Brown">003</font></span>
</font></td><td><font size="2">
<span id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_OpSeqNoshow"><font color="Brown">01</font></span>
</font></td><td class="wordbreak" width="50"><font size="2">
<a id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_LinkPatName" title="注意跌倒預防" href="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;NTUHWeb1$QueryOPPatListCommon1$OPScheduleShowDataGrid1$dgRecordData$ctl06$LinkPatName&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, true))"><font color="Black">薛福賜</font></a>
</font></td><td><font size="2">
<a id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_PopupPatWardInfoWindow" title="08D_22_01" href="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;NTUHWeb1$QueryOPPatListCommon1$OPScheduleShowDataGrid1$dgRecordData$ctl06$PopupPatWardInfoWindow&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, true))"><font color="Black">08D_22_01</font></a>
</font></td><td><font size="2">
<a id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_PatChartNo" href="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;NTUHWeb1$QueryOPPatListCommon1$OPScheduleShowDataGrid1$dgRecordData$ctl06$PatChartNo&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, true))"><font color="Black">5902391</font></a>
</font></td><td><font size="2">
<span id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_PatSex">M</span>
</font></td><td><font size="2">
<span id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_PatAge" title="1954/05/19">58y6m</span>
</font></td><td><font size="2">
</font></td><td><font size="2">
<span id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_MainOpMode" title="Craniotomy (A.V.M.) P-DUH
">Left far-lateral approach for C1 du...</span>
</font></td><td width="40"><font size="2">
<span id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_OpDoctorName">杜永光</span>
</font></td><td><font size="2">
<span id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_OpTypeName">預</span>
</font></td><td class="wordbreak" width="45"><font size="2">
<span id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_CompleteStatueName">完成</span>
</font></td><td width="5"><font size="2">
<a id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_PreAssessment" title="尚未完成術前評估" href="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;NTUHWeb1$QueryOPPatListCommon1$OPScheduleShowDataGrid1$dgRecordData$ctl06$PreAssessment&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, true))"><font color="Black">估</font></a>
<a id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_lbtPrint" title="全身麻醉" href="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;NTUHWeb1$QueryOPPatListCommon1$OPScheduleShowDataGrid1$dgRecordData$ctl06$lbtPrint&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, true))"><font color="Black">G</font></a>
<a id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_PostCarePlan" title="完成術後照護計畫" href="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;NTUHWeb1$QueryOPPatListCommon1$OPScheduleShowDataGrid1$dgRecordData$ctl06$PostCarePlan&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, true))"><font color="Black">護</font></a>
</font></td><td><font size="2">
<span id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_EstStartTimeShortString">09:03</span>
</font></td><td><font size="2">
<span id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_EstSpendTime">430</span>
</font></td><td width="5"><font size="2">
<a id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_LinkbuttonCancel" href="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;NTUHWeb1$QueryOPPatListCommon1$OPScheduleShowDataGrid1$dgRecordData$ctl06$LinkbuttonCancel&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, true))"><font color="Black">刪</font></a>
</font></td><td width="5"><font size="2">
<a id="NTUHWeb1_QueryOPPatListCommon1_OPScheduleShowDataGrid1_dgRecordData_ctl06_PopupEMRWindow" title="電子病歷視窗" href="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;NTUHWeb1$QueryOPPatListCommon1$OPScheduleShowDataGrid1$dgRecordData$ctl06$PopupEMRWindow&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, true))"><b><font color="Black">E</font></b></a>
</font></td>
'''
pattern = '''
_OPDateString">(?P<OPDateString>.*?)</span>
(.*?)_OpRoomNoShow">(?P<OpRoomNoShow>.*?)</span>
(.*?)_OpSeqNoshow">(?P<OpSeqNoshow>.*?)</span>
(.*?)_LinkPatName(.*?)<font color="Black">(?P<LinkPatName>.*?)</font></a>
(.*?)_PopupPatWardInfoWindow(.*?)<font color="Black">(?P<PopupPatWardInfoWindow>.*?)</font></a>
(.*?)_PatChartNo(.*?)<font color="Black">(?P<PatChartNo>.*?)</font></a>
(.*?)_PatSex">(?P<PatSex>.*?)</span>
(.*?)_PatAge" title="(?P<PatAgeTitle>.*?)">(?P<PatAge>.*?)</span>
(.*?)_PatDignosis" title="(?P<PatDignosis>.*?)">(.*?)</span>
(.*?)_MainOpMode" title="(?P<MainOpModeTitle>.*?)">(?P<MainOpMode>.*?)</span>
(.*?)_OpDoctorName">(?P<OpDoctorName>.*?)</span>
(.*?)_OpTypeName">(?P<OpTypeName>.*?)</span>
(.*?)_CompleteStatueName">(?P<CompleteStatueName>.*?)</span>
(.*?)_lbtPrint" title="(?P<lbtPrint>.*?)"
(.*?)_EstStartTimeShortString">(?P<EstStartTimeShortString>.*?)</span>
(.*?)_EstSpendTime">(?P<EstSpendTime>.*?)</span>
'''
# pattern = '''
#_OPDateString">(.*?)</span>
#(.*?)_OpRoomNoShow">(.*?)</span>
#(.*?)_OpSeqNoshow">(.*?)</span>
#(.*?)_LinkPatName(.*?)<font color="Black">(.*?)</font></a>
#(.*?)<font color="Black">(.*?)</font></a>
#(.*?)<font color="Black">(.*?)</font></a>
#(.*?)_PatSex">(.*?)</span>
#(.*?)_PatAge" title="(.*?)">(.*?)</span>
#(.*?)_PatDignosis"(.*?)><font size="1">(.*?)</font></span>
#(.*?)_MainOpMode" title="(.*?)"><font size="1">(.*?)</font></span>
#(.*?)_OpDoctorName">(.*?)</span>
#(.*?)_OpTypeName">(.*?)</span>
#(.*?)_CompleteStatueName">(.*?)</span>
#(.*?)_lbtPrint" title="(.*?)"
#(.*?)_EstStartTimeShortString">(.*?)</span>
#(.*?)_EstSpendTime">(.*?)</span>
#'''
pattern = pattern.replace('"', '\\"')
# pattern = pattern.replace('\n', '\\s*')
pattern = pattern.replace('\n', '')
# matches = re.findall(pattern, body, re.DOTALL)
pattern0 = '<tr(.*?)</tr>'
matches0 = re.findall(pattern0, body, re.DOTALL)
matches = []
reco = re.compile(pattern, re.DOTALL)
for match0 in matches0:
# matches1 = re.findall(pattern, match0, re.DOTALL)
matches1 = [m.groupdict() for m in reco.finditer(match0)]
matches.extend(matches1)
# print matches
# exit()
# for match in matches:
# print match[0], match[3], match[6], match[10], match[13], match[16], match[19], match[22], match[23], match[26], match[30], match[31], match[34], match[37], match[40], match[43], match[46], match[49]
# print match[26]
result = []
for match in matches:
# print match.group('OPDateString')
# exit()
r = {}
r['OPDate'] = remove_space(match['OPDateString'])
# r['OpRoomNo'] = remove_space(match[2])
# r['OpSeqNo'] = remove_space(match[4])
r['OpRoomNo'] = remove_tags(match['OpRoomNoShow'])
r['OpSeqNo'] = remove_tags(match['OpSeqNoshow'])
r['PatName'] = remove_space(match['LinkPatName'])
r['PatWard'] = remove_space(match['PopupPatWardInfoWindow'])
r['PatChartNo'] = remove_space(match['PatChartNo'])
r['PatSex'] = remove_space(match['PatSex'])
r['PatAgeTitle'] = remove_space(match['PatAgeTitle'])
r['PatAge'] = remove_space(match['PatAge'])
r['PatDignosis'] = remove_space(match['PatDignosis'])
r['MainOpModeTitle'] = remove_space(match['MainOpModeTitle'])
r['MainOpMode'] = remove_space(match['MainOpMode'])
r['OpDoctorName'] = remove_space(match['OpDoctorName'])
r['OpTypeName'] = remove_space(match['OpTypeName'])
r['Complete'] = remove_space(match['CompleteStatueName'])
r['Anes'] = remove_space(match['lbtPrint'])
r['StartTime'] = remove_space(match['EstStartTimeShortString'])
r['SpendTime'] = remove_space(match['EstSpendTime'])
# print match
# print r
# exit()
result.append(r)
return result
def PatientMedicalRecordListQuery(Chart, SESSION = None):
if SESSION is None:
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$PersonIDInputTextBox"] = PersonID
# br["NTUHWeb1$ChartInputTextBox"] = Chart
br["NTUHWeb1$PatientBasicInfoQueryByIDAndName1$ctl01"] = Chart
# response = br.submit('NTUHWeb1$ButtonQuery')
response = br.submit('NTUHWeb1$PatientBasicInfoQueryByIDAndName1$ctl09')
html = response.read()
patient = {}
pattern = r'<span id="NTUHWeb1_PatAccountListRecord1_PatBasicDescription">(?P<name>.*?)\((?P<gender>.*?),(?P<birthday>.*?),(?P<age>.*?)\) \((?P<branch>.*?)\)</span>'
r = re.compile(pattern)
d = [m.groupdict() for m in r.finditer(html)]
patient.update(d[0])
pattern = '''
InLabelWardName">(?P<WardName>.*?)</span>
</font></td><td><font color="#333333" size="2">
.*?_InLabelRoomName">(?P<RoomName>.*?)</span>
</font></td><td><font color="#333333" size="2">
.*?_InLabelBedName">(?P<BedName>.*?)</span>
</font></td><td><font color="#333333" size="2">
.*?_InLabelMainDrName">(?P<MainDrName>.*?)</span>
</font></td><td width="40%"><font color="#333333" size="2">
.*?_InLabelMainDiagnosisName">(?P<MainDiagnosisName>.*?)</span>
'''
pattern = pattern.strip().replace('\n','\s*')
r = re.compile(pattern)
d = [m.groupdict() for m in r.finditer(html)]
patient['InPatRecord'] = d
pattern = '''
LabelMainDrName">(?P<MainDrName>.*?)</span>
.*?
.*?_LabelMainDiagnosisName">(?P<MainDiagnosisName>.*?)</span>
'''
pattern = pattern.strip().replace('\n','\s*')
# pattern = pattern.replace('%', '\\%')
r = re.compile(pattern)
d = [m.groupdict() for m in r.finditer(html)]
patient['OutPatRecord'] = d
# print patient
return patient
def operationnotelist(Chart, SESSION = None):
if SESSION is None:
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.select_form('[name="Form1"]')
# br["NTUHWeb1$PersonIDInputTextBox"] = PersonID
# br["NTUHWeb1$ChartInputTextBox"] = Chart
br["NTUHWeb1$PatientBasicInfoQueryByIDAndName1$ctl01"] = Chart
# response = br.submit('NTUHWeb1$ButtonQuery')
# response = br.submit('NTUHWeb1$PatientBasicInfoQueryByIDAndName1$ctl09')
response = br.submit_selected('NTUHWeb1$PatientBasicInfoQueryByIDAndName1$ctl09')
# br.select_form(name="Form1")
br.select_form('[name="Form1"]')
# request = br.click("NTUHWeb1$PatAccountListRecord1$ShowOperationList")
# response = mechanize.urlopen(request)
# response = br.submit("NTUHWeb1$PatAccountListRecord1$ShowOperationList")
response = br.submit_selected("NTUHWeb1$PatAccountListRecord1$ShowOperationList")
'''
<form name=operationnotelist action='http://ihisaw.ntuh.gov.tw/WebApplication/OtherIndependentProj/PatientBasicInfoEdit/SimpleInfoShowUsingPlaceHolder.aspx?SESSION=A71FAC405B2D4E10865E94BCF1AFF563' target="operationnotelist" method="post" >
<input type=hidden name="KeyCodeList" value=2010-T0-046815|2010-T0-014806|2010-T0-014453|2010-T0-009297|2010-T0-006240|2010-T0-004275|2009-T0-056119|DWJ1211906971228>
<input type=hidden name="KeyNameList" value=SURG_2010/10/22|SURG_2010/04/10|SURG_2010/04/08|SURG_2010/03/08|SURG_2010/02/09|SURG_2010/01/29|SURG_2009/12/28|SURG_2009/12/28>
<input type=hidden name="Func" value=OPNoteList>
</form><script language='javascript'>operationnotelist.submit();</script>
'''
# print response.read()
# return
# matches = re.findall("&PersonID=(.*?)&Func=OPNoteList&Seed=", response.read())
matches = re.findall("&PersonID=(.*?)&Func=OPNoteList&Seed=", response.text)
PersonID = matches[0]
url2 = 'http://ihisaw.ntuh.gov.tw/WebApplication/OtherIndependentProj/PatientBasicInfoEdit/SimpleInfoShowUsingPlaceHolder.aspx?SESSION=%s&PersonID=%s&Func=OPNoteList' % (SESSION, PersonID)
response = br.open(url2)
# print response.read()
pattern ="'TreeViewItem','(.*?)'\)(.*?)>(.*?)</a>"
# pattern = 'name="KeyCodeList" value=(.*?)><input type=hidden name="KeyNameList" value=(.*?)>'
# matches=re.findall(pattern, response.read())
matches=re.findall(pattern, response.text)
# print matches
# print KeyCodeList, KeyNameList
# br.select_form('operationnotelist')
# response = br.submit()
KeyCode = []
KeyName = []
for m in matches:
KeyCode.append(m[0][1:])
KeyName.append(m[2])
return (KeyCode, KeyName)
def ShowOperationNote(KeyCodeList, KeyNameList, SESSION=None):
# print(KeyCodeList, KeyNameList)
if SESSION is None:
SESSION = Login()
url = 'http://ihisaw.ntuh.gov.tw/WebApplication/OtherIndependentProj/PatientBasicInfoEdit/SimpleInfoShowUsingPlaceHolder.aspx?SESSION=%s' % SESSION
data = {
'KeyCodeList': KeyCodeList,
'KeyNameList': KeyNameList,
'Func' : 'OPNoteList',
}
# response = br.open(url, urllib.urlencode(data))
response = br.post(url, data)
# body = response.read()
body = response.text
pattern ='(<div class="reportQuery">.*?</div>)\\s*?</td>'
matches=re.findall(pattern, body, re.DOTALL)
return matches[0]
def op_note_case(ChartNo):
pattern = '''
手術日期</TD><TD>(?P<SurgeryDate>.*?)</TD>
(.*?)手術主治醫師</TD><TD>(?P<Surgeon>.*?)</TD>
(.*?)手術科部: </SPAN>(?P<Division>.*?)<SPAN class="queryText" >
(.*?)Operative Method</TD></TR><TR><TD>(?P<NameSurgery>.*?)<
'''.replace('\n', '').replace('"', '\\"')
KeyCode, KeyName = operationnotelist(ChartNo)
result = []
for i in range(len(KeyCode)):
body = ShowOperationNote(KeyCode[i], KeyName[i])
matches = [m.groupdict() for m in re.finditer(pattern, body, re.DOTALL)]
# print matches[0]
# return
r = {}
r['surgery_date_time'] = matches[0]['SurgeryDate'].replace('/','-')
r['division'] = remove_space(matches[0]['Division'])
r['name_surgery'] = remove_space(matches[0]['NameSurgery'])
r['surgeon'] = remove_space(matches[0]['Surgeon'])
result.append(r)
return result