blob: ca491c8bf22ca2b4e72d504cf101664a8ce3365f [file] [log] [blame]
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +01001# Copyright 2016 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
Copybara854996b2021-09-07 19:36:02 +00004
5"""Class that implements the reranking on the hotlistissues table page."""
6from __future__ import print_function
7from __future__ import division
8from __future__ import absolute_import
9
10import logging
11
12from features import features_bizobj
13from features import hotlist_helpers
14from framework import jsonfeed
15from framework import permissions
16from framework import sorting
17from services import features_svc
18from tracker import rerank_helpers
19
20
21class RerankHotlistIssue(jsonfeed.JsonFeed):
22 """Rerank an issue in a hotlist."""
23
24 def AssertBasePermission(self, mr):
25 super(RerankHotlistIssue, self).AssertBasePermission(mr)
26 if mr.target_id and mr.moved_ids and mr.split_above:
27 try:
28 hotlist = self._GetHotlist(mr)
29 except features_svc.NoSuchHotlistException:
30 return
31 edit_perm = permissions.CanEditHotlist(
32 mr.auth.effective_ids, mr.perms, hotlist)
33 if not edit_perm:
34 raise permissions.PermissionException(
35 'User is not allowed to re-rank this hotlist')
36
37 def HandleRequest(self, mr):
38 changed_ranks = self._GetNewRankings(mr)
39
40 if changed_ranks:
41 relations_to_change = dict(
42 (issue_id, rank) for issue_id, rank in changed_ranks)
43
44 self.services.features.UpdateHotlistItemsFields(
45 mr.cnxn, mr.hotlist_id, new_ranks=relations_to_change)
46
47 hotlist_items = self.services.features.GetHotlist(
48 mr.cnxn, mr.hotlist_id).items
49
50 # Note: Cannot use mr.hotlist because hotlist_issues
51 # of mr.hotlist is not updated
52
53 sorting.InvalidateArtValuesKeys(
54 mr.cnxn, [hotlist_item.issue_id for hotlist_item in hotlist_items])
55 (table_data, _) = hotlist_helpers.CreateHotlistTableData(
56 mr, hotlist_items, self.services)
57
58 json_table_data = [{
59 'cells': [{
60 'type': cell.type,
61 'values': [{
62 'item': value.item,
63 'isDerived': value.is_derived,
64 } for value in cell.values],
65 'colIndex': cell.col_index,
66 'align': cell.align,
67 'noWrap': cell.NOWRAP,
68 'nonColLabels': [{
69 'value': label.value,
70 'isDerived': label.is_derived,
71 } for label in cell.non_column_labels],
72 } for cell in table_row.cells],
73 'issueRef': table_row.issue_ref,
74 'idx': table_row.idx,
75 'projectName': table_row.project_name,
76 'projectURL': table_row.project_url,
77 'localID': table_row.local_id,
78 'issueID': table_row.issue_id,
79 'isStarred': table_row.starred,
80 'issueCleanURL': table_row.issue_clean_url,
81 'issueContextURL': table_row.issue_ctx_url,
82 } for table_row in table_data]
83
84 for row, json_row in zip(
85 [table_row for table_row in table_data], json_table_data):
86 if (row.group and row.group.cells):
87 json_row.update({'group': {
88 'rowsInGroup': row.group.rows_in_group,
89 'cells': [{'groupName': cell.group_name,
90 'values': [{
91 # TODO(jojwang): check if this gives error when there
92 # is no value.item
93 'item': value.item if value.item else 'None',
94 } for value in cell.values],
95 } for cell in row.group.cells],
96 }})
97 else:
98 json_row['group'] = 'no'
99
100 return {'table_data': json_table_data}
101 else:
102 return {'table_data': ''}
103
104 def _GetHotlist(self, mr):
105 """Retrieve the current hotlist."""
106 if mr.hotlist_id is None:
107 return None
108 try:
109 hotlist = self.services.features.GetHotlist( mr.cnxn, mr.hotlist_id)
110 except features_svc.NoSuchHotlistException:
111 self.abort(404, 'hotlist not found')
112 return hotlist
113
114 def _GetNewRankings(self, mr):
115 """Compute new issue reference rankings."""
116 missing = False
117 if not (mr.target_id):
118 logging.info('No target_id.')
119 missing = True
120 if not (mr.moved_ids):
121 logging.info('No moved_ids.')
122 missing = True
123 if mr.split_above is None:
124 logging.info('No split_above.')
125 missing = True
126 if missing:
127 return
128
129 untouched_items = [
130 (item.issue_id, item.rank) for item in
131 mr.hotlist.items if item.issue_id not in mr.moved_ids]
132
133 lower, higher = features_bizobj.SplitHotlistIssueRanks(
134 mr.target_id, mr.split_above, untouched_items)
135 return rerank_helpers.GetInsertRankings(lower, higher, mr.moved_ids)
Adrià Vilanova Martínezde942802022-07-15 14:06:55 +0200136
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100137 def GetRerankHotlistIssuePage(self, **kwargs):
138 return self.handler(**kwargs)
Adrià Vilanova Martínezde942802022-07-15 14:06:55 +0200139
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100140 def PostRerankHotlistIssuePage(self, **kwargs):
141 return self.handler(**kwargs)