Example #1
0
def unclaimTask(task):
  """Used when a student requests to unclaim a task.

  Args:
    task: The task to unclaim.
  """
  student_key = task_model.GCITask.student.get_value_for_datastore(task)

  task.student = None
  task.status = task_model.REOPENED
  task.deadline = None

  comment_props = {
      'parent': task,
      'title': DEF_UNCLAIMED_TITLE,
      'content': DEF_UNCLAIMED,
      'created_by': student_key.parent()
  }
  comment = GCIComment(**comment_props)

  comment_txn = comment_logic.storeAndNotifyTxn(comment)

  def unclaimTaskTxn():
    task.put()
    comment_txn()

  return db.run_in_transaction(unclaimTaskTxn)
Example #2
0
def extendDeadline(task, delta, profile):
  """Extends the deadline of a task.

  Args:
    task: The task to extend the deadline for.
    delta: The timedelta object to be added to the current deadline.
    profile: GCIProfile of the user that extends the deadline.
  """
  if task.deadline:
    deadline = task.deadline + delta
  else:
    deadline = datetime.datetime.utcnow() + delta

  task.deadline = deadline

  comment_props = {
      'parent': task,
      'title': DEF_EXTEND_DEADLINE_TITLE,
      'content': DEF_EXTEND_DEADLINE %(delta.days, delta.seconds/3600),
      'created_by': profile.key.parent().to_old_key()
  }
  comment = GCIComment(**comment_props)

  comment_txn = comment_logic.storeAndNotifyTxn(comment)

  def extendDeadlineTxn():
    task.put()
    comment_txn()

  return db.run_in_transaction(extendDeadlineTxn)
Example #3
0
def claimRequestTask(task, student):
  """Used when a student requests to claim a task.

  Updates the status of the tasks and places a comment notifying the org
  that someone wants to work on this task.

  Args:
    task: The task to claim.
    student: Profile of the student that wants to claim the task.
  """
  task.status = 'ClaimRequested'
  task.student = student.key.to_old_key()

  if student.key.to_old_key() not in task.subscribers:
    task.subscribers.append(student.key.to_old_key())

  comment_props = {
      'parent': task,
      'title': DEF_CLAIM_REQUEST_TITLE,
      'content': DEF_CLAIM_REQUEST,
      'created_by': student.key.parent().to_old_key()
  }
  comment = GCIComment(**comment_props)

  comment_txn = comment_logic.storeAndNotifyTxn(comment)

  def claimRequestTaskTxn():
    task.put()
    comment_txn()

  return db.run_in_transaction(claimRequestTaskTxn)
Example #4
0
def unassignTask(task, profile):
  """Unassigns a task.

  This will put the task in the Reopened state and reset the student and
  deadline property. A comment will also be generated to record this event.

  Args:
    task: task_model.GCITask entity.
    profile: GCIProfile of the user that unassigns the task.
  """
  task.student = None
  task.status = task_model.REOPENED
  task.deadline = None

  comment_props = {
      'parent': task,
      'title': DEF_UNASSIGNED_TITLE,
      'content': DEF_UNASSIGNED,
      'created_by': profile.key.parent().to_old_key()
  }
  comment = GCIComment(**comment_props)

  comment_txn = comment_logic.storeAndNotifyTxn(comment)

  def unassignTaskTxn():
    task.put()
    comment_txn()

  return db.run_in_transaction(unassignTaskTxn)
Example #5
0
def assignTask(task, student_key, assigner):
  """Assigns the task to the student.

  This will put the task in the Claimed state and set the student and deadline
  property. A comment will also be generated to record this event.

  Args:
    task: task_model.GCITask entity.
    student_key: Key of the student to assign
    assigner: GCIProfile of the user that assigns the student.
  """
  task.student = student_key.to_old_key()
  task.status = 'Claimed'
  task.deadline = datetime.datetime.now() + \
      datetime.timedelta(hours=task.time_to_complete)

  student = student_key.get()
  comment_props = {
      'parent': task,
      'title': DEF_ASSIGNED_TITLE,
      'content': DEF_ASSIGNED %(
          student.public_name, task.time_to_complete),
      'created_by': assigner.key.parent().to_old_key(),
  }
  comment = GCIComment(**comment_props)

  comment_txn = comment_logic.storeAndNotifyTxn(comment)

  def assignTaskTxn():
    task.put()
    comment_txn()
    _spawnUpdateTask(task, transactional=True)

  return db.run_in_transaction(assignTaskTxn)
Example #6
0
def unpublishTask(task, unpublisher):
  """Unpublishes the task.

  This will put the task in the Unpublished state. A comment will also be
  generated to record this event.

  Args:
    task: GCITask entity.
    publisher: GCIProfile of the user that unpublishes the task.
  """
  task.status = task_model.UNPUBLISHED

  comment_props = {
      'parent': task,
      'title': DEF_UNPUBLISHED_TITLE,
      'content': DEF_UNPUBLISHED,
      'created_by': unpublisher.key.parent().to_old_key(),
  }
  comment = GCIComment(**comment_props)

  comment_txn = comment_logic.storeAndNotifyTxn(comment)

  def unpublishTaskTxn():
    task.put()
    comment_txn()
    _spawnUpdateTask(task, transactional=True)

  return db.run_in_transaction(unpublishTaskTxn)
