Chromium Code Reviews| Index: chrome/tools/extract_actions.py |
| diff --git a/chrome/tools/extract_actions.py b/chrome/tools/extract_actions.py |
| index 68f5352465e86ed3500ec1aa147c4046083e90bd..7b265fad151c158e97b9dd02cc0ab74fb82de215 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,6 +226,7 @@ def GrepForActions(path, actions): |
| # we look for the UserMetricsAction structure constructor |
| # this should be on one line |
| action_re = re.compile(r'UserMetricsAction\("([^"]*)') |
| + malformed_action_re = re.compile(r'[^a-zA-Z]UserMetricsAction\([^"]') |
|
jar (doing other things)
2011/08/01 17:26:45
I like your definition better than the one in 228.
Ilya Sherman
2011/08/06 03:23:52
There are two differences between |action_re| and
|
| computed_action_re = re.compile(r'UserMetrics::RecordComputedAction') |
| line_number = 0 |
| for line in open(path): |
| @@ -229,20 +234,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: |
| @@ -270,15 +359,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)) |