OLD | NEW |
---|---|
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2014 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import logging | 5 import logging |
6 import os | |
7 import xml.dom.minidom as minidom | 6 import xml.dom.minidom as minidom |
8 from xml.parsers.expat import ExpatError | 7 from xml.parsers.expat import ExpatError |
9 | 8 |
10 import crash_utils | 9 import crash_utils |
11 from repository_parser_interface import ParserInterface | 10 from repository_parser_interface import ParserInterface |
12 | 11 |
13 | 12 |
14 # This number is 6 because each linediff page in src.chromium.org should | 13 # This number is 6 because each linediff page in src.chromium.org should |
15 # contain the following tables: table with revision number, table with actual | 14 # contain the following tables: table with revision number, table with actual |
16 # diff, table with dropdown menu, table with legend, a border table and a table | 15 # diff, table with dropdown menu, table with legend, a border table and a table |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
71 revision_object['author'] = revision.getElementsByTagName( | 70 revision_object['author'] = revision.getElementsByTagName( |
72 'author')[0].firstChild.nodeValue | 71 'author')[0].firstChild.nodeValue |
73 | 72 |
74 # Get the revision number from xml. | 73 # Get the revision number from xml. |
75 revision_number = int(revision.getAttribute('revision')) | 74 revision_number = int(revision.getAttribute('revision')) |
76 | 75 |
77 # Iterate through the changed paths in the CL. | 76 # Iterate through the changed paths in the CL. |
78 paths = revision.getElementsByTagName('paths') | 77 paths = revision.getElementsByTagName('paths') |
79 if paths: | 78 if paths: |
80 for changed_path in paths[0].getElementsByTagName('path'): | 79 for changed_path in paths[0].getElementsByTagName('path'): |
81 # Get path, file action and file name from the xml. | 80 # Get path, file action and file name from the xml. |
stgao
2014/08/22 06:50:54
comment is not updated.
jeun
2014/08/22 22:58:44
Done.
| |
82 file_path = changed_path.firstChild.nodeValue | 81 file_path = changed_path.firstChild.nodeValue |
83 file_action = changed_path.getAttribute('action') | 82 file_change_type = changed_path.getAttribute('action') |
84 changed_file = os.path.basename(file_path) | 83 |
84 if file_path.startswith('/trunk/'): | |
85 file_path = file_path[len('/trunk/'):] | |
85 | 86 |
86 # Add file to the map. | 87 # Add file to the map. |
87 if changed_file not in file_to_revision_map: | 88 if file_path not in file_to_revision_map: |
88 file_to_revision_map[changed_file] = [] | 89 file_to_revision_map[file_path] = [] |
89 file_to_revision_map[changed_file].append( | 90 file_to_revision_map[file_path].append( |
90 (revision_number, file_action, file_path)) | 91 (revision_number, file_change_type)) |
91 | 92 |
92 # Set commit message of the CL. | 93 # Set commit message of the CL. |
93 revision_object['message'] = revision.getElementsByTagName('msg')[ | 94 revision_object['message'] = revision.getElementsByTagName('msg')[ |
94 0].firstChild.nodeValue | 95 0].firstChild.nodeValue |
95 | 96 |
96 # Set url of this CL. | 97 # Set url of this CL. |
97 revision_url = url_map['revision_url'] % revision_number | 98 revision_url = url_map['revision_url'] % revision_number |
98 revision_object['url'] = revision_url | 99 revision_object['url'] = revision_url |
99 | 100 |
100 # Add this CL to the revision map. | 101 # Add this CL to the revision map. |
101 revision_map[revision_number] = revision_object | 102 revision_map[revision_number] = revision_object |
102 | 103 |
103 return (revision_map, file_to_revision_map) | 104 return (revision_map, file_to_revision_map) |
104 | 105 |
105 def ParseLineDiff(self, path, component, file_action, revision_number): | 106 def ParseLineDiff(self, path, component, file_change_type, revision_number): |
106 changed_line_numbers = [] | 107 changed_line_numbers = [] |
107 changed_line_contents = [] | 108 changed_line_contents = [] |
108 | 109 |
109 url_map = self.component_to_urls_map.get(component) | 110 url_map = self.component_to_urls_map.get(component) |
110 if not url_map: | 111 if not url_map: |
111 logging.error('Component %s is not currently supported.', component) | 112 logging.error('Component %s is not currently supported.', component) |
112 return (None, None, None) | 113 return (None, None, None) |
113 | 114 |
114 # If the file is added (not modified), treat it as if it is not changed. | 115 # If the file is added (not modified), treat it as if it is not changed. |
115 backup_url = url_map['revision_url'] % revision_number | 116 backup_url = url_map['revision_url'] % revision_number |
116 if file_action == 'A': | 117 if file_change_type == 'A': |
117 return (backup_url, changed_line_numbers, changed_line_contents) | 118 return (backup_url, changed_line_numbers, changed_line_contents) |
118 | 119 |
119 # Retrieve data from the url. If no data is retrieved, return empty lists. | 120 # Retrieve data from the url. If no data is retrieved, return empty lists. |
120 url = url_map['diff_url'] % (path, revision_number - 1, | 121 url = url_map['diff_url'] % (path, revision_number - 1, |
121 revision_number, revision_number) | 122 revision_number, revision_number) |
122 data = crash_utils.GetDataFromURL(url) | 123 data = crash_utils.GetDataFromURL(url) |
123 if not data: | 124 if not data: |
124 logging.error('Failed to get line changes from %s.', url) | 125 logging.error('Failed to get line changes from %s.', url) |
125 return (backup_url, changed_line_numbers, changed_line_contents) | 126 return (backup_url, changed_line_numbers, changed_line_contents) |
126 | 127 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
212 blame_html = minidom.parseString(data) | 213 blame_html = minidom.parseString(data) |
213 | 214 |
214 title = blame_html.getElementsByTagName('title') | 215 title = blame_html.getElementsByTagName('title') |
215 # If the returned html page is an exception page, return None. | 216 # If the returned html page is an exception page, return None. |
216 if title[0].firstChild.nodeValue == 'ViewVC Exception': | 217 if title[0].firstChild.nodeValue == 'ViewVC Exception': |
217 logging.error('Failed to retrieve blame information from %s.', url) | 218 logging.error('Failed to retrieve blame information from %s.', url) |
218 return None | 219 return None |
219 | 220 |
220 # Each of the blame result is in <tr>. | 221 # Each of the blame result is in <tr>. |
221 blame_results = blame_html.getElementsByTagName('tr') | 222 blame_results = blame_html.getElementsByTagName('tr') |
222 blame_result = blame_results[line] | 223 try: |
224 blame_result = blame_results[line] | |
225 except IndexError: | |
226 logging.error('Failed to retrieve blame information from %s.', url) | |
227 return None | |
223 | 228 |
224 # There must be 4 <td> for each <tr>. If not, this page is wrong. | 229 # There must be 4 <td> for each <tr>. If not, this page is wrong. |
225 tds = blame_result.getElementsByTagName('td') | 230 tds = blame_result.getElementsByTagName('td') |
226 if len(tds) != 4: | 231 if len(tds) != 4: |
227 logging.error('Failed to retrieve blame information from %s.', url) | 232 logging.error('Failed to retrieve blame information from %s.', url) |
228 return None | 233 return None |
229 | 234 |
230 # The third <td> has the line content, separated by <span>s. Combine | 235 # The third <td> has the line content, separated by <span>s. Combine |
231 # those to get a string of changed line. If it has nothing, the line | 236 # those to get a string of changed line. If it has nothing, the line |
232 # is empty. | 237 # is empty. |
(...skipping 17 matching lines...) Expand all Loading... | |
250 blame_result = blame_results[line] | 255 blame_result = blame_results[line] |
251 tds = blame_result.getElementsByTagName('td') | 256 tds = blame_result.getElementsByTagName('td') |
252 author = tds[1].firstChild.nodeValue | 257 author = tds[1].firstChild.nodeValue |
253 | 258 |
254 # Revision can either be in hyperlink or plain text. | 259 # Revision can either be in hyperlink or plain text. |
255 try: | 260 try: |
256 revision = tds[2].getElementsByTagName('a')[0].firstChild.nodeValue | 261 revision = tds[2].getElementsByTagName('a')[0].firstChild.nodeValue |
257 except IndexError: | 262 except IndexError: |
258 revision = tds[2].firstChild.nodeValue | 263 revision = tds[2].firstChild.nodeValue |
259 | 264 |
265 (revision_info, _) = self.ParseChangelog(component, revision, revision) | |
266 message = revision_info[int(revision)]['message'] | |
267 | |
260 # Return the parsed information. | 268 # Return the parsed information. |
261 revision_url = url_map['revision_url'] % int(revision) | 269 revision_url = url_map['revision_url'] % int(revision) |
262 return (line_content, revision, author, revision_url) | 270 return (line_content, revision, author, revision_url, message) |
OLD | NEW |