OLD | NEW |
(Empty) | |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is govered by a BSD-style |
| 3 # license that can be found in the LICENSE file or at |
| 4 # https://developers.google.com/open-source/licenses/bsd |
| 5 |
| 6 """Implemention of the issue list output as a CSV file.""" |
| 7 |
| 8 import settings |
| 9 from framework import framework_helpers |
| 10 from framework import permissions |
| 11 from framework import urls |
| 12 from tracker import issuelist |
| 13 from tracker import tablecell |
| 14 from tracker import tracker_constants |
| 15 |
| 16 |
| 17 class IssueListCsv(issuelist.IssueList): |
| 18 """IssueListCsv provides to the user a list of issues as a CSV document. |
| 19 |
| 20 Overrides the standard IssueList servlet but uses a different EZT template |
| 21 to provide the same content as the IssueList only as CSV. Adds the HTTP |
| 22 header to offer the result as a download. |
| 23 """ |
| 24 |
| 25 _PAGE_TEMPLATE = 'tracker/issue-list-csv.ezt' |
| 26 _DEFAULT_RESULTS_PER_PAGE = settings.max_artifact_search_results_per_page |
| 27 |
| 28 def GatherPageData(self, mr): |
| 29 if not mr.auth.user_id: |
| 30 raise permissions.PermissionException( |
| 31 'Anonymous users are not allowed to download issue list CSV') |
| 32 |
| 33 # Sets headers to allow the response to be downloaded. |
| 34 self.content_type = 'text/csv; charset=UTF-8' |
| 35 download_filename = '%s-issues.csv' % mr.project_name |
| 36 self.response.headers.add( |
| 37 'Content-Disposition', 'attachment; filename=%s' % download_filename) |
| 38 self.response.headers.add('X-Content-Type-Options', 'nosniff') |
| 39 |
| 40 # Rewrite the colspec to add some extra columns that make the CSV |
| 41 # file more complete. |
| 42 with self.profiler.Phase('finishing config work'): |
| 43 config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id) |
| 44 |
| 45 mr.ComputeColSpec(config) |
| 46 mr.col_spec = _RewriteColspec(mr.col_spec) |
| 47 page_data = issuelist.IssueList.GatherPageData(self, mr) |
| 48 |
| 49 # CSV files are at risk for PDF content sniffing by Acrobat Reader. |
| 50 page_data['prevent_sniffing'] = True |
| 51 |
| 52 # If we're truncating the results, add a URL to the next page of results |
| 53 page_data['next_csv_link'] = None |
| 54 pagination = page_data['pagination'] |
| 55 if pagination.next_url: |
| 56 page_data['next_csv_link'] = framework_helpers.FormatAbsoluteURL( |
| 57 mr, urls.ISSUE_LIST_CSV, start=pagination.last) |
| 58 page_data['item_count'] = pagination.last - pagination.start + 1 |
| 59 |
| 60 return page_data |
| 61 |
| 62 def GetCellFactories(self): |
| 63 return tablecell.CSV_CELL_FACTORIES |
| 64 |
| 65 |
| 66 # Whenever the user request one of these columns, we replace it with the |
| 67 # list of alternate columns. In effect, we split the requested column |
| 68 # into two CSV columns. |
| 69 _CSV_COLS_TO_REPLACE = { |
| 70 'summary': ['Summary', 'AllLabels'], |
| 71 'opened': ['Opened', 'OpenedTimestamp'], |
| 72 'closed': ['Closed', 'ClosedTimestamp'], |
| 73 'modified': ['Modified', 'ModifiedTimestamp'], |
| 74 } |
| 75 |
| 76 |
| 77 def _RewriteColspec(col_spec): |
| 78 """Rewrite the given colspec to expand special CSV columns.""" |
| 79 new_cols = [] |
| 80 |
| 81 for col in col_spec.split(): |
| 82 rewriten_cols = _CSV_COLS_TO_REPLACE.get(col.lower(), [col]) |
| 83 new_cols.extend(rewriten_cols) |
| 84 |
| 85 return ' '.join(new_cols) |
OLD | NEW |