def initiate_next_task(self, user_id, user_email, current_task_nr, next_task_nr): """ Initiate the generation of the next task for the user if he has not got the task already and if it has already started """ if not c.is_valid_task_nr(self.dbs["course"], next_task_nr, \ self.queues["logger"], self.name): return if current_task_nr < next_task_nr: # user did not get this task yet task_start = c.get_task_starttime(self.dbs["course"], \ next_task_nr, \ self.queues["logger"], \ self.name) if task_start <= datetime.datetime.now(): # task has already started c.generate_task(self.queues["generator"], user_id, next_task_nr, user_email, "") else: c.send_email(self.queues["sender"], str(user_email), \ str(user_id), "CurLast", \ str(next_task_nr), "", "")
def a_task_is_requested(self, user_id, user_email, task_nr, message_id): """ Process a request for a certain task_nr. Check if that task exists, if it is active, and if the deadline has not passed yet. If yes put in generator queue. """ logmsg = "Processing a Task Request, UserId:{0} TaskNr:{1}"\ .format(user_id, task_nr) c.log_a_msg(self.queues["logger"], self.name, logmsg, "INFO") #task with this task_nr exists? is_task = c.is_valid_task_nr(self.dbs["course"], task_nr, self.queues["logger"], \ self.name) if not is_task: # task_nr is not valid c.send_email(self.queues["sender"], user_email, "", "InvalidTask", str(task_nr), \ "", message_id) return # get time now, deadline and starttime of task time_now = datetime.datetime.now() starttime = c.get_task_starttime(self.dbs["course"], task_nr, \ self.queues["logger"], self.name) deadline = c.get_task_deadline(self.dbs["course"], task_nr, \ self.queues["logger"], self.name) if not (starttime <= time_now): # task not active yet logmsg = ("Task not active") c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") c.send_email(self.queues["sender"], user_email, "", "TaskNotActive", \ str(task_nr), "", message_id) return if deadline < time_now: # deadline passed for that task_nr! logmsg = ("Deadline passed") c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") c.send_email(self.queues["sender"], user_email, "", "DeadTask", \ str(task_nr), "", message_id) return logmsg = ("Calling Generator to create" "TaskNr:{0} for UserId:{1}").format(task_nr, user_id) c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") c.generate_task(self.queues["generator"], user_id, task_nr, user_email, \ message_id)
def a_result_was_submitted(self, user_id, user_email, task_nr, messageid, \ mail): logmsg = "Processing a Result, UserId:{0} TaskNr:{1}"\ .format(user_id, task_nr) c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") # at which task_nr is the user cur_task = c.user_get_current_task(self.semesterdb, user_id, self.logger_queue, \ self.name) #task with this tasknr exists? is_task = c.is_valid_task_nr(self.coursedb, task_nr, self.logger_queue,\ self.name) if is_task == False: # task_nr is not valid c.send_email(self.sender_queue, user_email, "", "InvalidTask", str(task_nr), \ "", messageid) return # task_nr is valid, get deadline deadline = c.get_task_deadline(self.coursedb, task_nr, self.logger_queue, \ self.name) if is_task and cur_task < int(task_nr): #task_nr valid, but user has not reached that tasknr yet logmsg = ("User can not submit for this task yet.") c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") c.send_email(self.sender_queue, user_email, "", "TaskNotSubmittable", str(task_nr), \ "", messageid) elif deadline < datetime.datetime.now(): # deadline passed for that task_nr! logmsg = ("Deadline passed") c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") c.send_email(self.sender_queue, user_email, "", "DeadTask", str(task_nr), \ "", messageid) else: # okay, let's work with the submission #save the attached files to user task directory self.save_submission_user_dir(user_email, task_nr, mail, messageid) # send job request to worker self.job_queue.put(dict({"UserId": user_id, "UserEmail": user_email, \ "message_type": "Task", "taskNr": task_nr, \ "MessageId": messageid}))
def skip_was_requested(self, user_id, user_email, messageid): # at which task_nr is the user cur_task = c.user_get_current_task(self.semesterdb, user_id, self.logger_queue, \ self.name) next_task = cur_task + 1 logmsg = ("Skip requested: User with UserId:{0}, from " "TaskNr= {1} to {2}").format(user_id, cur_task, next_task) c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") #task with this tasknr exists? is_task = c.is_valid_task_nr(self.coursedb, next_task, self.logger_queue,\ self.name) if is_task == True: task_starttime = c.get_task_starttime(self.coursedb, next_task, self.logger_queue, self.name) task_has_started = task_starttime < datetime.datetime.now() if task_has_started == True: #set new current task c.user_set_current_task(self.semesterdb, next_task, user_id, \ self.logger_queue, self.name) #tell generator thread to create new task logmsg = ("Calling Generator to create " "TaskNr:{0} for UserId:{1}").format( next_task, user_id) c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") self.gen_queue.put(dict({"user_id": user_id, "user_email": user_email, \ "task_nr": next_task, "messageid": messageid})) logmsg = ("Skip done: User with UserId:{0}, from " "TaskNr= {1} to {2}").format(user_id, cur_task, next_task) c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") return #Skip not possible logmsg = ("Skip NOT POSSIBLE: User with UserId:{0}, from " "TaskNr= {1} to {2}").format(user_id, cur_task, next_task) c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") c.send_email(self.sender_queue, user_email, "", "SkipNotPossible", \ "", "", messageid)
def a_result_was_submitted(self, user_id, user_email, task_nr, message_id, \ mail): """ Check if the user is allowed ot submit a result to the task with given task nr and if yes add to worker queue. """ logmsg = "Processing a Result, UserId:{0} TaskNr:{1}"\ .format(user_id, task_nr) c.log_a_msg(self.queues["logger"], self.name, logmsg, "INFO") #task with this task_nr exists? is_task = c.is_valid_task_nr(self.dbs["course"], task_nr, self.queues["logger"],\ self.name) if not is_task: # task_nr is not valid c.send_email(self.queues["sender"], user_email, "", "InvalidTask", str(task_nr), \ "", message_id) return # task_nr is valid, get deadline deadline = c.get_task_deadline(self.dbs["course"], task_nr, self.queues["logger"], \ self.name) already_received = c.user_received_task(self.dbs["semester"], user_id, \ task_nr, self.queues["logger"], \ self.name) if is_task and not already_received: #task_nr valid, but user has not gotten that task yet logmsg = ("User can not submit for this task yet.") c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") c.send_email(self.queues["sender"], user_email, "", "TaskNotSubmittable", str(task_nr), \ "", message_id) elif deadline < datetime.datetime.now(): # deadline passed for that task_nr! logmsg = ("Deadline passed") c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") c.send_email(self.queues["sender"], user_email, "", "DeadTask", str(task_nr), \ "", message_id) else: # okay, let's work with the submission job_tuple = (user_id, task_nr) dispatchable = job_tuple not in self.jobs_active if not dispatchable: if job_tuple in self.jobs_backlog: self.jobs_backlog[job_tuple].append(message_id) else: self.jobs_backlog[job_tuple] = [message_id] logmsg = ("Backlogged {0},{1},{2}").format( user_id, task_nr, message_id) c.log_a_msg(self.queues["logger"], self.name, logmsg, "INFO") else: # save the attached files to user task directory self.save_submission_user_dir(user_id, task_nr, mail) c.dispatch_job(self.queues["job"], user_id, task_nr, \ user_email, message_id) dispatch_time = time.time() self.jobs_active[job_tuple] = {"dispatch": dispatch_time, \ "message_id": message_id} self.mid_to_job_tuple[message_id] = job_tuple
def a_question_was_asked(self, user_id, user_email, mail, message_id): """ Process a question that was asked by a user. """ mail_subject = str(mail['subject']) logmsg = 'The user has a question, please take care of that!' c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") # was the question asked to a specific task_nr search_obj = re.search( '[0-9]+', mail_subject, ) task_nr = "" if (search_obj != None): task_nr = search_obj.group() #task with this task_nr exists? is_task = c.is_valid_task_nr(self.dbs["course"], task_nr, self.queues["logger"], \ self.name) if not is_task: # task_nr is not valid c.send_email(self.queues["sender"], user_email, "", "InvalidTask", str(task_nr), \ "", message_id) logmsg = ("Question from user with email {0} contains an " "invalid TaskNr. Informing user, message dropped" ).format(user_email) c.log_a_msg(self.queues["logger"], self.name, logmsg, "INFO") return fwd_mails = self.get_taskoperator_emails(task_nr) if not fwd_mails: logmsg = ("Error getting the taskoperator email for task {0}. " "Question from user with email={1} " "dropped.").format(task_nr, user_email) c.log_a_msg(self.queues["logger"], self.name, logmsg, "ERROR") return else: fwd_mails = self.get_admin_emails() if not fwd_mails: logmsg = ("Error getting the admin email." "Question from user with email={1} " "dropped.").format(task_nr, user_email) c.log_a_msg(self.queues["logger"], self.name, logmsg, "ERROR") return # send Question received message to user c.send_email(self.queues["sender"], user_email, "", "Question", "", "", "") # forward email to admins/taskoperators mail["Reply-To"] = user_email c.send_email(self.queues["sender"], fwd_mails, user_id, "QFwd", task_nr, mail, message_id) c.increment_db_statcounter(self.dbs["semester"], 'nr_questions_received', \ self.queues["logger"], self.name)
def generator_loop(self): """ Loop code for the generator thread """ # blocking wait on gen_queue next_gen_msg = self.queues["generator"].get(True) logmsg = "gen_queue content:" + str(next_gen_msg) c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") task_nr = next_gen_msg.get('task_nr') user_id = next_gen_msg.get('user_id') user_email = next_gen_msg.get('user_email') message_id = next_gen_msg.get('message_id') # requested task is a valid task? if not c.is_valid_task_nr(self.dbs["course"], task_nr, \ self.queues["logger"], self.name): logmsg = ( "Generator was given the task to create non valid TaskNr {0}. " "This should not happen!").format(task_nr) c.log_a_msg(self.queues["logger"], self.name, logmsg, "ERROR") return # check if user already got this task already_received = c.user_received_task(self.dbs["semester"], user_id, \ task_nr, self.queues["logger"], \ self.name) if already_received: if self.allow_requests == "multiple": logmsg = ("User with Id {0} TaskNr {1} already got this task, " "deleting it to make place for new").format( user_id, task_nr) c.log_a_msg(self.queues["logger"], self.name, logmsg, "INFO") self.delete_usertask(user_id, task_nr) else: logmsg = ( "User with Id {0} TaskNr {1} already got this task, " "multiple request not allowed for this course").format( user_id, task_nr) c.log_a_msg(self.queues["logger"], self.name, logmsg, "INFO") c.send_email(self.queues["sender"], str(user_email), str(user_id), \ "NoMultipleRequest", str(task_nr), "", str(message_id)) return # generate the directory for the task in the space of the user usertask_dir = 'users/' + str(user_id) + "/Task" + str(task_nr) c.check_dir_mkdir(usertask_dir, self.queues["logger"], self.name) # generate the folder for the task description desc_dir = usertask_dir + "/desc" c.check_dir_mkdir(desc_dir, self.queues["logger"], self.name) # get the path to the generator script scriptpath, language = self.get_scriptinfo(task_nr) # check the path if not scriptpath or not os.path.isfile(scriptpath): logmsg = "Could not find generator script for task{0}".format( task_nr) c.log_a_msg(self.queues["logger"], self.name, logmsg, "ERROR") return command = [scriptpath, str(user_id), str(task_nr), self.submission_mail,\ str(self.course_mode), self.dbs["semester"], str(language)] logmsg = "generator command with arguments: {0} ".format(command) c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") process = Popen(command, stdout=PIPE, stderr=PIPE) generator_msg, generator_error = process.communicate() generator_msg = generator_msg.decode('UTF-8') generator_error = generator_error.decode('UTF-8') generator_res = process.returncode log_src = "Generator{0}({1})".format(str(task_nr), str(user_id)) if generator_msg: c.log_task_msg(self.queues["logger"], log_src, generator_msg, "INFO") if generator_error: c.log_task_error(self.queues["logger"], log_src, generator_error, "ERROR") # Error at task generation if generator_res != 0: # generator not 0 returned logmsg = "Failed executing the generator script, return value: " + \ str(generator_res) c.log_a_msg(self.queues["logger"], self.name, logmsg, "ERROR") # alert to admin c.send_email(self.queues["sender"], "", user_id, \ "TaskAlert", task_nr, "", message_id) #notice to user c.send_email(self.queues["sender"], user_email, user_id, \ "TaskErrorNotice", task_nr, "", message_id) return logmsg = "Generated individual task for user/task_nr:" + str(user_id) \ + "/" + str(task_nr) c.log_a_msg(self.queues["logger"], self.name, logmsg, "INFO") c.send_email(self.queues["sender"], str(user_email), str(user_id), \ "Task", str(task_nr), "Your personal example", str(message_id))