Updates the cache
        :param course: a Course object
        :param taskid: a (valid) task id
        :raise InvalidNameException, TaskNotFoundException, TaskUnreadableException
5857
def _update_cache(self, course, taskid):
        
        if not id_checker(taskid):
            raise InvalidNameException("Task with invalid name: " + taskid)

        task_fs = self.get_task_fs(course.get_id(), taskid)
        last_modif, translation_fs, task_content = self._get_last_updates(course, taskid, task_fs, True)

        self._cache[(course.get_id(), taskid)] = (
            self._task_class(course, taskid, task_content, task_fs, translation_fs, self._hook_manager, self._task_problem_types),
            last_modif
        )
164361
def POST(self, courseid, taskid, isLTI):
        
        username = self.user_manager.session_username()

        course = self.course_factory.get_course(courseid)
        if not self.user_manager.course_is_open_to_user(course, username, isLTI):
            return self.template_helper.get_renderer().course_unavailable()

        task = course.get_task(taskid)
        if not self.user_manager.task_is_visible_by_user(task, username, isLTI):
            return self.template_helper.get_renderer().task_unavailable()

        self.user_manager.user_saw_task(username, courseid, taskid)

        is_staff = self.user_manager.has_staff_rights_on_course(course, username)
        is_admin = self.user_manager.has_admin_rights_on_course(course, username)

        userinput = web.input()
        if "@action" in userinput and userinput["@action"] == "submit":
            # Verify rights
            if not self.user_manager.task_can_user_submit(task, username, isLTI):
                return json.dumps({"status": "error", "text": _("You are not allowed to submit for this task.")})

            # Retrieve input random and check still valid
            random_input = self.database.user_tasks.find_one({"courseid": task.get_course_id(), "taskid": task.get_id(), "username": username}, { "random": 1 })
            random_input = random_input["random"] if "random" in random_input else []
            for i in range(0, len(random_input)):
                s = "@random_" + str(i)
                if s not in userinput or float(userinput[s]) != random_input[i]:
                    return json.dumps({"status": "error", "text": _("Your task has been regenerated. This current task is outdated.")})

            # Reparse user input with array for multiple choices
            init_var = {
                problem.get_id(): problem.input_type()()
                for problem in task.get_problems() if problem.input_type() in [dict, list]
            }
            userinput = task.adapt_input_for_backend(web.input(**init_var))

            if not task.input_is_consistent(userinput, self.default_allowed_file_extensions, self.default_max_file_size):
                web.header('Content-Type', 'application/json')
                return json.dumps({"status": "error", "text": _("Please answer to all the questions and verify the extensions of the files "
                                                              "you want to upload. Your responses were not tested.")})
            del userinput['@action']

            # Get debug info if the current user is an admin
            debug = is_admin
            if "@debug-mode" in userinput:
                if userinput["@debug-mode"] == "ssh" and debug:
                    debug = "ssh"
                del userinput['@debug-mode']

            # Start the submission
            try:
                submissionid, oldsubids = self.submission_manager.add_job(task, userinput, debug)
                web.header('Content-Type', 'application/json')
                return json.dumps({"status": "ok", "submissionid": str(submissionid), "remove": oldsubids, "text": _("<b>Your submission has been sent...</b>")})
            except Exception as ex:
                web.header('Content-Type', 'application/json')
                return json.dumps({"status": "error", "text": str(ex)})

        elif "@action" in userinput and userinput["@action"] == "check" and "submissionid" in userinput:
            result = self.submission_manager.get_submission(userinput['submissionid'], user_check=not is_staff)
            if result is None:
                web.header('Content-Type', 'application/json')
                return json.dumps({'status': "error", "text": _("Internal error")})
            elif self.submission_manager.is_done(result, user_check=not is_staff):
                web.header('Content-Type', 'application/json')
                result = self.submission_manager.get_input_from_submission(result)
                result = self.submission_manager.get_feedback_from_submission(result, show_everything=is_staff)

                # user_task always exists as we called user_saw_task before
                user_task = self.database.user_tasks.find_one({
                    "courseid":task.get_course_id(),
                    "taskid": task.get_id(),
                    "username": {"$in": result["username"]}
                })

                default_submissionid = user_task.get('submissionid', None)
                if default_submissionid is None:
                    # This should never happen, as user_manager.update_user_stats is called whenever a submission is done.
                    return json.dumps({'status': "error", "text": _("Internal error")})

                return self.submission_to_json(task, result, is_admin, False, default_submissionid == result['_id'], tags=task.get_tags())
            else:
                web.header('Content-Type', 'application/json')
                return self.submission_to_json(task, result, is_admin)

        elif "@action" in userinput and userinput["@action"] == "load_submission_input" and "submissionid" in userinput:
            submission = self.submission_manager.get_submission(userinput["submissionid"], user_check=not is_staff)
            submission = self.submission_manager.get_input_from_submission(submission)
            submission = self.submission_manager.get_feedback_from_submission(submission, show_everything=is_staff)
            if not submission:
                raise web.notfound()
            web.header('Content-Type', 'application/json')

            return self.submission_to_json(task, submission, is_admin, True, tags=task.get_tags())

        elif "@action" in userinput and userinput["@action"] == "kill" and "submissionid" in userinput:
            self.submission_manager.kill_running_submission(userinput["submissionid"])  # ignore return value
            web.header('Content-Type', 'application/json')
            return json.dumps({'status': 'done'})
        elif "@action" in userinput and userinput["@action"] == "set_submission" and "submissionid" in userinput:
            web.header('Content-Type', 'application/json')
            if task.get_evaluate() != 'student':
                return json.dumps({'status': "error"})

            if self.set_selected_submission(course, task, userinput["submissionid"]):
                return json.dumps({'status': 'done'})
            else:
                return json.dumps({'status': 'error'})
        else:
            raise web.notfound()
