| Index: chrome/tools/extract_actions.py
|
| diff --git a/chrome/tools/extract_actions.py b/chrome/tools/extract_actions.py
|
| index df767b992dd03a53a0c0514280c426323b69d3db..3b9cbcb7ca0d2e160f199f66f194b3aec6e255e4 100755
|
| --- a/chrome/tools/extract_actions.py
|
| +++ b/chrome/tools/extract_actions.py
|
| @@ -20,10 +20,11 @@ If run with a "--hash" argument, chromeactions.txt will be updated.
|
|
|
| __author__ = 'evanm (Evan Martin)'
|
|
|
| +import hashlib
|
| +from HTMLParser import HTMLParser
|
| import os
|
| import re
|
| import sys
|
| -import hashlib
|
|
|
| sys.path.insert(1, os.path.join(sys.path[0], '..', '..', 'tools', 'python'))
|
| from google import path_utils
|
| @@ -40,8 +41,11 @@ KNOWN_COMPUTED_USERS = (
|
| 'new_tab_ui.cc', # most visited clicks 1-9
|
| 'extension_metrics_module.cc', # extensions hook for user metrics
|
| 'safe_browsing_blocking_page.cc', # various interstitial types and actions
|
| - 'language_options_handler.cc', # languages and input methods in chrome os
|
| + 'language_options_handler_common.cc', # languages and input methods in CrOS
|
| + 'cros_language_options_handler.cc', # languages and input methods in CrOS
|
| 'about_flags.cc', # do not generate a warning; see AddAboutFlagsActions()
|
| + 'external_metrics.cc', # see AddChromeOSActions()
|
| + 'core_options_handler.cc' # see AddWebUIActions()
|
| )
|
|
|
| # Language codes used in Chrome. The list should be updated when a new
|
| @@ -222,7 +226,8 @@ def GrepForActions(path, actions):
|
| number_of_files_total = number_of_files_total + 1
|
| # we look for the UserMetricsAction structure constructor
|
| # this should be on one line
|
| - action_re = re.compile(r'UserMetricsAction\("([^"]*)')
|
| + action_re = re.compile(r'[^a-zA-Z]UserMetricsAction\("([^"]*)')
|
| + malformed_action_re = re.compile(r'[^a-zA-Z]UserMetricsAction\([^"]')
|
| computed_action_re = re.compile(r'UserMetrics::RecordComputedAction')
|
| line_number = 0
|
| for line in open(path):
|
| @@ -230,20 +235,104 @@ def GrepForActions(path, actions):
|
| match = action_re.search(line)
|
| if match: # Plain call to RecordAction
|
| actions.add(match.group(1))
|
| + elif malformed_action_re.search(line):
|
| + # Warn if this line is using RecordAction incorrectly.
|
| + print >>sys.stderr, ('WARNING: %s has malformed call to RecordAction'
|
| + ' at %d' % (path, line_number))
|
| elif computed_action_re.search(line):
|
| # Warn if this file shouldn't be calling RecordComputedAction.
|
| if os.path.basename(path) not in KNOWN_COMPUTED_USERS:
|
| - print >>sys.stderr, 'WARNING: {0} has RecordComputedAction at {1}'.\
|
| - format(path, line_number)
|
| + print >>sys.stderr, ('WARNING: %s has RecordComputedAction at %d' %
|
| + (path, line_number))
|
| +
|
| +class WebUIActionsParser(HTMLParser):
|
| + """Parses an HTML file, looking for all tags with a 'metric' attribute.
|
| + Adds user actions corresponding to any metrics found.
|
| +
|
| + Arguments:
|
| + actions: set of actions to add to
|
| + """
|
| + def __init__(self, actions):
|
| + HTMLParser.__init__(self)
|
| + self.actions = actions
|
| +
|
| + def handle_starttag(self, tag, attrs):
|
| + # We only care to examine tags that have a 'metric' attribute.
|
| + attrs = dict(attrs)
|
| + if not 'metric' in attrs:
|
| + return
|
| +
|
| + # Boolean metrics have two corresponding actions. All other metrics have
|
| + # just one corresponding action. By default, we check the 'dataType'
|
| + # attribute.
|
| + is_boolean = ('dataType' in attrs and attrs['dataType'] == 'boolean')
|
| + if 'type' in attrs and attrs['type'] in ('checkbox', 'radio'):
|
| + if attrs['type'] == 'checkbox':
|
| + # Checkboxes are boolean by default. However, their 'value-type' can
|
| + # instead be set to 'integer'.
|
| + if 'value-type' not in attrs or attrs['value-type'] in ['', 'boolean']:
|
| + is_boolean = True
|
| + else:
|
| + # Radio buttons are boolean if and only if their values are 'true' or
|
| + # 'false'.
|
| + assert(attrs['type'] == 'radio')
|
| + if 'value' in attrs and attrs['value'] in ['true', 'false']:
|
| + is_boolean = True
|
| +
|
| + if is_boolean:
|
| + self.actions.add(attrs['metric'] + '_Enable')
|
| + self.actions.add(attrs['metric'] + '_Disable')
|
| + else:
|
| + self.actions.add(attrs['metric'])
|
| +
|
| +def GrepForWebUIActions(path, actions):
|
| + """Grep a WebUI source file for elements with associated metrics.
|
|
|
| -def WalkDirectory(root_path, actions):
|
| + Arguments:
|
| + path: path to the file
|
| + actions: set of actions to add to
|
| + """
|
| + parser = WebUIActionsParser(actions)
|
| + parser.feed(open(path).read())
|
| + parser.close()
|
| +
|
| +def WalkDirectory(root_path, actions, extensions, callback):
|
| for path, dirs, files in os.walk(root_path):
|
| if '.svn' in dirs:
|
| dirs.remove('.svn')
|
| for file in files:
|
| ext = os.path.splitext(file)[1]
|
| - if ext in ('.cc', '.mm', '.c', '.m'):
|
| - GrepForActions(os.path.join(path, file), actions)
|
| + if ext in extensions:
|
| + callback(os.path.join(path, file), actions)
|
| +
|
| +def AddLiteralActions(actions):
|
| + """Add literal actions specified via calls to UserMetrics functions.
|
| +
|
| + Arguments:
|
| + actions: set of actions to add to.
|
| + """
|
| + EXTENSIONS = ('.cc', '.mm', '.c', '.m')
|
| +
|
| + # Walk the source tree to process all .cc files.
|
| + chrome_root = os.path.join(path_utils.ScriptDir(), '..')
|
| + WalkDirectory(chrome_root, actions, EXTENSIONS, GrepForActions)
|
| + content_root = os.path.join(path_utils.ScriptDir(), '..', '..', 'content')
|
| + WalkDirectory(content_root, actions, EXTENSIONS, GrepForActions)
|
| + webkit_root = os.path.join(path_utils.ScriptDir(), '..', '..', 'webkit')
|
| + WalkDirectory(os.path.join(webkit_root, 'glue'), actions, EXTENSIONS,
|
| + GrepForActions)
|
| + WalkDirectory(os.path.join(webkit_root, 'port'), actions, EXTENSIONS,
|
| + GrepForActions)
|
| +
|
| +def AddWebUIActions(actions):
|
| + """Add user actions defined in WebUI files.
|
| +
|
| + Arguments:
|
| + actions: set of actions to add to.
|
| + """
|
| + resources_root = os.path.join(path_utils.ScriptDir(), '..', 'browser',
|
| + 'resources')
|
| + WalkDirectory(resources_root, actions, ('.html'), GrepForWebUIActions)
|
|
|
| def main(argv):
|
| if '--hash' in argv:
|
| @@ -271,15 +360,9 @@ def main(argv):
|
| # TODO(fmantek): bring back webkit editor actions.
|
| # AddWebKitEditorActions(actions)
|
| AddAboutFlagsActions(actions)
|
| + AddWebUIActions(actions)
|
|
|
| - # Walk the source tree to process all .cc files.
|
| - chrome_root = os.path.join(path_utils.ScriptDir(), '..')
|
| - WalkDirectory(chrome_root, actions)
|
| - content_root = os.path.join(path_utils.ScriptDir(), '..', '..', 'content')
|
| - WalkDirectory(content_root, actions)
|
| - webkit_root = os.path.join(path_utils.ScriptDir(), '..', '..', 'webkit')
|
| - WalkDirectory(os.path.join(webkit_root, 'glue'), actions)
|
| - WalkDirectory(os.path.join(webkit_root, 'port'), actions)
|
| + AddLiteralActions(actions)
|
|
|
| # print "Scanned {0} number of files".format(number_of_files_total)
|
| # print "Found {0} entries".format(len(actions))
|
|
|