add portal.py back

This commit is contained in:
Furen Xiao 2024-12-11 13:19:30 +08:00
parent 9d60ed1042
commit 9794234784

990
portal.py Executable file
View file

@ -0,0 +1,990 @@
# -*- 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