ver Mar10th

changed AT element filtering
This commit is contained in:
David Chang
2024-03-10 18:03:02 +08:00
parent ce23f3dab4
commit f08fa4912c
7 changed files with 322 additions and 37 deletions

1
.gitignore vendored
View File

@@ -171,6 +171,7 @@ tags-opts
snapshots snapshots
*.syncthing.*.tmp *.syncthing.*.tmp
cache cache
version.folder
test.xlsx test.xlsx
test2.xlsx test2.xlsx

4
at_processing/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/*.json
/*.xml
/*.list
/*.png

249
at_processing/filter.anal Normal file
View File

@@ -0,0 +1,249 @@
vimc: hi AnalSecTitle term=bold cterm=bold:
vimc: syn match AnalSecTitle /^|\d\+\.\ .*$/:
vimc: syn match Comment /^#.*$/:
vimc: hi AnalMetaInfo term=italic ctermfg=red:
vimc: syn match AnalMetaInfo /^[A-Z]\:\ /:
vimc: syn match Todo /\<TODO\>\|^I\:/:
vimc: hi VIMC ctermfg=grey:
vimc: syn match VIMC /^vimc\:\ .*\:$/:
vimc: hi AnalComplete term=reverse,bold ctermfg=green:
vimc: syn match AnalComplete /✓$/:
vimc: hi AnalFail term=reverse,bold ctermfg=red:
vimc: syn match AnalFail /✗$/:
vimc: hi AnalInfoElm term=reverse,bold ctermfg=cyan:
vimc: syn match AnalInfoElm /\<i$/:
# 分析如何按照UFO的规则过滤AT元素
# E: 列出元素类型
# P: 列出属性
# R: 引用
UFO中保留的十一种元素类型
E: Button, Edit, TabItem, Document, ListItem, MenuItem, ScrollBar, TreeItem, Hyperlink, ComboBox, RadioButton
|1. GNOME上元素类型
R: ubuntu-tag.shrunk.list
alert 3 ✓
animation 29
application 12
canvas 6 ✓
check-box 17 ✓
check-menu-item 1263 ✓
combo-box 19 ✓
desktop-frame 1
dialog 1
document-frame 4 ✓
document-presentation 1 ✓
document-spreadsheet 1 ✓
document-text 1 ✓
document-web 10 ✓
drawing-area 1
embedded 1
entry 8 ✓
filler 264
form 2
frame 15
heading 36 ✓
icon 96 ✓
image 246 ✓
image-map 1
internal-frame 10
label 170 ✓
landmark 12
layered-pane 3
link 315 ✓
list 17
list-box 7
list-item 145 ✓
menu 546
menu-bar 12
menu-item 2392 ✓
notification 45
page 21
page-tab 16
page-tab-list 9
panel 362
paragraph 42 ✓
popup-menu 9
push-button 612 ✓
radio-button 28 ✓
radio-menu-item 174 ✓
root-pane 3
ruler 1
scroll-bar 46 ✓
scroll-pane 28
section 568 ✓
separator 879
slider 1 ✓
split-pane 11
static 76 ✓
status-bar 7
table 5
table-cell 841 ✓
table-column-header 42 ✓
table-row 8
terminal 1 ✓
text 27 ✓
toggle-button 123 ✓
tool-bar 63
tree 5
tree-item 14 ✓
tree-table 1
unknown 9
viewport 13
| 2. Windows上元素类型
R: windows-tag.list
_wwf 1
address-band-root 1
backforwardbutton 1 ✓
boxlayoutview 1
breadcrumb-parent 1
browserappmenubutton 1 ✓
browsercaptionbuttoncontainer 1
browserframeviewwin 1
browserrootview 1
browserview 1
bubbledialogdelegateview 1
bubbleframeview 1
button 6 ✓
cabinetwclass 1
chrome_widgetwin_1 2
consolewindowclass 1
container 1
desktop 1
dialogclientview 1
duilistview 1
duiviewwndclassname 1
dynamiccontent1 1
dynamiccontent2 1
edgeavatartoolbarbutton 1 ✓
edgehubappstowerscreenshotbutton 1 ✓
edgehubappstowerscrollview 1
edgehubappstowertoggletoolbarbutton 10 ✓
edgehubappstowerview 1
edgenewtabbutton 1 ✓
edgetab 2
edgetabactionsmenubutton 1 ✓
edgetabclosebutton 2 ✓
edgetabcontainerimpl 1
edgetabstrip 1
edgetabstripregionview 1
element 1
excel- 2
excel2 2
framegrabhandle 1
fullpageuihost 3
hubtoggletoolbarbutton 3 ✓
imemodebutton 1 ✓
linevscrollbar 1 ✓
locationbarview 1
locationiconview 1
mdiclient 1
metadatalabel 1 ✓
modernsearchbox 1 ✓
msctls_progress32 1
mstasklistwclass 1
netuiappframehelper 12
netuielement 3
netuifullpageuiwindow 3
netuihwnd 1
netuihyperlink 3 ✓
netuikeyboardtabelement 3 ✓
netuilabel 9 ✓
netuilistview 6
netuilistviewitem 27 ✓
netuiofficecaption 3
netuioutspacebutton 3 ✓
netuipanviewer 3
netuiribbontab 15 ✓
netuiscrollbar 6 ✓
netuiscrollviewer 12
netuisimplebutton 6 ✓
netuislabcontainer 6
netuislabexpandcollapsebutton 3 ✓
netuitabheader 6 ✓
nonclientview 2
nuipane 1
omniboxviewviews 1
opusapp 1
pageactioniconcontainerview 1
pageactioniconview 1
pptframeclass 1
progman 1
propertreehost 1
rebarwindow32 1
reloadbutton 1 ✓
rootview 1
scrollview 1
scrollview--viewport 1
selectorbutton 2 ✓
selectornodefault 1
separator 2
separatorband 2
shell_traywnd 1
shelltabwindowclass 1
sidebarcontentssplitview 5
splitwindowcontainerview 1
start 1 ✓
starview 1
statusbarmoduleinner 1
syslistview32 1
syspager 1
systreeview32 1
tabstrip--edgetabdragcontextimpl 1
textfield 1 ✓
toolbarhubiconcontainerview 1
toolbarsplitwindowbutton 1 ✓
toolbarview 1
toolbarview--containerview 1
toolbarwindow32 5
topcontaineroverlayview 1
topcontainerview 1
towerhubiconcontainerview 1
travelband 1
traybutton 2 ✓
trayclockwclass 1 ✓
traydummysearchcontrol 1 ✓
trayinputindicatorwclass 1
traynotifywnd 1
trayshowdesktopbuttonwclass 1
uicolumnheader 4
uiimage 24 ✓
uiitem 24 ✓
uiitemsview 1
uiproperty 96 ✓
uiribboncommandbar 1 ✓
uiribboncommandbardock 1
uiribbonworkpane 1
uiviewheader 1 ✓
universalsearchband 1
unknown 92
upband 1
view 7
windowedfindbarfocusproxyview 1
windowscaptionbutton 3 ✓
worker-window 1
xldesk 1
xlmain 1
|3. 筛选属性
UFO中筛选的几种元素属性
P: is_visible, is_enabled, title_list, class_name_list
对Ubuntu照葫芦画瓢筛选
P: visible & showing
P: enabled
P: name
P: text
对Windows筛选
P: visible
P: enabled
P: name
P: text

View File

@@ -0,0 +1,22 @@
#!/usr/bin/python3
import lxml.etree
from lxml.etree import _Element
from typing import Counter
import json
import collections
file_name = "w0"
with open("{:}.json".format(file_name)) as f:
xml_str: str = json.load(f)["AT"]
root: _Element = lxml.etree.fromstring(xml_str)
with open("{:}.xml".format(file_name), "w") as f:
f.write(lxml.etree.tostring(root, encoding="unicode", pretty_print=True))
#root: _Element = lxml.etree.parse("{:}.xml".format(file_name)).getroot()
node_types: Counter[str] = collections.Counter()
for n in root.iter():
node_types[n.tag] += 1
for n in sorted(node_types):
print(n, node_types[n])

View File

@@ -276,12 +276,12 @@ def _create_atspi_node(node: Accessible, depth: int = 0, flag: Optional[str] = N
# only text shown on current screen is available # only text shown on current screen is available
# attribute_dict["txt:text"] = text_obj.getText(0, text_obj.characterCount) # attribute_dict["txt:text"] = text_obj.getText(0, text_obj.characterCount)
text: str = text_obj.getText(0, text_obj.characterCount) text: str = text_obj.getText(0, text_obj.characterCount)
if flag=="thunderbird": #if flag=="thunderbird":
# appeard in thunderbird (uFFFC), "Object Replacement Character" in # appeard in thunderbird (uFFFC) (not only in thunderbird), "Object
# Unicode, "used as placeholder in text for an otherwise # Replacement Character" in Unicode, "used as placeholder in text for
# unspecified object; uFFFD is another "Replacement Character", # an otherwise unspecified object; uFFFD is another "Replacement
# just in case # Character", just in case
text = text.replace("\ufffc", "").replace("\ufffd", "") text = text.replace("\ufffc", "").replace("\ufffd", "")
# }}} Text # # }}} Text #
# Selection {{{ # # Selection {{{ #

View File

@@ -57,7 +57,7 @@
{ {
"type": "launch", "type": "launch",
"parameters": { "parameters": {
"command": ["nautilus"] "command": ["nautilus", "/home/user/Documents/Finance"]
} }
} }
], ],

View File

@@ -25,35 +25,42 @@ def find_leaf_nodes(xlm_file_str):
return leaf_nodes return leaf_nodes
def filter_nodes(nodes): def filter_nodes(nodes, platform="ubuntu"):
filtered_nodes = [] filtered_nodes = []
for node in nodes: for node in nodes:
if not node.get('{uri:deskat:state.at-spi.gnome.org}visible', None) == 'true': if node.tag.startswith("document")\
# Not visible or node.tag.endswith("item")\
continue or node.tag.endswith("button")\
# Check if the node is a 'panel' or node.tag.endswith("heading")\
if node.tag == 'panel': or node.tag.endswith("label")\
# Check if the 'panel' represents an interactive element or node.tag.endswith("bar")\
# or if it has certain attributes that are of interest. or node.tag.endswith("searchbox")\
# Add your conditions here... or node.tag.endswith("textbox")\
if node.get('{uri:deskat:state.at-spi.gnome.org}focusable', 'false') == 'true': or node.tag.endswith("link")\
filtered_nodes.append(node) or node.tag.endswith("tabelement")\
elif node.tag == 'text': or node.tag.endswith("textfield")\
continue or node.tag.endswith("textarea")\
elif node.get("name") == "" and node.text is None: or node.tag in [ "alert", "canvas", "check-box"
continue , "combo-box", "entry", "icon"
else: , "image", "paragraph"
coords = tuple( , "section", "slider", "static"
map(int, node.attrib.get('{uri:deskat:component.at-spi.gnome.org}screencoord').strip('()').split(', '))) , "table-cell", "terminal", "text"
if coords[0] < 0 or coords[1] < 0: , "netuiribbontab", "start", "trayclockwclass"
continue , "traydummysearchcontrol", "uiimage", "uiproperty"
size = tuple( ]:
map(int, node.attrib.get('{uri:deskat:component.at-spi.gnome.org}size').strip('()').split(', '))) if ( platform=="ubuntu"\
if size[0] <= 0 or size[1] <= 0: and node.get("{{{:}}}showing".format("uri:deskat:state.at-spi.gnome.org"), "false")=="true"\
continue and node.get("{{{:}}}visible".format("uri:deskat:state.at-spi.gnome.org"), "false")=="true"\
# Node is not a 'panel', add to the list. or platform=="windows"\
filtered_nodes.append(node) and node.get("{{{:}}}visible".format("uri:deskat:state.at-spi.gnome.org"), "false")=="true"\
)\
and node.get("{{{:}}}enabled".format("uri:deskat:state.at-spi.gnome.org"), "false")=="true"\
and (node.get("name", "") != "" or node.text is not None and len(node.text)>0):
coordinates: Tuple[int, int] = eval(node.get("{{{:}}}screencoord".format("uri:deskat:component.at-spi.gnome.org")))
sizes: Tuple[int, int] = eval(node.get("{{{:}}}size".format("uri:deskat:component.at-spi.gnome.org")))
if coordinates[0]>0 and coordinates[1]>0 and sizes[0]>0 and sizes[1]>0:
filtered_nodes.append(node)
return filtered_nodes return filtered_nodes
@@ -134,12 +141,14 @@ def print_nodes_with_indent(nodes, indent=0):
if __name__ == '__main__': if __name__ == '__main__':
with open('chrome_desktop_example_1.xml', 'r', encoding='utf-8') as f: import json
xml_file_str = f.read() with open('2.json', 'r', encoding='utf-8') as f:
xml_file_str = json.load(f)["AT"]
filtered_nodes = filter_nodes(find_leaf_nodes(xml_file_str)) filtered_nodes = filter_nodes(find_leaf_nodes(xml_file_str))
print(len(filtered_nodes)) print(len(filtered_nodes))
masks = draw_bounding_boxes(filtered_nodes, 'screenshot.png', masks = draw_bounding_boxes( filtered_nodes, '2.png'
'chrome_desktop_example_1_tagged_remove.png', ) , '2.a.png'
)
# print(masks) # print(masks)
print(len(masks)) print(len(masks))