Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1742)

Unified Diff: chrome/tools/extract_actions.py

Issue 7314020: Update UMA user actions parsing, primarily to include WebUI metrics. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update regex Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/tools/chromeactions.txt ('k') | content/browser/renderer_host/render_widget_host.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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))
« no previous file with comments | « chrome/tools/chromeactions.txt ('k') | content/browser/renderer_host/render_widget_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698