from pathlib import PureWindowsPath import base64 import datetime import re import time from appium import webdriver from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from models import * MIN_NUM_IMAGES = 9 RootPath = PureWindowsPath(r'S:\storage\0') RunStamp = base64.urlsafe_b64encode(int(time.time()).to_bytes(4,'big')).decode().replace('=','') RunPath = RootPath/RunStamp print(RunStamp, RunPath) session = Session() def launchApp(desired_caps): # desired_caps["ms:experimental-webdriver"] = True # dut_url = "http://win10z:4723" dut_url = "http://192.168.11.101:4723" driver = webdriver.Remote( command_executor = dut_url, desired_capabilities = desired_caps) return driver def getDriverFromWin( win): win_handle1 = win.get_attribute("NativeWindowHandle") win_handle = format(int(win_handle1), 'x') # convert to hex string # Launch new session attached to the window desired_caps = {} desired_caps["appTopLevelWindow"] = win_handle driver = launchApp(desired_caps) driver.switch_to.window(win_handle) return driver def getDict(row): d = {} # num_images = row.find_elements_by_name('study.num_images') # if not num_images or int(num_images[0] < 9): # return d # for e in row.find_elements_by_xpath('//DataItem'): for e in row.find_elements_by_tag_name('DataItem'): # d[e.get_attribute('Name')] = e.get_attribute('Value.Value') name = e.get_attribute('Name').strip() value = e.get_attribute('Value.Value') if value: value = value.strip() d[name] = value # if name == 'study.num_images' and int(value) quality: down.click() export = view.find_element_by_xpath(r'//Edit[@Name="匯出位置:"]') while len(export.text): export.send_keys(Keys.BACKSPACE) export.send_keys(str(exportPath)+'\\') # exit() driver.find_element_by_accessibility_id('btnOK').click() driver.find_element_by_accessibility_id('btnCancel').click() # desktop2.close() # desktop2.quit() def screen_1x1(): # top = WebDriverWait(driver, 600).until( # EC.presence_of_element_located((By.ACCESSIBILITY_ID, "TOP_TOOLBAR0")) # ) box = desktop.find_elements_by_accessibility_id('GenericDialogBox') if box: box[0].find_element_by_name("確定").click() # if driver.find_element_by_accessibility_id('StudyImageViewer').find_elements_by_name("Screen_0_format_5_Position_0_0"): # return top = driver.find_element_by_accessibility_id("TOP_TOOLBAR0") button = top.find_element_by_xpath('//Button[5]') ActionChains(driver).click(button).perform() AfxWnd90u = driver.find_element_by_xpath(r'//Pane[@ClassName="AfxWnd90u"][1]') ActionChains(driver).click(AfxWnd90u).perform() return # desktop = launchApp({'app': 'Root'}) # # position = driver.find_element_by_accessibility_id('StudyImageViewer').find_element_by_name("Screen_0_format_5_Position_0_0") # box = desktop.find_elements_by_accessibility_id('GenericDialogBox') # if box: # box[0].find_element_by_name("確定").click() # for i in range(3): # desktop = launchApp({'app': 'Root'}) # win = desktop.find_element_by_accessibility_id('ApplicationView') # d2 = getDriverFromWin(win) # StudyImageViewer = d2.find_elements_by_accessibility_id('StudyImageViewer') # if StudyImageViewer: # position = StudyImageViewer[0].find_elements_by_name("Screen_0_format_5_Position_0_0") # if position: # break # print('screen 1x1', i) # top = d2.find_elements_by_accessibility_id("TOP_TOOLBAR0") # if top: # button = top[0].find_element_by_xpath('//Button[5]') # ActionChains(d2).click(button).perform() # AfxWnd90u = d2.find_element_by_xpath(r'//Pane[@ClassName="AfxWnd90u"][1]') # ActionChains(d2).click(AfxWnd90u).perform() pattern_series_uid = r'series_uid ] = "([.0-9T]+)"' prog_series_uid = re.compile(pattern_series_uid) def getSeriesDocument(): screen_1x1() position = driver.find_element_by_accessibility_id('StudyImageViewer').find_element_by_name("Screen_0_format_5_Position_0_0") # position = screen_1x1() ActionChains(driver).key_down(Keys.LEFT_CONTROL).context_click(position).key_down(Keys.LEFT_CONTROL).perform() ActionChains(desktop).send_keys(Keys.ARROW_DOWN).perform() ActionChains(desktop).send_keys(Keys.ARROW_DOWN).perform() DisplayMenuForm = desktop.find_element_by_accessibility_id('DisplayMenuForm0') ActionChains(desktop).move_to_element(DisplayMenuForm.find_element_by_name('資訊')).perform() # ActionChains(desktop).click(DisplayMenuForm.find_element_by_name('服務視窗')).perform() DisplayMenuForm.find_element_by_name('服務視窗').click() # DisplayMenuForm.find_element_by_accessibility_id('lr_informationStrip').click() # DisplayMenuForm.find_element_by_accessibility_id('資訊Strip_SubMenu').click() position.click() tool = driver.find_element_by_name("Display Service Tool") doc = [] for e in tool.find_elements_by_xpath("//Document"): # print(e, e.tag_name, e.text, e.get_attribute('AutomationId')) doc.append(e.text) result = prog_series_uid.search(doc[1]) print(result) # [ series, date_time_modified ] = 1453532533 ( 4, 4 )\r\n # [ series, series_number ] = "3" ( 1, 2 )\r\n # [ series, manufacturer ] = "GE MEDICAL SYSTEMS" ( 18, 19 )\r\n # [ series, series_ref ] = 31044392 ( 8, 8 )\r\n # [ series, manufacturer_model_name ] = "Signa HDxt" ( 10, 11 )\r\n # [ series, series_time ] = "150149" ( 6, 7 )\r\n # [ series, series_uid ] = "1.2.840.113619.2.244.6945.1127238.26918.1453507651.969" ( 54, 55 )\r\n # [ series, modality ] = "MR" ( 2, 3 )\r\n # [ series, station_name ] = "CGEMR1C1" ( 8, 9 )\r\n # [ series, study_ref ] = 29907821 ( 8, 8 )\r\n # [ series, series_date ] = "20160123" ( 8, 9 )\r\n # [ series, date_time_created ] = 1453532533 ( 4, 4 )\r\n # [ series, series_description ] = "Ax T2 FLAIR" ( 11, 12 ) tool.find_element_by_accessibility_id('Close').click() ActionChains(driver).context_click(position).perform() return result[1], doc def getStudyByViewer(accessionNumber, studyPath): # ### Get study report last # driver.find_element_by_accessibility_id('ShowTextArea').click() # # driver.find_element_by_accessibility_id('reportTab').click() # report = driver.find_element_by_accessibility_id('reportControl').find_element_by_xpath('//Document').text # driver.find_element_by_accessibility_id('_textAreaHideButton').click() # print(report) # exit() # time.sleep(1) # Make it 1x1 view, Try to moved to saveSeries and getSeriesDocument? # driver.find_element_by_accessibility_id("TOP_TOOLBAR0").find_element_by_xpath('//Button[5]').click() # driver.find_element_by_xpath(r'//Pane[@ClassName="AfxWnd90u"][1]').click() # top = WebDriverWait(driver, 20).until( # EC.presence_of_element_located((By.ACCESSIBILITY_ID, "TOP_TOOLBAR0")) # ) screen_1x1() # top = win.find_element_by_accessibility_id("TOP_TOOLBAR0") # button = top.find_element_by_xpath('//Button[5]') # button.click() # AfxWnd90u = win.find_element_by_xpath(r'//Pane[@ClassName="AfxWnd90u"][1]') # AfxWnd90u.click() # driver = getDriverFromWin(win) items = driver.find_elements_by_xpath(r'//ListItem[@AutomationId="ListViewItem-0"]/../ListItem') if len(items) == 0: toolbar = driver.find_element_by_accessibility_id("STANDARD_TOOLBAR0") toolbar.find_element_by_xpath('//Button[1]').click() items = driver.find_elements_by_xpath(r'//ListItem[@AutomationId="ListViewItem-0"]/../ListItem') num_images = 0 for c in driver.find_elements_by_xpath(r'//ListItem[@AutomationId="ListViewItem-0"]/../ListItem'): # AutomationId = print(c.get_attribute('AutomationId'), c.tag_name, c.text) ActionChains(driver).double_click(c).perform() name = c.text num_images += int(name.split(' : ')[1]) uid, doc = getSeriesDocument() # print(doc) # print(uid) s = session.query(Series).get(uid) if s is None: s = Series(series_uid = uid) session.add(s) s.name = name s.document0 = doc[0] s.document1 = doc[1] s.accession_number = accessionNumber # p.saved = datetime.datetime.now() session.commit() # Save Demographics shown saveSeries(100, studyPath / 'shown' / s.slugify()) driver.find_element_by_accessibility_id("TOP_TOOLBAR0").find_element_by_xpath('//Button[1]').click() # Save Demographics hidden saveSeries(100, studyPath / 'hidden' / s.slugify()) driver.find_element_by_accessibility_id("TOP_TOOLBAR0").find_element_by_xpath('//Button[1]').click() ### Get study report last driver.find_element_by_accessibility_id('ShowTextArea').click() try: report = driver.find_element_by_accessibility_id('reportControl').find_element_by_xpath('//Document').text except: report = None driver.find_element_by_accessibility_id('_textAreaHideButton').click() s = session.query(Study).get(accessionNumber) if s is None: s = Study(accession_number = accessionNumber) session.add(s) s.report = report if s.num_images == num_images and (report or (datetime.date.today()-s.study_date).days>99): s.success = True s.run = RunStamp session.commit() def getStudyByGrid(study, patientPath): # print(patientPath) # exit() # print(driver.find_element_by_accessibility_id("TOP_TOOLBAR0")) driver.find_element_by_accessibility_id("resetButton").click() # driver.find_element_by_accessibility_id("accessionNumberText").find_element_by_xpath(r'//Edit[@Name="檢查流水號"]').send_keys(accessionNumber) accession = win.find_element_by_accessibility_id('accessionNumberText').find_element_by_tag_name('Edit') edit_input(accession, study.accession_number.replace('@', '')) # accession.send_keys(study.accession_number) # time.sleep(1) # if accession.text != study.accession_number: # Chinese input method? # accession.send_keys(Keys.LEFT_SHIFT) # accession.send_keys(Keys.BACKSPACE * len(study.accession_number)) # accession.send_keys(study.accession_number) driver.find_element_by_accessibility_id("searchButton").click() grid = driver.find_element_by_accessibility_id("grid") # print(1) # for i, e in enumerate(grid.find_elements_by_xpath('*')): # print(e, e.tag_name, e.text) # exit() # print(2) for i, e in enumerate(grid.find_elements_by_xpath('//DataItem[@Name="View"]/..')): print(i, e.tag_name) d = getDict(e) print(d) if 'study.num_images' not in d or int(d['study.num_images']) < MIN_NUM_IMAGES: continue # 取回 nearline, But dont wait if d['View'] == 'nearline': ActionChains(driver).context_click(e.find_element_by_name('View')).perform() # desktop.find_element_by_xpath(r'Pane/Menu[@Name="路徑位置"]/MenuItem[@Name="取回"]').click() desktop.find_element_by_name('路徑位置').find_element_by_name("取回").click() # faster print('skip nearline',study.accession_number) return ActionChains(driver).double_click(e.find_element_by_name('View')).perform() # print(study.naming()) # exit() # getStudyByViewer(study.accession_number, patientPath/(datetime.datetime.strptime(d['study.study_date'], '%Y/%m/%d').strftime('%Y-%m-%d-')+accessionNumber)) getStudyByViewer(study.accession_number, patientPath/study.naming()) #close image viewer CloseItemPanel() # exit() # "/Pane[@ClassName=\"#32769\"][@Name=\"桌面 1\"]/Window[@Name=\"IMPAX 6.5.2.114 Enterprise Unlimited\"][@AutomationId=\"ApplicationView\"]/Pane[@AutomationId=\"displayPanel\"]/Pane[@AutomationId=\"DisplayView\"]/Pane[@Name=\"TOP_TOOLBAR0\"][starts-with(@AutomationId,\"TOP_TOOLBAR\")]/Button[starts-with(@ClassName,\"WindowsForms10\")]"; def getPatient(ID, rescanStudy = True): if rescanStudy: driver.find_element_by_accessibility_id("resetButton").click() # patientId = win.find_element_by_accessibility_id('patientIdText').find_element_by_xpath(r'//Edit[@Name="病歷號碼"]') # patientId = win.find_element_by_accessibility_id('patientIdText').find_element_by_tag_name('Edit') patientId = driver.find_element_by_accessibility_id('patientIdText').find_element_by_tag_name('Edit') edit_input(patientId, ID) # patientId.send_keys(ID) # time.sleep(1) # if patientId.text != ID: # Chinese input method? # patientId.send_keys(Keys.LEFT_SHIFT) # patientId.send_keys(Keys.BACKSPACE * len(ID)) # patientId.send_keys(ID) # driver.find_element_by_accessibility_id("patientIdText").find_element_by_xpath(r'//Edit[@Name="病歷號碼"]').send_keys(patientId) driver.find_element_by_accessibility_id("searchButton").click() grid = driver.find_element_by_accessibility_id("grid") try: DownButton = grid.find_element_by_accessibility_id("DownButton") except: DownButton = None print(1) # for i, e in enumerate(grid.find_elements_by_xpath('*/*')): # for i, e in enumerate(grid.find_elements_by_xpath('//DataItem[@Name="View"]/..')): for i, e in enumerate(grid.find_elements_by_xpath('*/Custom')): print(i, e.tag_name, e.text) if not e.text.isdigit(): continue d = getDict(e) print(d) if ('study.accession_number' not in d) or not d['study.accession_number']: continue p = session.query(Patient).get(d['patient.patient_id']) if p is None: p = Patient(patient_id = d['patient.patient_id']) session.add(p) p.patient_name = d['patient.patient_name'] p.patient_name_ph_utf8 = d['patient.patient_name_ph_utf8'] # p.saved = datetime.datetime.now() session.commit() s = session.query(Study).get(d['study.accession_number']) if s is None: s = Study(accession_number = d['study.accession_number']) session.add(s) # else: # #skip study already success # if s.success: # continue s.date_time_created = d['study.date_time_created'] s.modality = d['study.modality'] s.num_images = d['study.num_images'] s.status = d['study.status'] s.study_date = datetime.datetime.strptime(d['study.study_date'], '%Y/%m/%d') s.study_description = d['study.study_description'] s.study_time = d['study.study_time'] s.patient_id = d['patient.patient_id'] # p.saved = datetime.datetime.now() session.commit() # if int(d['study.num_images']) < MIN_NUM_IMAGES: # continue # if 'View'in d and d['View']==None: # driver.find_element_by_accessibility_id("DownButton").click() # exit() # continue if (not s.success) and s.num_images > MIN_NUM_IMAGES: # if d['View'] not in ['Available', 'VIEWABLE', 'VIEWING']: if d['View'] == 'nearline': ActionChains(driver).context_click(e.find_element_by_name('View')).perform() # desktop.find_element_by_xpath(r'Pane/Menu[@Name="路徑位置"]/MenuItem[@Name="取回"]').click() desktop.find_element_by_name('路徑位置').find_element_by_name("取回").click() # faster # getDriverFromWin(desktop.find_element_by_name('路徑位置')).find_element_by_name("取回").click() # print(desktop.find_element_by_xpath(r'Pane/Menu[@Name="路徑位置"]/MenuItem[@Name="取回"]')) # exit() if DownButton: DownButton.click() if DownButton: UpPageButton = grid.find_element_by_accessibility_id("UpPageButton") try: while True: UpPageButton.click() except: pass if p.counter is None: p.counter = 1 else: p.counter += 1 session.commit() for study in session.query(Patient).get(ID).studies: if study.success or study.num_images < MIN_NUM_IMAGES: continue getStudyByGrid(study, RunPath/ID) if __name__ == '__main__': rescan = True getPatient('3009684', rescanStudy=rescan) # getPatient('2347157', rescanStudy=rescan) # getStudyByViewer('T0159343504', r'S:\storage\0') # getStudyByGrid('T0159343504', r'S:\storage\0')