1# Copyright 2013 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import optparse
6import re
7
8from telemetry.core import command_line
9
10
11def HasLabelIn(obj, labels):
12  for label in labels:
13    if hasattr(obj, label) and getattr(obj, label):
14      return True
15  return False
16
17
18class PageFilter(command_line.ArgumentHandlerMixIn):
19  """Filters pages in the page set based on command-line flags."""
20
21  @classmethod
22  def AddCommandLineArgs(cls, parser):
23    group = optparse.OptionGroup(parser, 'Page filtering options')
24    group.add_option('--page-filter',
25        help='Use only pages whose URLs match the given filter regexp.')
26    group.add_option('--page-filter-exclude',
27        help='Exclude pages whose URLs match the given filter regexp.')
28    group.add_option('--page-label-filter',
29        help='Use only pages that have any of these labels')
30    group.add_option('--page-label-filter-exclude',
31        help='Exclude pages that have any of these labels')
32
33    parser.add_option_group(group)
34
35  @classmethod
36  def ProcessCommandLineArgs(cls, parser, args):
37    cls._page_regex = None
38    cls._page_exclude_regex = None
39    cls._include_labels = None
40    cls._exclude_labels = None
41
42    if args.page_filter:
43      try:
44        cls._page_regex = re.compile(args.page_filter)
45      except re.error:
46        raise parser.error('--page-filter: invalid regex')
47
48    if args.page_filter_exclude:
49      try:
50        cls._page_exclude_regex = re.compile(args.page_filter_exclude)
51      except re.error:
52        raise parser.error('--page-filter-exclude: invalid regex')
53
54    if args.page_label_filter:
55      cls._include_labels = args.page_label_filter.split(',')
56
57    if args.page_label_filter_exclude:
58      cls._exclude_labels = args.page_label_filter_exclude.split(',')
59
60  @classmethod
61  def IsSelected(cls, page):
62    # Exclude filters take priority.
63    if cls._exclude_labels and HasLabelIn(page, cls._exclude_labels):
64      return False
65    if cls._page_exclude_regex:
66      matches_url = cls._page_exclude_regex.search(page.url)
67      matches_name = page.name and cls._page_exclude_regex.search(page.name)
68      if matches_url or matches_name:
69        return False
70
71    # Apply all filters.
72    filter_result = True
73    if cls._include_labels:
74      filter_result = filter_result and HasLabelIn(page, cls._include_labels)
75    if cls._page_regex:
76      matches_url = cls._page_regex.search(page.url)
77      matches_name = page.name and cls._page_regex.search(page.name)
78      filter_result = filter_result and (matches_url or matches_name)
79
80    return filter_result
81