12118
def delete_all_possible_task_files(self, courseid, taskid):
        
        if not id_checker(courseid):
            raise InvalidNameException("Course with invalid name: " + courseid)
        if not id_checker(taskid):
            raise InvalidNameException("Task with invalid name: " + taskid)
        task_fs = self.get_task_fs(courseid, taskid)
        for ext in self.get_available_task_file_extensions():
            try:
                task_fs.delete("task."+ext)
            except:
                pass
53145
def action_edit_save(self, courseid, taskid, path, content):
        
        wanted_path = self.verify_path(courseid, taskid, path)
        if wanted_path is None:
            return json.dumps({"error": True})
        try:
            self.task_factory.get_task_fs(courseid, taskid).put(wanted_path, content.encode("utf-8"))
            return json.dumps({"ok": True})
        except:
            return json.dumps({"error": True})
487267
def put_info(self, key, value):
        
        return self.instance.put_task_info(self.name, key, value)
191780
def reset(self, subject_id, entity_id):
        
        if not self._cache.set(_key(subject_id, entity_id), {}, 0):
            raise CacheError("reset failed")
135247
def update_task(self, task_id, revision, title=None, assignee_id=None, completed=None, recurrence_type=None, recurrence_count=None, due_date=None, starred=None, remove=None):
        ''' 
        
        '''
        return tasks_endpoint.update_task(self, task_id, revision, title=title, assignee_id=assignee_id, completed=completed, recurrence_type=recurrence_type, recurrence_count=recurrence_count, due_date=due_date, starred=starred, remove=remove)
432361
def show_page(self, course):
        
        username = self.user_manager.session_username()
        if not self.user_manager.course_is_open_to_user(course, lti=False):
            return self.template_helper.get_renderer().course_unavailable()
        else:
            tasks = course.get_tasks()
            last_submissions = self.submission_manager.get_user_last_submissions(5, {"courseid": course.get_id(), "taskid": {"$in": list(tasks.keys())}})

            for submission in last_submissions:
                    submission["taskname"] = tasks[submission['taskid']].get_name(self.user_manager.session_language())

            tasks_data = {}
            user_tasks = self.database.user_tasks.find({"username": username, "courseid": course.get_id(), "taskid": {"$in": list(tasks.keys())}})
            is_admin = self.user_manager.has_staff_rights_on_course(course, username)

            tasks_score = [0.0, 0.0]

            for taskid, task in tasks.items():
                tasks_data[taskid] = {"visible": task.get_accessible_time().after_start() or is_admin, "succeeded": False,
                                      "grade": 0.0}
                tasks_score[1] += task.get_grading_weight() if tasks_data[taskid]["visible"] else 0

            for user_task in user_tasks:
                tasks_data[user_task["taskid"]]["succeeded"] = user_task["succeeded"]
                tasks_data[user_task["taskid"]]["grade"] = user_task["grade"]

                weighted_score = user_task["grade"]*tasks[user_task["taskid"]].get_grading_weight()
                tasks_score[0] += weighted_score if tasks_data[user_task["taskid"]]["visible"] else 0

            course_grade = round(tasks_score[0]/tasks_score[1]) if tasks_score[1] > 0 else 0
            tag_list = course.get_all_tags_names_as_list(is_admin, self.user_manager.session_language())
            user_info = self.database.users.find_one({"username": username})

            return self.template_helper.get_renderer().course(user_info, course, last_submissions, tasks, tasks_data, course_grade, tag_list)
