Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Tools / Scripts / webkitpy / common / system / user.py
1 # Copyright (c) 2009, Google Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
5 # met:
6 #
7 #     * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 #     * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer
11 # in the documentation and/or other materials provided with the
12 # distribution.
13 #     * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived from
15 # this software without specific prior written permission.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 import getpass
30 import logging
31 import os
32 import platform
33 import re
34 import shlex
35 import subprocess
36 import sys
37 import webbrowser
38
39 from webkitpy.common.system.executive import Executive
40 from webkitpy.common.system.platforminfo import PlatformInfo
41
42
43 _log = logging.getLogger(__name__)
44
45
46 class User(object):
47     DEFAULT_NO = 'n'
48     DEFAULT_YES = 'y'
49
50     def __init__(self, platforminfo=None):
51         # We cannot get the PlatformInfo object from a SystemHost because
52         # User is part of SystemHost itself.
53         self._platforminfo = platforminfo or PlatformInfo(sys, platform, Executive())
54
55     # FIXME: These are @classmethods because bugzilla.py doesn't have a Tool object (thus no User instance).
56     @classmethod
57     def prompt(cls, message, repeat=1, raw_input=raw_input):
58         response = None
59         while (repeat and not response):
60             repeat -= 1
61             response = raw_input(message)
62         return response
63
64     @classmethod
65     def prompt_password(cls, message, repeat=1):
66         return cls.prompt(message, repeat=repeat, raw_input=getpass.getpass)
67
68     @classmethod
69     def prompt_with_multiple_lists(cls, list_title, subtitles, lists, can_choose_multiple=False, raw_input=raw_input):
70         item_index = 0
71         cumulated_list = []
72         print list_title
73         for i in range(len(subtitles)):
74             print "\n" + subtitles[i]
75             for item in lists[i]:
76                 item_index += 1
77                 print "%2d. %s" % (item_index, item)
78             cumulated_list += lists[i]
79         return cls._wait_on_list_response(cumulated_list, can_choose_multiple, raw_input)
80
81     @classmethod
82     def _wait_on_list_response(cls, list_items, can_choose_multiple, raw_input):
83         while True:
84             if can_choose_multiple:
85                 response = cls.prompt("Enter one or more numbers (comma-separated) or ranges (e.g. 3-7), or \"all\": ", raw_input=raw_input)
86                 if not response.strip() or response == "all":
87                     return list_items
88
89                 try:
90                     indices = []
91                     for value in re.split("\s*,\s*", response):
92                         parts = value.split('-')
93                         if len(parts) == 2:
94                             indices += range(int(parts[0]) - 1, int(parts[1]))
95                         else:
96                             indices.append(int(value) - 1)
97                 except ValueError, err:
98                     continue
99
100                 return [list_items[i] for i in indices]
101             else:
102                 try:
103                     result = int(cls.prompt("Enter a number: ", raw_input=raw_input)) - 1
104                 except ValueError, err:
105                     continue
106                 return list_items[result]
107
108     @classmethod
109     def prompt_with_list(cls, list_title, list_items, can_choose_multiple=False, raw_input=raw_input):
110         print list_title
111         i = 0
112         for item in list_items:
113             i += 1
114             print "%2d. %s" % (i, item)
115         return cls._wait_on_list_response(list_items, can_choose_multiple, raw_input)
116
117     def edit(self, files):
118         editor = os.environ.get("EDITOR") or "vi"
119         args = shlex.split(editor)
120         # Note: Not thread safe: http://bugs.python.org/issue2320
121         subprocess.call(args + files)
122
123     def page(self, message):
124         pager = os.environ.get("PAGER") or "less"
125         try:
126             # Note: Not thread safe: http://bugs.python.org/issue2320
127             child_process = subprocess.Popen([pager], stdin=subprocess.PIPE)
128             child_process.communicate(input=message)
129         except IOError, e:
130             pass
131
132     def confirm(self, message=None, default=DEFAULT_YES, raw_input=raw_input):
133         if not message:
134             message = "Continue?"
135         choice = {'y': 'Y/n', 'n': 'y/N'}[default]
136         response = raw_input("%s [%s]: " % (message, choice))
137         if not response:
138             response = default
139         return response.lower() == 'y'
140
141     def can_open_url(self):
142         try:
143             webbrowser.get()
144             return True
145         except webbrowser.Error, e:
146             return False
147
148     def open_url(self, url):
149         if not self.can_open_url():
150             _log.warn("Failed to open %s" % url)
151         webbrowser.open(url)