Merge branch 'daniel/project-list'
diff --git a/app/soc/modules/gsoc/views/dashboard.py b/app/soc/modules/gsoc/views/dashboard.py
index 63db37a..6f8b5e3 100644
--- a/app/soc/modules/gsoc/views/dashboard.py
+++ b/app/soc/modules/gsoc/views/dashboard.py
@@ -340,7 +340,7 @@
the current user.
"""
- IDX = 0
+ IDX = 5
def __init__(self, data, survey):
"""Initializes the component.
@@ -1026,27 +1026,8 @@
def __init__(self, data):
"""Initializes this component."""
-
- def getOrganization(entity, *args):
- """Helper function to get value of organization column."""
- org_key = GSoCProject.org.get_value_for_datastore(entity)
- return ndb.Key.from_old_key(org_key).get().name
-
- list_config = lists.ListConfiguration()
- list_config.addSimpleColumn('title', 'Title')
-
- def getStudent(entity, *args):
- """Helper function to get value of student column."""
- return ndb.Key.from_old_key(entity.parent_key()).get().public_name
-
- list_config.addPlainTextColumn('student', 'Student', getStudent)
- list_config.addPlainTextColumn('org', 'Organization', getOrganization)
- list_config.setDefaultSort('title')
- list_config.setRowAction(
- lambda e, *args: links.LINKER.userId(
- e.parent_key(), e.key().id(), url_names.GSOC_PROJECT_DETAILS))
- self._list_config = list_config
-
+ self._list = project_list.getMentoredProjectList(
+ data, data.ndb_profile.key)
super(ProjectsIMentorComponent, self).__init__(data)
def templatePath(self):
@@ -1060,43 +1041,18 @@
If the lists as requested is not supported by this component None is
returned.
"""
- if lists.getListIndex(self.data.request) != 5:
- return None
-
- list_query = project_logic.getAcceptedProjectsQuery(
- program=self.data.program)
-
- if self.data.ndb_profile.is_admin:
- list_query.filter(
- 'org IN',
- map(lambda key: key.to_old_key(), self.data.ndb_profile.admin_for))
- else:
- list_query.filter('mentors', self.data.ndb_profile.key.to_old_key())
-
- starter = lists.keyStarter
- # TODO(daniel): enable prefetching from ndb models ('org', 'parent')
- prefetcher = None
-
- response_builder = lists.RawQueryContentResponseBuilder(
- self.data.request, self._list_config, list_query,
- starter, prefetcher=prefetcher)
- return response_builder.build()
+ return self._list.getListData()
def context(self):
"""Returns the context of this component."""
list_configuration_response = lists.ListConfigurationResponse(
- self.data, self._list_config, idx=5)
-
- if self.data.ndb_profile.is_admin:
- title = 'Projects for my orgs'
- else:
- title = 'Projects I am a mentor for'
+ self.data, self._list._list_config, idx=0, preload_list=False)
return {
'name': 'mentoring_projects',
- 'title': title,
+ 'title': 'Projects I am a mentor for',
'lists': [list_configuration_response],
- 'description': ugettext(title),
+ 'description': ugettext('Projects I am a mentor for'),
}
diff --git a/app/soc/modules/gsoc/views/participants.py b/app/soc/modules/gsoc/views/participants.py
index d3aa9ed..06f5153 100644
--- a/app/soc/modules/gsoc/views/participants.py
+++ b/app/soc/modules/gsoc/views/participants.py
@@ -181,7 +181,9 @@
list_config = lists.ListConfiguration()
list_config.addPlainTextColumn(
- 'name', 'Name', lambda entity, *args: entity.public_name.strip())
+ 'name', 'Public Name', lambda entity, *args: entity.public_name.strip())
+ list_config.addSimpleColumn('first_name', 'First Name')
+ list_config.addSimpleColumn('last_name', 'Last Name')
list_config.addSimpleColumn('profile_id', 'Username')
list_config.addPlainTextColumn(
'email', 'Email', lambda entity, *args: entity.contact.email)
diff --git a/app/summerofcode/logic/project.py b/app/summerofcode/logic/project.py
index 08cdf34..e502b0a 100644
--- a/app/summerofcode/logic/project.py
+++ b/app/summerofcode/logic/project.py
@@ -86,6 +86,20 @@
project_model.Project.status == project_model.Status.ACCEPTED)
+def queryAllProjectsForOrgMember(profile_key):
+ """Returns a query to fetch all projects mentored by the specified
+ organization memebr.
+
+ Args:
+ profile_key: ndb.Key of the profile.
+
+ Returns:
+ ndb.Query object to fetch all projects mentored by specified profile.
+ """
+ return project_model.Project.query(
+ project_model.Project.mentors == profile_key)
+
+
@ndb.transactional
def updateProject(project_key, project_properties):
"""Updates the specified project based on the specified properties.
diff --git a/app/summerofcode/templates/project_list.py b/app/summerofcode/templates/project_list.py
index f232892..bd7f6f4 100644
--- a/app/summerofcode/templates/project_list.py
+++ b/app/summerofcode/templates/project_list.py
@@ -219,7 +219,7 @@
list_config.addHtmlColumn('student', 'Student', _getStudent)
list_config.addHtmlColumn('organization', 'Organization', _getOrganization)
list_config.addSimpleColumn('status', 'Status')
- list_config.addHtmlColumn('mentors', 'Mentors', _getMentors)
+ list_config.addPlainTextColumn('mentors', 'Mentors', _getMentors)
list_config.addHtmlColumn('manage_link', 'Manage', _getManage)
list_config.setRowAction(
@@ -266,3 +266,41 @@
return ProjectList(
'summerofcode/_list_component.html', data, list_config,
query, _PUBLIC_PROJECT_LIST_DESCRIPTION)
+
+
+def getMentoredProjectList(data, profile_key):
+ """Returns an instance of ProjectList class that lists all projects mentored
+ by the specified organization member.
+
+ Args:
+ data: request_data.RequestData for the current request.
+ profile_key: ndb.Key of the profile.
+
+ Returns:
+ The newly created ProjectList object.
+ """
+ list_config = lists.ListConfiguration(add_key_column=False)
+
+ list_config.addPlainTextColumn(
+ 'key', 'Key', lambda entity, *args: entity.key.urlsafe(), hidden=True)
+ list_config.addSimpleColumn('title', 'Title')
+
+ # organization column is added only when the user is a mentor for
+ # more than one organization
+ if len(data.ndb_profile.mentor_for) > 1:
+ list_config.addPlainTextColumn(
+ 'organization', 'Organization', _getOrganization)
+
+ list_config.addSimpleColumn('status', 'Status')
+ list_config.addPlainTextColumn('mentors', 'Mentors', _getMentors)
+
+ list_config.setRowAction(
+ lambda entity, *args: links.LINKER.userId(
+ entity.key.parent(), entity.key.id(),
+ urls.UrlNames.PROJECT_DETAILS))
+
+ query = project_logic.queryAllProjectsForOrgMember(profile_key)
+
+ return ProjectList(
+ 'summerofcode/_list_component.html', data, list_config,
+ query, _PUBLIC_PROJECT_LIST_DESCRIPTION)
diff --git a/tests/app/summerofcode/logic/test_project.py b/tests/app/summerofcode/logic/test_project.py
index 1054d57..42d8075 100644
--- a/tests/app/summerofcode/logic/test_project.py
+++ b/tests/app/summerofcode/logic/test_project.py
@@ -182,6 +182,49 @@
self.assertSetEqual(set(project_keys), self.accepted_project_keys)
+class queryAllProjectsForOrgMemberTest(unittest.TestCase):
+ """Unit tests for queryAllProjectsForOrgMember function."""
+
+ def setUp(self):
+ """See unittest.UnitTest.setUp for specification."""
+ program = program_utils.seedGSoCProgram()
+ org = org_utils.seedSOCOrganization(program.key())
+
+ self.mentor = profile_utils.seedNDBProfile(
+ program.key(), mentor_for=[org.key])
+
+ # seed a few accepted, withdrawn and failed projects for the mentor
+ self.accepted_project_keys = set()
+ for _ in range(_TEST_NUMER_OF_PROJECTS):
+ student = profile_utils.seedNDBStudent(program)
+ self.accepted_project_keys.add(
+ project_utils.seedNDBProject(
+ student, program.key(), org_key=org.key,
+ mentor_key=self.mentor.key).key)
+
+ self.accepted_project_keys.add(
+ project_utils.seedNDBProject(
+ student, program.key(), mentor_key=self.mentor.key,
+ status=project_model.Status.WITHDRAWN, org_key=org.key).key)
+
+ self.accepted_project_keys.add(
+ project_utils.seedNDBProject(
+ student, program.key(), mentor_key=self.mentor.key,
+ status=project_model.Status.FAILED, org_key=org.key).key)
+
+ # seed a few accepted projects for other mentors
+ for _ in range(_TEST_NUMER_OF_PROJECTS):
+ student = profile_utils.seedNDBStudent(program)
+ project_utils.seedNDBProject(student, program.key(), org_key=org.key)
+
+ def testsFetchedProjects(self):
+ """Tests that only accepted projects for the organization are fetched."""
+ query = project_logic.queryAllProjectsForOrgMember(self.mentor.key)
+ project_keys = query.fetch(1000, keys_only=True)
+
+ self.assertSetEqual(set(project_keys), self.accepted_project_keys)
+
+
_OTHER_PROJECT_PROPERTIES = {
'title': u'Other Title',
'abstract': u'Other Abstract',