Example #7
0
def closeTask(task, profile):
  """Closes the task.

  Args:
    task: task_model.GCITask entity.
    profile: GCIProfile of the user that closes the task.
  """
  from soc.modules.gci.tasks.ranking_update import startUpdatingTask

  task.status = 'Closed'
  task.closed_on = datetime.datetime.now()
  task.deadline = None

  comment_props = {
      'parent': task,
      'title': DEF_CLOSED_TITLE,
      'content': DEF_CLOSED,
      'created_by': profile.key.parent().to_old_key()
  }
  comment = GCIComment(**comment_props)

  comment_txn = comment_logic.storeAndNotifyTxn(comment)

  student_key = ndb.Key.from_old_key(
      task_model.GCITask.student.get_value_for_datastore(task))
  student = student_key.get()

  # student, who worked on the task, should receive a confirmation
  # having submitted his or her first task
  query = queryAllTasksClosedByStudent(student, keys_only=True)
  if query.get() is None: # this is the first task
    confirmation = profile_logic.sendFirstTaskConfirmationTxn(student, task)
  else:
    confirmation = lambda: None

  org_score_txn = org_score_logic.updateOrgScoreTxn(task, student)

  @db.transactional(xg=True)
  def closeTaskTxn():
    task.put()
    comment_txn()
    startUpdatingTask(task, transactional=True)
    confirmation()
    org_score_txn()

  # TODO(daniel): move this to a transaction when other models are NDB
  student = student_key.get()
  student.student_data.number_of_completed_tasks += 1
  student.put()

  return closeTaskTxn()
Example #8
0
def transitFromClaimed(task):
  """Makes a state transition of a GCI Task from Claimed state
  to ActionNeeded.

  Args:
    task: The task_model.GCITask entity
  """
  # deadline is extended by 24 hours.
  task.status = 'ActionNeeded'
  task.deadline = task.deadline + datetime.timedelta(hours=24)

  comment_props = {
      'parent': task,
      'title': DEF_ACTION_NEEDED_TITLE,
      'content': DEF_ACTION_NEEDED,
  }
  comment = GCIComment(**comment_props)

  return task, comment
Example #9
0
def transitFromActionNeeded(task):
  """Makes a state transition of a GCI Task from ActionNeeded state
  to Reopened state.

  Args:
    task: The task_model.GCITask entity
  """
  # reopen the task
  task.student = None
  task.status = task_model.REOPENED
  task.deadline = None

  comment_props = {
      'parent': task,
      'title': DEF_REOPENED_TITLE,
      'content': DEF_REOPENED,
  }
  comment = GCIComment(**comment_props)

  return task, comment
Example #10
0
def transitFromNeedsWork(task):
  """Makes a state transition of a GCI Task from NeedsWork state
  to Reopened state.

  A task that has been marked as Needs(more)Work will NOT get a deadline
  extension and will be reopened immediately.

  Args:
    task: The task_model.GCITask entity
  """
  task.student = None
  task.status = task_model.REOPENED
  task.deadline = None

  comment_props = {
      'parent': task,
      'title': DEF_REOPENED_TITLE,
      'content': DEF_REOPENED,
  }
  comment = GCIComment(**comment_props)

  return task, comment
Example #11
0
def transitFromNeedsReview(task):
  """Makes a state transition of a GCI Task that is in NeedsReview state.

  This state transition is special since it actually only clears the deadline
  field and does not change value of the state field. A Task is in this state
  when work has been submitted and it has not been reviewed before the original
  deadline runs out.

  Args:
    task: The task_model.GCITask entity
  """
  # Clear the deadline since mentors are not forced to review work within a
  # certain period.
  task.deadline = None

  comment_props = {
      'parent': task,
      'title': DEF_NO_MORE_WORK_TITLE,
      'content': DEF_NO_MORE_WORK,
  }
  comment = GCIComment(**comment_props)

  return task, comment
Example #12
0
def sendForReview(task, student):
  """Send in a task for review.

  Args:
    task: The task to send for review.
    student: Profile of the student that is sending in the work.
  """
  task.status = 'NeedsReview'

  comment_props = {
      'parent': task,
      'title': DEF_SEND_FOR_REVIEW_TITLE,
      'content': DEF_SEND_FOR_REVIEW,
      'created_by': student.key.parent().to_old_key(),
  }
  comment = GCIComment(**comment_props)

  comment_txn = comment_logic.storeAndNotifyTxn(comment)

  def sendForReviewTxn():
    task.put()
    comment_txn()

  return db.run_in_transaction(sendForReviewTxn)
Example #13
0
def needsWorkTask(task, profile):
  """Closes the task.

  Args:
    task: task_model.GCITask entity.
    profile: GCIProfile of the user that marks this task as needs more work.
  """
  task.status = 'NeedsWork'

  comment_props = {
      'parent': task,
      'title': DEF_NEEDS_WORK_TITLE,
      'content': DEF_NEEDS_WORK,
      'created_by': profile.key.parent().to_old_key()
  }
  comment = GCIComment(**comment_props)

  comment_txn = comment_logic.storeAndNotifyTxn(comment)

  def needsWorkTaskTxn():
    task.put()
    comment_txn()

  return db.run_in_transaction(needsWorkTaskTxn)