| # Copyright 2013 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. |
| |
| """Logic for tasks.""" |
| |
| from google.appengine.ext import ndb |
| |
| from codein.logic import timeline as timeline_logic |
| |
| from melange.appengine import db as melange_db |
| |
| from soc.modules.gci.models import task as task_model |
| |
| |
| def queryTasksForMentor(profile_key, extra_filters=None): |
| """Returns a query to fetch tasks for which the specified mentor has been |
| assigned based on the specified criteria. |
| |
| Args: |
| profile: profile key of the mentor. |
| extra_filters: a dictionary containing additional constraints on the query. |
| """ |
| query = task_model.GCITask.all() |
| query.filter('mentors', profile_key) |
| |
| extra_filters = extra_filters or {} |
| for prop, value in extra_filters.iteritems(): |
| melange_db.addFilterToQuery(query, prop, value) |
| |
| return query |
| |
| |
| def queryForOrganization(org_key): |
| """Returns a query for all tasks for the specified organization. |
| |
| Args: |
| org_key: ndb.Key of the organization. |
| |
| Returns: |
| A query to fetch all tasks for the specified organization. |
| """ |
| return task_model.GCITask.all().filter('org', org_key.to_old_key()) |
| |
| |
| def queryForStudentAndOrganizationAndStatus( |
| student_key, org_key=None, statuses=None): |
| """Returns a query for all tasks for the specified student, |
| organization and status. |
| |
| Args: |
| student_key: ndb.Key of the student profile. |
| org_key: Optional ndb.Key of the organization. If specified, only tasks |
| for this organization will be fetched by the returned query. |
| statuses: Optional list of allowed statuses of the tasks to query. |
| |
| Returns: |
| A query to fetch all tasks with the specified properties. |
| """ |
| query = task_model.GCITask.all() |
| query.filter('student', student_key.to_old_key()) |
| |
| if org_key: |
| query.filter('org', org_key.to_old_key()) |
| |
| if statuses: |
| query.filter('status IN', statuses) |
| |
| return query |
| |
| |
| def queryForProgram(program_key): |
| """Returns a query for all tasks for program_key. |
| |
| Args: |
| program_key: Program key. |
| |
| Returns: |
| A query to fetch all tasks for program_key. |
| """ |
| return task_model.GCITask.all().filter('program', program_key) |
| |
| |
| def getOrganizationKey(task): |
| """Returns the key of the organization for the specified task. |
| |
| Args: |
| task: Task entity. |
| |
| Returns: |
| ndb.Key of the organization. |
| """ |
| return ndb.Key.from_old_key( |
| task_model.GCITask.org.get_value_for_datastore(task)) |
| |
| |
| def isCommentingAllowed(task, profile, program): |
| """Tells whether the specified profile can post a comment for the specified |
| task that belongs to the specified program. |
| """ |
| # check if the task belongs to the program |
| program_key = task_model.GCITask.program.get_value_for_datastore(task) |
| if program_key != program.key(): |
| raise ValueError('Task %r does not belong to program %r.' % ( |
| task.key(), program.key())) |
| |
| # commenting is always allowed only for registered users with profiles |
| if not profile: |
| return False |
| else: |
| all_work_stopped = ( |
| timeline_logic.isAfterStopAllWorkDeadline(program.timeline)) |
| all_reviews_stopped = ( |
| timeline_logic.isAfterWorkReviewDeadline(program.timeline)) |
| org_key = getOrganizationKey(task) |
| return (not all_work_stopped or |
| (not all_reviews_stopped and org_key in profile.mentor_for)) |