blob: 0564de66e2b31284c0717daa0a861cf1a57a6ab0 [file] [log] [blame]
# Copyright 2014 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Module for templates with proposal lists."""
import json
from django.utils import translation
from melange.request import exception
from melange.request import links
from melange.utils import rich_bool
from soc.views import template
from soc.views.helper import lists
from summerofcode.logic import proposal as proposal_logic
from summerofcode.views.helper import urls
_PROPOSAL_REVISIONS_LIST_TITLE = translation.ugettext('Proposal revisions')
_PROPOSAL_REVISIONS_LIST_DESCRIPTION = translation.ugettext(
'List of proposal revisions for the selected proposal. '
'Select two revisions to see the diff between them.')
_PROPOSAL_REVISION_KEY = 'full_proposal_revision_key'
_PROPOSAL_REVISION_MISSING = translation.ugettext(
'Proposal revision is missing in post data.')
class ProposalRevisionsList(template.Template):
"""Template for list of proposal revisions."""
def __init__(self, template_path, data, list_config, query,
description, prefetcher=None):
"""Initializes a new instance of the list for the specified parameters.
Args:
url_names: Instance of url_names.UrlNames.
template_path: The path of the template to be used.
data: request_data.RequestData for the current request.
list_config: List configuration object.
query: ndb.Query to get list data.
description: A string containing description of the list.
prefetcher: Optional instance of lists.ListPrefetcher to prefetch data.
"""
super(ProposalRevisionsList, self).__init__(data)
self.template_path = template_path
self._list_config = list_config
self._query = query
self._description = description
self._prefetcher = prefetcher
def context(self):
"""See template.Template.context for specification."""
list_configuration_response = lists.ListConfigurationResponse(
self.data, self._list_config, 0, self._description)
return {
'list_title': _PROPOSAL_REVISIONS_LIST_TITLE,
'lists': [list_configuration_response]
}
def getListData(self):
idx = lists.getListIndex(self.data.request)
if idx != 0:
return None
prefetcher = self._prefetcher
response_builder = lists.RawQueryContentResponseBuilder(
self.data.request, self._list_config, self._query,
lists.keyStarter, prefetcher=prefetcher)
return response_builder.buildNDB()
def post(self):
"""POST handler for the student proposal revisions list actions.
Returns:
rich_bool.RichBool whose value is set to True, if the data is
successfully modified. In that case, the extra part is a dict containing
keys of proposal_model.ProposalRevision entities for which the diff is
to be produced. Otherwise, rich_bool.RichBool whose value is set
to False and an extra part is added if 'full_proposal_revision_key' is
not found.
"""
idx = lists.getListIndex(self.data.request)
if idx != 0:
return rich_bool.RichBool.FALSE
post_data = self.data.POST.get('data')
if not post_data:
raise exception.BadRequest(message='Missing data')
parsed = json.loads(post_data)
for properties in parsed:
if 'full_proposal_revision_key' not in properties:
return rich_bool.RichBool(False, _PROPOSAL_REVISION_MISSING)
revisions = {}
revisions['one'] = parsed[0]['full_proposal_revision_key']
revisions['two'] = parsed[1]['full_proposal_revision_key']
return rich_bool.RichBool(True, revisions)
def getProposalRevisionList(data, proposal_key):
"""Returns an instance of ProposalRevisionList class that will list
proposals revisions for the specified proposal.
Args:
data: request_data.RequestData for the current request.
proposal_key: ndb.Key of the proposal.
Returns:
The newly created ProposalRevisionList object.
"""
list_config = lists.ListConfiguration()
list_config.addSimpleColumn('revision', 'Revision')
list_config.addPlainTextColumn(
'content_size', 'Content Size (bytes)',
lambda entity, *args: len(entity.content))
list_config.addDateColumn(
'submitted_on', 'Submitted On',
lambda entity, *args: entity.created_on)
list_config.setDefaultSort('revision')
# hidden keys
list_config.addHtmlColumn(
_PROPOSAL_REVISION_KEY, 'Full proposal revision key',
(lambda entity, *args: entity.key.urlsafe()), hidden=True)
list_config.setRowAction(
lambda entity, *args: links.LINKER.proposalRevisionId(
entity.key.parent(), entity.key.id(),
urls.UrlNames.PROPOSAL_REVISION_REVIEW))
bounds = [0, 2]
keys = [_PROPOSAL_REVISION_KEY]
list_config.addPostButton(
'show_diff', 'Show Diff', '', bounds, keys, redirect=True)
query = proposal_logic.queryProposalRevisions(proposal_key)
return ProposalRevisionsList(
'summerofcode/_list_component.html', data, list_config,
query, _PROPOSAL_REVISIONS_LIST_DESCRIPTION)