def generalize_annotations(annotation_data): ''' Implement this method to generalize your annotations. For example, you might generate path descriptors for each annotated node so that you can find these same nodes when interpreting a new screenshot. Or you might create a classifier using the annotations as training data. annotation_data.annotated_nodes: This argument is a list of annotations. An annotation consists of a tree node and the associated data. The associated data is a dict containing key/value pairs. It also It also contains the root node to the entire tree containing this annotation. See the interpret method for the specifications of the tree node object. annotation = annotated_nodes[0] is_text = annotation.data['is_text'] node = annotation.node root = annotation.root annotation_data.runtime_storage: This is a dict where you can store any information generalized from your annotations, such as path descriptors or learned classifiers. This data will be passed into the interpret method, and it will also be serialized to disk so that the layer does not need to recompute everything if Prefab exits and restarts. annotation = annotated_nodes[0] path = get_path( annotation.node ) runtime_storage[path] = annotation.data annotation_data.parameters: This is a dict of developer-provided parameters the layer can access to parameterize its behavior. The same parameters also available in the interpret method. For example, if you are translating the language of inter the layer might accept the specific language as a parameter. translation_language = parameters['language'] Here's an example that computes and stores path descriptors with the annotation data. ''' runtime_storage = annotation_data.runtime_storage runtime_storage.clear() annotated_nodes = annotation_data.annotated_nodes #importing the script for computing path descriptors from path_utils import get_path for anode in annotated_nodes: path = get_path(anode.node, anode.root) runtime_storage[path] = anode.data
def generalize_annotations(annotation_data): ''' Implement this method to generalize your annotations. For example, you might generate path descriptors for each annotated node so that you can find these same nodes when interpreting a new screenshot. Or you might create a classifier using the annotations as training data. annotation_data.annotated_nodes: This argument is a list of annotations. An annotation consists of a tree node and the associated data. The associated data is a dict containing key/value pairs. It also It also contains the root node to the entire tree containing this annotation. See the interpret method for the specifications of the tree node object. annotation = annotated_nodes[0] is_text = annotation.data['is_text'] node = annotation.node root = annotation.root annotation_data.runtime_storage: This is a dict where you can store any information generalized from your annotations, such as path descriptors or learned classifiers. This data will be passed into the interpret method, and it will also be serialized to disk so that the layer does not need to recompute everything if Prefab exits and restarts. annotation = annotated_nodes[0] path = get_path( annotation.node ) runtime_storage[path] = annotation.data annotation_data.parameters: This is a dict of developer-provided parameters the layer can access to parameterize its behavior. The same parameters also available in the interpret method. For example, if you are translating the language of inter the layer might accept the specific language as a parameter. translation_language = parameters['language'] Here's an example that computes and stores path descriptors with the annotation data. ''' runtime_storage = annotation_data.runtime_storage runtime_storage.clear() annotated_nodes = annotation_data.annotated_nodes #importing the script for computing path descriptors from path_utils import get_path for anode in annotated_nodes: path = get_path( anode.node, anode.root) runtime_storage[path] = anode.data
def recursively_tag_nodes(interpret_data, currnode): ''' This method recursively tags nodes that match path descriptors stored in the runtime_storage ''' transformer = interpret_data.tree_transformer from path_utils import get_path #import the method to retrieve path descriptors path = get_path(currnode, interpret_data.tree) if path in interpret_data.runtime_storage: #check if there is a corresponding path descriptor stored data = interpret_data.runtime_storage[path] for key in data: transformer.enqueue_set_tag(currnode, key, data[key]) for child in currnode.get_children(): recursively_tag_nodes(interpret_data, child)
def apply_text_corrections(interpret_data, currnode): ''' Walk through tree and use path descriptors to overwrite erroneous tags. ''' from path_utils import get_path #importing the method to compute path descriptors path = get_path(currnode, interpret_data.tree) #computing the path descriptor for the current node if path in interpret_data.runtime_storage: #if there is an annotation for this node and it has 'is_text' metadata #then tag the node with that data if 'is_text' in interpret_data.runtime_storage[path]: correction = interpret_data.runtime_storage[path]['is_text'] currnode['is_text'] = correction #recurse on the children of currnode for child in currnode.get_children(): apply_text_corrections(interpret_data, child)
def recursively_tag_widget_type(interpret_data, currnode): ''' This method visits each node in the hierarchy and tags it with its widget type. It heuristically guesses that elements larger than 100x100 are containers, and it uses stored annotations to override that label. ''' from path_utils import get_path path = get_path(currnode, interpret_data.tree) #import method to compute path descriptor runtime_storage = interpret_data.runtime_storage if path in runtime_storage: if 'widget_type' in runtime_storage[path]: currnode['widget_type'] = runtime_storage[path]['widget_type'] elif currnode.width > 100 and currnode.height > 100: currnode['widget_type'] = 'container' for child in currnode.get_children(): recursively_tag_widget_type(interpret_data, child)
def process_annotations( args ): args.saved_data.Clear() for node in args.annotated_nodes: if node.Node: if args.parameters.ContainsKey("use_path") and args.Parameters["use_path"] == "true": path = path_utils.get_path(node.Node, node.Root) else: path = path_utils.get_prototype_id_path(node.Node) data = args.saved_data[path] if not data: data = args.saved_data.CreateItem() key = node.Data['key'].ToString() val = node.Data['value'] data['keys'].Add( key ) data[key] = val data[ key + '-id' ] = node.Data['id'] data[ key + '-lib' ] = node.Data['lib'] args.saved_data[path] = data
def interpret_helper(node, root, args): if args.parameters.ContainsKey("use_path") and args.Parameters["use_path"] == "true": path = path_utils.get_path(node, root) else: path = path_utils.get_prototype_id_path(node) if path in args.saved_data: keys = args.saved_data[path]['keys'] for key in keys: key = key.ToString() val = args.saved_data[path][key].ToString() args.set_attribute( node, key, val) keyid = args.saved_data[path][key + '-id' ].ToString() args.set_attribute(node, key + '-id', keyid) srclib = args.saved_data[path][key + '-lib'].ToString() args.set_attribute(node, key + '-lib', srclib) children = node.GetChildren() for child in children: interpret_helper( child, root, args)