def __init__(self, *args, **kwargs):
   """Constructor - ensures ancestor is current user."""
   if 'created_by' not in kwargs:
     assert 'parent' not in kwargs
     current_player = Player.getCurrentPlayer()
     RemoteModel.__init__(self, *args, parent=current_player, **kwargs)
   else:
     RemoteModel.__init__(self, *args, **kwargs)
   assert self.created_by == self.parent().user
    def submitSolution(cls, instruction_uid=None, calendar=None):
        """Submits a solution to this do-puzzle, returns information
    about whether the solution is correct."""
        # get the instruction (and the next instruction if it extists)
        instruction = Instruction.getBy("uid", instruction_uid)
        next_instruction = Instruction.getBy("previous_uid", instruction_uid)
        if next_instruction:
            assert instruction.created_by == next_instruction.created_by

        # if the instruction was already completed, then we're done
        if instruction.state == "done":
            return {"submission": "success", "next_puzzle": cls.dequeueInstruction()}

        # make sure the calendar doesn't exist
        assert Calendar.getBy("uid", calendar.uid) == None

        # store the calendar
        calendar.put()

        # indicate that the next instruction should be processed
        def pass_batton(instruction, next_instruction, solution):
            instruction.soln_cal_uid = solution.uid
            instruction.state = "done"
            instruction.put()
            if not next_instruction:
                return
            next_instruction.calendar_uid = solution.uid
            assert instruction.previousChainAllDone()  # <- debug
            next_instruction.state = "processing"
            next_instruction.put()

        db.run_in_transaction(pass_batton, instruction, next_instruction, calendar)

        # update the player who typed this instruction
        logging.error("notifying: %s" % instruction.created_by)
        player_to_notify = Player.getByUser(instruction.created_by)
        player_channel = player_to_notify.getChannel()
        player_channel.postSolution(
            solved_instruction=instruction, solved_calendar=calendar, next_instruction=next_instruction
        )

        logging.error("TODO: update the player with a channel")
        #

        # return a new puzzle
        return {"submission": "success", "next_puzzle": cls.dequeueInstruction()}