blob: fe235dbdf073570b49a718c505086b3e3b6a7815 [file] [log] [blame]
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
"""Class that implements the reranking on the hotlistissues table page."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
import logging
from features import features_bizobj
from features import hotlist_helpers
from framework import jsonfeed
from framework import permissions
from framework import sorting
from services import features_svc
from tracker import rerank_helpers
class RerankHotlistIssue(jsonfeed.JsonFeed):
"""Rerank an issue in a hotlist."""
def AssertBasePermission(self, mr):
super(RerankHotlistIssue, self).AssertBasePermission(mr)
if mr.target_id and mr.moved_ids and mr.split_above:
try:
hotlist = self._GetHotlist(mr)
except features_svc.NoSuchHotlistException:
return
edit_perm = permissions.CanEditHotlist(
mr.auth.effective_ids, mr.perms, hotlist)
if not edit_perm:
raise permissions.PermissionException(
'User is not allowed to re-rank this hotlist')
def HandleRequest(self, mr):
changed_ranks = self._GetNewRankings(mr)
if changed_ranks:
relations_to_change = dict(
(issue_id, rank) for issue_id, rank in changed_ranks)
self.services.features.UpdateHotlistItemsFields(
mr.cnxn, mr.hotlist_id, new_ranks=relations_to_change)
hotlist_items = self.services.features.GetHotlist(
mr.cnxn, mr.hotlist_id).items
# Note: Cannot use mr.hotlist because hotlist_issues
# of mr.hotlist is not updated
sorting.InvalidateArtValuesKeys(
mr.cnxn, [hotlist_item.issue_id for hotlist_item in hotlist_items])
(table_data, _) = hotlist_helpers.CreateHotlistTableData(
mr, hotlist_items, self.services)
json_table_data = [{
'cells': [{
'type': cell.type,
'values': [{
'item': value.item,
'isDerived': value.is_derived,
} for value in cell.values],
'colIndex': cell.col_index,
'align': cell.align,
'noWrap': cell.NOWRAP,
'nonColLabels': [{
'value': label.value,
'isDerived': label.is_derived,
} for label in cell.non_column_labels],
} for cell in table_row.cells],
'issueRef': table_row.issue_ref,
'idx': table_row.idx,
'projectName': table_row.project_name,
'projectURL': table_row.project_url,
'localID': table_row.local_id,
'issueID': table_row.issue_id,
'isStarred': table_row.starred,
'issueCleanURL': table_row.issue_clean_url,
'issueContextURL': table_row.issue_ctx_url,
} for table_row in table_data]
for row, json_row in zip(
[table_row for table_row in table_data], json_table_data):
if (row.group and row.group.cells):
json_row.update({'group': {
'rowsInGroup': row.group.rows_in_group,
'cells': [{'groupName': cell.group_name,
'values': [{
# TODO(jojwang): check if this gives error when there
# is no value.item
'item': value.item if value.item else 'None',
} for value in cell.values],
} for cell in row.group.cells],
}})
else:
json_row['group'] = 'no'
return {'table_data': json_table_data}
else:
return {'table_data': ''}
def _GetHotlist(self, mr):
"""Retrieve the current hotlist."""
if mr.hotlist_id is None:
return None
try:
hotlist = self.services.features.GetHotlist( mr.cnxn, mr.hotlist_id)
except features_svc.NoSuchHotlistException:
self.abort(404, 'hotlist not found')
return hotlist
def _GetNewRankings(self, mr):
"""Compute new issue reference rankings."""
missing = False
if not (mr.target_id):
logging.info('No target_id.')
missing = True
if not (mr.moved_ids):
logging.info('No moved_ids.')
missing = True
if mr.split_above is None:
logging.info('No split_above.')
missing = True
if missing:
return
untouched_items = [
(item.issue_id, item.rank) for item in
mr.hotlist.items if item.issue_id not in mr.moved_ids]
lower, higher = features_bizobj.SplitHotlistIssueRanks(
mr.target_id, mr.split_above, untouched_items)
return rerank_helpers.GetInsertRankings(lower, higher, mr.moved_ids)