1221372
public static function preload_course($courseid) {
        // Users can call this multiple times without doing any harm
        if (isset(context::$cache_preloaded[$courseid])) {
            return;
        }
        $coursecontext = context_course::instance($courseid);
        $coursecontext->get_child_contexts();

        context::$cache_preloaded[$courseid] = true;
    }
517001
function update() {
		while (waiting.length && count < concurrency) (function() {
			var t = waiting.shift()
			
			if (inProg[t.task.id]) {
				inProg[t.task.id].push(t.cb)
				return
			} else {
				inProg[t.task.id] = [t.cb]
				count++
				processor(t.task, function() {
					var args = arguments

					if (!inProg[t.task.id]) return // probably callback called twice
	
					count--
					inProg[t.task.id].forEach(function(cb) { cb.apply(null, args) })
					delete inProg[t.task.id]
	
					setImmediate(update)
				})
			}	
		})()
	}
568370
def rename(self, old_task_name, new_task_name):
        

        if not old_task_name or old_task_name.startswith('-'):
            raise ValueError('Old task name is invalid')

        if not new_task_name or new_task_name.startswith('-'):
            raise ValueError('New new task name is invalid')

        if old_task_name == new_task_name:
            raise ValueError('Cannot rename task to itself')

        try:
            old_task_dir = self._get_task_dir(old_task_name)
            if not self.exists(old_task_dir):
                raise errors.TaskNotFound(old_task_name)

            new_task_dir = self._get_task_dir(new_task_name)
            if self.exists(new_task_dir):
                raise errors.TaskExists(new_task_name)

            os.rename(old_task_dir, new_task_dir)
            return True

        except OSError:
            return False
1270720
def update_cache(self, data=None):
        
        if data:
            self.cache_data = data
        self.cache_updated = timezone.now()
        self.save()
1269272
def add_vts(self, task_name, targets, cache_key, valid, phase):
    
    if task_name not in self._task_reports:
      self.add_task(task_name)
    self._task_reports[task_name].add(targets, cache_key, valid, phase)
1276586
def get_readable_tasks(self, course):
        
        course_fs = self._filesystem.from_subfolder(course.get_id())
        tasks = [
            task[0:len(task)-1]  # remove trailing /
            for task in course_fs.list(folders=True, files=False, recursive=False)
            if self._task_file_exists(course_fs.from_subfolder(task))]
        return tasks
1004281
def _update_cache(self, courseid):
        
        path_to_descriptor = self._get_course_descriptor_path(courseid)
        try:
            course_descriptor = loads_json_or_yaml(path_to_descriptor, self._filesystem.get(path_to_descriptor).decode("utf8"))
        except Exception as e:
            raise CourseUnreadableException(str(e))

        last_modif = {path_to_descriptor: self._filesystem.get_last_modification_time(path_to_descriptor)}
        translations_fs = self._filesystem.from_subfolder("$i18n")
        if translations_fs.exists():
            for f in translations_fs.list(folders=False, files=True, recursive=False):
                lang = f[0:len(f) - 3]
                if translations_fs.exists(lang + ".mo"):
                    last_modif["$i18n/" + lang + ".mo"] = translations_fs.get_last_modification_time(lang + ".mo")

        self._cache[courseid] = (
            self._course_class(courseid, course_descriptor, self.get_course_fs(courseid), self._task_factory, self._hook_manager),
            last_modif
        )

        self._task_factory.update_cache_for_course(courseid)
1318106
def mark_done(task_id):
  
  task = Task.get_by_id(task_id)
  if task is None:
    raise ValueError('Task with id %d does not exist' % task_id)
  task.done = True
  task.put()
233790
def synchronise(func):
    
    def inner(request, *args):
        lock_id = '%s-%s-built-%s' % (
            datetime.date.today(), func.__name__,
            ",".join([str(a) for a in args]))

        if cache.add(lock_id, 'true', LOCK_EXPIRE):
            result = func(request, *args)
            cache.set(lock_id, result.task_id)
        else:
            task_id = cache.get(lock_id)
            if not task_id:
                return None

            cache.set(lock_id, "")
            result = Task.AsyncResult(task_id)
            if result.ready():
                result.forget()
                return None
        return result
    return inner