| OLD | NEW |
| 1 # Copyright (c) 2009, Google Inc. All rights reserved. | 1 # Copyright (c) 2009, Google Inc. All rights reserved. |
| 2 # | 2 # |
| 3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
| 4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
| 5 # met: | 5 # met: |
| 6 # | 6 # |
| 7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
| 8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
| 9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
| 10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 DEFAULT_NO = 'n' | 48 DEFAULT_NO = 'n' |
| 49 DEFAULT_YES = 'y' | 49 DEFAULT_YES = 'y' |
| 50 | 50 |
| 51 def __init__(self, platforminfo=None): | 51 def __init__(self, platforminfo=None): |
| 52 # We cannot get the PlatformInfo object from a SystemHost because | 52 # We cannot get the PlatformInfo object from a SystemHost because |
| 53 # User is part of SystemHost itself. | 53 # User is part of SystemHost itself. |
| 54 self._platforminfo = platforminfo or PlatformInfo(sys, platform, FileSys
tem(), Executive()) | 54 self._platforminfo = platforminfo or PlatformInfo(sys, platform, FileSys
tem(), Executive()) |
| 55 | 55 |
| 56 # FIXME: These are @classmethods because bugzilla.py doesn't have a Tool obj
ect (thus no User instance). | 56 # FIXME: These are @classmethods because bugzilla.py doesn't have a Tool obj
ect (thus no User instance). |
| 57 @classmethod | 57 @classmethod |
| 58 def prompt(cls, message, repeat=1, raw_input_func=raw_input): | 58 def prompt(cls, message, repeat=1, raw_input=raw_input): |
| 59 response = None | 59 response = None |
| 60 while repeat and not response: | 60 while repeat and not response: |
| 61 repeat -= 1 | 61 repeat -= 1 |
| 62 response = raw_input_func(message) | 62 response = raw_input(message) |
| 63 return response | 63 return response |
| 64 | 64 |
| 65 @classmethod | 65 @classmethod |
| 66 def prompt_password(cls, message, repeat=1): | 66 def prompt_password(cls, message, repeat=1): |
| 67 return cls.prompt(message, repeat=repeat, raw_input_func=getpass.getpass
) | 67 return cls.prompt(message, repeat=repeat, raw_input=getpass.getpass) |
| 68 | 68 |
| 69 @classmethod | 69 @classmethod |
| 70 def prompt_with_multiple_lists(cls, list_title, subtitles, lists, can_choose
_multiple=False, raw_input_func=raw_input): | 70 def prompt_with_multiple_lists(cls, list_title, subtitles, lists, can_choose
_multiple=False, raw_input=raw_input): |
| 71 item_index = 0 | 71 item_index = 0 |
| 72 cumulated_list = [] | 72 cumulated_list = [] |
| 73 print list_title | 73 print list_title |
| 74 for i in range(len(subtitles)): | 74 for i in range(len(subtitles)): |
| 75 print "\n" + subtitles[i] | 75 print "\n" + subtitles[i] |
| 76 for item in lists[i]: | 76 for item in lists[i]: |
| 77 item_index += 1 | 77 item_index += 1 |
| 78 print "%2d. %s" % (item_index, item) | 78 print "%2d. %s" % (item_index, item) |
| 79 cumulated_list += lists[i] | 79 cumulated_list += lists[i] |
| 80 return cls._wait_on_list_response(cumulated_list, can_choose_multiple, r
aw_input_func) | 80 return cls._wait_on_list_response(cumulated_list, can_choose_multiple, r
aw_input) |
| 81 | 81 |
| 82 @classmethod | 82 @classmethod |
| 83 def _wait_on_list_response(cls, list_items, can_choose_multiple, raw_input_f
unc): | 83 def _wait_on_list_response(cls, list_items, can_choose_multiple, raw_input): |
| 84 while True: | 84 while True: |
| 85 if can_choose_multiple: | 85 if can_choose_multiple: |
| 86 response = cls.prompt( | 86 response = cls.prompt( |
| 87 "Enter one or more numbers (comma-separated) or ranges (e.g.
3-7), or \"all\": ", raw_input_func=raw_input_func) | 87 "Enter one or more numbers (comma-separated) or ranges (e.g.
3-7), or \"all\": ", raw_input=raw_input) |
| 88 if not response.strip() or response == "all": | 88 if not response.strip() or response == "all": |
| 89 return list_items | 89 return list_items |
| 90 | 90 |
| 91 try: | 91 try: |
| 92 indices = [] | 92 indices = [] |
| 93 for value in re.split(r"\s*,\s*", response): | 93 for value in re.split("\s*,\s*", response): |
| 94 parts = value.split('-') | 94 parts = value.split('-') |
| 95 if len(parts) == 2: | 95 if len(parts) == 2: |
| 96 indices += range(int(parts[0]) - 1, int(parts[1])) | 96 indices += range(int(parts[0]) - 1, int(parts[1])) |
| 97 else: | 97 else: |
| 98 indices.append(int(value) - 1) | 98 indices.append(int(value) - 1) |
| 99 except ValueError: | 99 except ValueError: |
| 100 continue | 100 continue |
| 101 | 101 |
| 102 return [list_items[i] for i in indices] | 102 return [list_items[i] for i in indices] |
| 103 else: | 103 else: |
| 104 try: | 104 try: |
| 105 result = int(cls.prompt("Enter a number: ", raw_input_func=r
aw_input_func)) - 1 | 105 result = int(cls.prompt("Enter a number: ", raw_input=raw_in
put)) - 1 |
| 106 except ValueError: | 106 except ValueError: |
| 107 continue | 107 continue |
| 108 return list_items[result] | 108 return list_items[result] |
| 109 | 109 |
| 110 @classmethod | 110 @classmethod |
| 111 def prompt_with_list(cls, list_title, list_items, can_choose_multiple=False,
raw_input_func=raw_input): | 111 def prompt_with_list(cls, list_title, list_items, can_choose_multiple=False,
raw_input=raw_input): |
| 112 print list_title | 112 print list_title |
| 113 i = 0 | 113 i = 0 |
| 114 for item in list_items: | 114 for item in list_items: |
| 115 i += 1 | 115 i += 1 |
| 116 print "%2d. %s" % (i, item) | 116 print "%2d. %s" % (i, item) |
| 117 return cls._wait_on_list_response(list_items, can_choose_multiple, raw_i
nput_func) | 117 return cls._wait_on_list_response(list_items, can_choose_multiple, raw_i
nput) |
| 118 | 118 |
| 119 def edit(self, files): | 119 def edit(self, files): |
| 120 editor = os.environ.get("EDITOR") or "vi" | 120 editor = os.environ.get("EDITOR") or "vi" |
| 121 args = shlex.split(editor) | 121 args = shlex.split(editor) |
| 122 # Note: Not thread safe: http://bugs.python.org/issue2320 | 122 # Note: Not thread safe: http://bugs.python.org/issue2320 |
| 123 subprocess.call(args + files) | 123 subprocess.call(args + files) |
| 124 | 124 |
| 125 def page(self, message): | 125 def page(self, message): |
| 126 pager = os.environ.get("PAGER") or "less" | 126 pager = os.environ.get("PAGER") or "less" |
| 127 try: | 127 try: |
| 128 # Note: Not thread safe: http://bugs.python.org/issue2320 | 128 # Note: Not thread safe: http://bugs.python.org/issue2320 |
| 129 child_process = subprocess.Popen([pager], stdin=subprocess.PIPE) | 129 child_process = subprocess.Popen([pager], stdin=subprocess.PIPE) |
| 130 child_process.communicate(input=message) | 130 child_process.communicate(input=message) |
| 131 except IOError: | 131 except IOError: |
| 132 pass | 132 pass |
| 133 | 133 |
| 134 def confirm(self, message=None, default=DEFAULT_YES, raw_input_func=raw_inpu
t): | 134 def confirm(self, message=None, default=DEFAULT_YES, raw_input=raw_input): |
| 135 if not message: | 135 if not message: |
| 136 message = "Continue?" | 136 message = "Continue?" |
| 137 choice = {'y': 'Y/n', 'n': 'y/N'}[default] | 137 choice = {'y': 'Y/n', 'n': 'y/N'}[default] |
| 138 response = raw_input_func("%s [%s]: " % (message, choice)) | 138 response = raw_input("%s [%s]: " % (message, choice)) |
| 139 if not response: | 139 if not response: |
| 140 response = default | 140 response = default |
| 141 return response.lower() == 'y' | 141 return response.lower() == 'y' |
| 142 | 142 |
| 143 def can_open_url(self): | 143 def can_open_url(self): |
| 144 try: | 144 try: |
| 145 webbrowser.get() | 145 webbrowser.get() |
| 146 return True | 146 return True |
| 147 except webbrowser.Error: | 147 except webbrowser.Error: |
| 148 return False | 148 return False |
| 149 | 149 |
| 150 def open_url(self, url): | 150 def open_url(self, url): |
| 151 if not self.can_open_url(): | 151 if not self.can_open_url(): |
| 152 _log.warning("Failed to open %s", url) | 152 _log.warning("Failed to open %s", url) |
| 153 webbrowser.open(url) | 153 webbrowser.open(url) |
| OLD | NEW |